diff options
Diffstat (limited to 'Build/source/texk/dvipdfm-x/spc_pdfm.c')
-rw-r--r-- | Build/source/texk/dvipdfm-x/spc_pdfm.c | 91 |
1 files changed, 34 insertions, 57 deletions
diff --git a/Build/source/texk/dvipdfm-x/spc_pdfm.c b/Build/source/texk/dvipdfm-x/spc_pdfm.c index 019230ca15d..1b12dd966eb 100644 --- a/Build/source/texk/dvipdfm-x/spc_pdfm.c +++ b/Build/source/texk/dvipdfm-x/spc_pdfm.c @@ -37,6 +37,8 @@ #include "dpxfile.h" #include "dpxutil.h" +#include "unicode.h" + #include "pdfobj.h" #include "pdfparse.h" @@ -126,6 +128,9 @@ static int spc_handler_pdfm__init (void *dp) { struct spc_pdf_ *sd = dp; + /* The folllowing dictionary entry keys are considered as keys for + * text strings. Be sure that string object is NOT always a text string. + */ static const char *default_taintkeys[] = { "Title", "Author", "Subject", "Keywords", "Creator", "Producer", "Contents", "Subj", @@ -399,31 +404,6 @@ reencodestring (CMap *cmap, pdf_obj *instring) return 0; } -/* tables/values used in UTF-8 interpretation - - code is based on ConvertUTF.[ch] sample code - published by the Unicode consortium */ -static uint32_t -offsetsFromUTF8[6] = { - 0x00000000U, - 0x00003080U, - 0x000E2080U, - 0x03C82080U, - 0xFA082080U, - 0x82082080U -}; - -static unsigned char -bytesFromUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; - static int maybe_reencode_utf8(pdf_obj *instring) { @@ -449,7 +429,15 @@ maybe_reencode_utf8(pdf_obj *instring) if (non_ascii == 0) return 0; /* no need to reencode ASCII strings */ - if (inbuf[0] == 0xfe && inbuf[1] == 0xff) + /* Check if the input string is valid UTF8 string + * This routine may be called against non-text strings. + * We need to re-encode string only when string is a text string + * endcoded in UTF8. + */ + if (!UC_UTF8_is_valid_string(inbuf, inbuf + inlen)) + return 0; + else if (inbuf[0] == 0xfe && inbuf[1] == 0xff && + UC_UTF16BE_is_valid_string(inbuf + 2, inbuf + inlen)) return 0; /* no need to reencode UTF16BE with BOM */ cp = inbuf; @@ -457,35 +445,15 @@ maybe_reencode_utf8(pdf_obj *instring) *op++ = 0xfe; *op++ = 0xff; while (cp < inbuf + inlen) { - uint32_t usv = *cp++; - int extraBytes = bytesFromUTF8[usv]; - if (cp + extraBytes > inbuf + inlen) - return -1; /* ill-formed, so give up reencoding */ - switch (extraBytes) { /* note: code falls through cases! */ - case 5: usv <<= 6; usv += *cp++; - case 4: usv <<= 6; usv += *cp++; - case 3: usv <<= 6; usv += *cp++; - case 2: usv <<= 6; usv += *cp++; - case 1: usv <<= 6; usv += *cp++; - case 0: ; - }; - usv -= offsetsFromUTF8[extraBytes]; - if (usv > 0x10FFFF) - return -1; /* out of valid Unicode range, give up */ - if (usv > 0xFFFF) { - /* supplementary-plane character: generate high surrogate */ - uint32_t hi = 0xdc00 + (usv - 0x10000) % 0x0400; - if (op > wbuf + WBUF_SIZE - 2) - return -1; /* out of space */ - *op++ = hi / 256; - *op++ = hi % 256; - usv = 0xd800 + (usv - 0x10000) / 0x0400; - /* remaining value in usv is the low surrogate */ - } - if (op > wbuf + WBUF_SIZE - 2) - return -1; /* out of space */ - *op++ = usv / 256; - *op++ = usv % 256; + int32_t usv; + int len; + + usv = UC_UTF8_decode_char((const unsigned char **)&cp, inbuf + inlen); + if (!UC_is_valid(usv)) + return -1; /* out of valid Unicode range, give up (redundant) */ + len = UC_UTF16BE_encode_char(usv, &op, wbuf + WBUF_SIZE); + if (len == 0) + return -1; } pdf_set_string(instring, wbuf, op - wbuf); @@ -493,6 +461,11 @@ maybe_reencode_utf8(pdf_obj *instring) return 0; } +/* The purpose of this routine is to check if given string object is + * surely an object for *text* strings. It does not do a complete check + * but does a quick check. Please add entries for taintkeys if you have found + * additional dictionary entries which is considered as a text string. + */ static int needreencode (pdf_obj *kp, pdf_obj *vp, struct tounicode *cd) { @@ -535,8 +508,13 @@ modstrings (pdf_obj *kp, pdf_obj *vp, void *dp) CMap *cmap = CMap_cache_get(cd->cmap_id); if (needreencode(kp, vp, cd)) r = reencodestring(cmap, vp); - } else if (is_xdv) + } else if (is_xdv) { + /* Please fix this... PDF string object is not always a text string. + * needreencode() is assumed to do a simple check if given string + * object is actually a text string. + */ r = maybe_reencode_utf8(vp); + } if (r < 0) /* error occured... */ WARN("Failed to convert input string to UTF16..."); break; @@ -2063,4 +2041,3 @@ spc_pdfm_setup_handler (struct spc_handler *sph, return error; } - |