summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x/spc_pdfm.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipdfm-x/spc_pdfm.c')
-rw-r--r--Build/source/texk/dvipdfm-x/spc_pdfm.c91
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;
}
-