diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2013-03-04 13:56:54 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2013-04-11 13:58:58 +0100 |
commit | b302892a8c302aee9ca6d2abab2f32afbee3a8a5 (patch) | |
tree | 38479155f5b62933d6e7bbc4826494a6ed548fc8 | |
parent | 5ff123aed2b3853a4765a0d85de18d7074c2e1ec (diff) | |
download | mupdf-b302892a8c302aee9ca6d2abab2f32afbee3a8a5.tar.xz |
Convert UTF-8 passwords to correct encoding.
PDFDocEncoding for crypt revisions <= 4, UTF-8 for newer.
-rw-r--r-- | pdf/data_encodings.h | 7 | ||||
-rw-r--r-- | pdf/mupdf.h | 2 | ||||
-rw-r--r-- | pdf/pdf_crypt.c | 40 |
3 files changed, 42 insertions, 7 deletions
diff --git a/pdf/data_encodings.h b/pdf/data_encodings.h index 96b06769..025e9d03 100644 --- a/pdf/data_encodings.h +++ b/pdf/data_encodings.h @@ -2,9 +2,10 @@ const unsigned short pdf_doc_encoding[256] = { - 0x0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', 0x9, 0xA, ' ', ' ', 0xD, ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + /* 0x0 to 0x17 except \t, \n and \r are really undefined */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, diff --git a/pdf/mupdf.h b/pdf/mupdf.h index 9dbafc91..301f8a8a 100644 --- a/pdf/mupdf.h +++ b/pdf/mupdf.h @@ -193,7 +193,7 @@ pdf_document *pdf_open_document_with_stream(fz_context *ctx, fz_stream *file); void pdf_close_document(pdf_document *doc); int pdf_needs_password(pdf_document *doc); -int pdf_authenticate_password(pdf_document *doc, char *pw); +int pdf_authenticate_password(pdf_document *doc, const char *pw); enum { diff --git a/pdf/pdf_crypt.c b/pdf/pdf_crypt.c index 82295af2..54579570 100644 --- a/pdf/pdf_crypt.c +++ b/pdf/pdf_crypt.c @@ -699,13 +699,47 @@ pdf_authenticate_owner_password(fz_context *ctx, pdf_crypt *crypt, unsigned char return pdf_authenticate_user_password(ctx, crypt, userpass, 32); } +static void pdf_docenc_from_utf8(char *password, const char *utf8, int n) +{ + int i = 0, k, c; + while (*utf8 && i + 1 < n) + { + utf8 += fz_chartorune(&c, utf8); + for (k = 0; k < 256; k++) + { + if (c == pdf_doc_encoding[k]) + { + password[i++] = k; + break; + } + } + /* FIXME: drop characters that can't be encoded or return an error? */ + } + password[i] = 0; +} + +static void pdf_saslprep_from_utf8(char *password, const char *utf8, int n) +{ + /* TODO: stringprep with SALSprep profile */ + fz_strlcpy(password, utf8, n); +} + int -pdf_authenticate_password(pdf_document *xref, char *password) +pdf_authenticate_password(pdf_document *xref, const char *pwd_utf8) { + char password[2048]; + if (xref->crypt) { - if (!password) - password = ""; + password[0] = 0; + if (pwd_utf8) + { + if (xref->crypt->r <= 4) + pdf_docenc_from_utf8(password, pwd_utf8, sizeof password); + else + pdf_saslprep_from_utf8(password, pwd_utf8, sizeof password); + } + if (pdf_authenticate_user_password(xref->ctx, xref->crypt, (unsigned char *)password, strlen(password))) return 1; if (pdf_authenticate_owner_password(xref->ctx, xref->crypt, (unsigned char *)password, strlen(password))) |