summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2017-08-13 07:14:48 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2017-08-13 07:14:48 +0000
commit4b4995cda35627e06c43e25ecbe07c1bc1859bb5 (patch)
tree143ed02a389bab62f44043a54cbc70f69e312e2f /Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
parent00d00899c484b81967558f43c4fe4a896ffdf610 (diff)
xpdf 4.00
git-svn-id: svn://tug.org/texlive/trunk@45031 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc177
1 files changed, 137 insertions, 40 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
index 674b992434c..0d064cff379 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
@@ -15,6 +15,7 @@
#include <stdio.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "gfile.h"
#include "GString.h"
#include "Error.h"
@@ -34,18 +35,17 @@ struct CharCodeToUnicodeString {
//------------------------------------------------------------------------
-static int getCharFromString(void *data) {
- char *p;
- int c;
+struct GStringIndex {
+ GString *s;
+ int i;
+};
- p = *(char **)data;
- if (*p) {
- c = *p++;
- *(char **)data = p;
- } else {
- c = EOF;
+static int getCharFromGString(void *data) {
+ GStringIndex *idx = (GStringIndex *)data;
+ if (idx->i >= idx->s->getLength()) {
+ return EOF;
}
- return c;
+ return idx->s->getChar(idx->i++) & 0xff;
}
static int getCharFromFile(void *data) {
@@ -234,23 +234,28 @@ CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) {
CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) {
CharCodeToUnicode *ctu;
- char *p;
+ GStringIndex idx;
ctu = new CharCodeToUnicode(NULL);
- p = buf->getCString();
- ctu->parseCMap1(&getCharFromString, &p, nBits);
+ idx.s = buf;
+ idx.i = 0;
+ if (!ctu->parseCMap1(&getCharFromGString, &idx, nBits)) {
+ delete ctu;
+ return NULL;
+ }
return ctu;
}
void CharCodeToUnicode::mergeCMap(GString *buf, int nBits) {
- char *p;
+ GStringIndex idx;
- p = buf->getCString();
- parseCMap1(&getCharFromString, &p, nBits);
+ idx.s = buf;
+ idx.i = 0;
+ parseCMap1(&getCharFromGString, &idx, nBits);
}
-void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
- int nBits) {
+GBool CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
+ int nBits) {
PSTokenizer *pst;
char tok1[256], tok2[256], tok3[256];
int n1, n2, n3;
@@ -258,7 +263,9 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
CharCode maxCode, code1, code2;
GString *name;
FILE *f;
+ GBool ok;
+ ok = gFalse;
maxCode = (nBits == 8) ? 0xff : (nBits == 16) ? 0xffff : 0xffffffff;
pst = new PSTokenizer(getCharFunc, data);
pst->getToken(tok1, sizeof(tok1), &n1);
@@ -267,7 +274,9 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
if (tok1[0] == '/') {
name = new GString(tok1 + 1);
if ((f = globalParams->findToUnicodeFile(name))) {
- parseCMap1(&getCharFromFile, f, nBits);
+ if (parseCMap1(&getCharFromFile, f, nBits)) {
+ ok = gTrue;
+ }
fclose(f);
} else {
error(errSyntaxError, -1,
@@ -305,6 +314,7 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
"Invalid entry in bfchar block in ToUnicode CMap");
}
addMapping(code1, tok2 + 1, n2 - 2, 0);
+ ok = gTrue;
}
pst->getToken(tok1, sizeof(tok1), &n1);
} else if (!strcmp(tok2, "beginbfrange")) {
@@ -350,6 +360,7 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
if (code1 + i <= code2) {
tok1[n1 - 1] = '\0';
addMapping(code1 + i, tok1 + 1, n1 - 2, 0);
+ ok = gTrue;
}
} else {
error(errSyntaxWarning, -1,
@@ -361,19 +372,99 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
tok3[n3 - 1] = '\0';
for (i = 0; code1 <= code2; ++code1, ++i) {
addMapping(code1, tok3 + 1, n3 - 2, i);
+ ok = gTrue;
}
-
} else {
error(errSyntaxWarning, -1,
"Illegal entry in bfrange block in ToUnicode CMap");
}
}
pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "begincidchar")) {
+ // the begincidchar operator is not allowed in ToUnicode CMaps,
+ // but some buggy PDF generators incorrectly use
+ // code-to-CID-type CMaps here
+ error(errSyntaxWarning, -1,
+ "Invalid 'begincidchar' operator in ToUnicode CMap");
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
+ if (!strcmp(tok1, "endcidchar")) {
+ break;
+ }
+ if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
+ !strcmp(tok2, "endcidchar")) {
+ error(errSyntaxWarning, -1,
+ "Illegal entry in cidchar block in ToUnicode CMap");
+ break;
+ }
+ if (!(tok1[0] == '<' && tok1[n1 - 1] == '>')) {
+ error(errSyntaxWarning, -1,
+ "Illegal entry in cidchar block in ToUnicode CMap");
+ continue;
+ }
+ tok1[n1 - 1] = '\0';
+ if (!parseHex(tok1 + 1, n1 - 2, &code1)) {
+ error(errSyntaxWarning, -1,
+ "Illegal entry in cidchar block in ToUnicode CMap");
+ continue;
+ }
+ if (code1 > maxCode) {
+ error(errSyntaxWarning, -1,
+ "Invalid entry in cidchar block in ToUnicode CMap");
+ }
+ addMappingInt(code1, atoi(tok2));
+ ok = gTrue;
+ }
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "begincidrange")) {
+ // the begincidrange operator is not allowed in ToUnicode CMaps,
+ // but some buggy PDF generators incorrectly use
+ // code-to-CID-type CMaps here
+ error(errSyntaxWarning, -1,
+ "Invalid 'begincidrange' operator in ToUnicode CMap");
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
+ if (!strcmp(tok1, "endcidrange")) {
+ break;
+ }
+ if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
+ !strcmp(tok2, "endcidrange") ||
+ !pst->getToken(tok3, sizeof(tok3), &n3) ||
+ !strcmp(tok3, "endcidrange")) {
+ error(errSyntaxWarning, -1,
+ "Illegal entry in cidrange block in ToUnicode CMap");
+ break;
+ }
+ if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' &&
+ tok2[0] == '<' && tok2[n2 - 1] == '>')) {
+ error(errSyntaxWarning,
+ -1, "Illegal entry in cidrange block in ToUnicode CMap");
+ continue;
+ }
+ tok1[n1 - 1] = tok2[n2 - 1] = '\0';
+ if (!parseHex(tok1 + 1, n1 - 2, &code1) ||
+ !parseHex(tok2 + 1, n2 - 2, &code2)) {
+ error(errSyntaxWarning, -1,
+ "Illegal entry in cidrange block in ToUnicode CMap");
+ continue;
+ }
+ if (code1 > maxCode || code2 > maxCode) {
+ error(errSyntaxWarning, -1,
+ "Invalid entry in cidrange block in ToUnicode CMap");
+ if (code2 > maxCode) {
+ code2 = maxCode;
+ }
+ }
+ for (i = atoi(tok3); code1 <= code2; ++code1, ++i) {
+ addMappingInt(code1, i);
+ ok = gTrue;
+ }
+ }
+ pst->getToken(tok1, sizeof(tok1), &n1);
} else {
strcpy(tok1, tok2);
}
}
delete pst;
+ return ok;
}
void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
@@ -426,6 +517,28 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
}
}
+void CharCodeToUnicode::addMappingInt(CharCode code, Unicode u) {
+ CharCode oldLen, i;
+
+ if (code > 0xffffff) {
+ // This is an arbitrary limit to avoid integer overflow issues.
+ // (I've seen CMaps with mappings for <ffffffff>.)
+ return;
+ }
+ if (code >= mapLen) {
+ oldLen = mapLen;
+ mapLen = mapLen ? 2 * mapLen : 256;
+ if (code >= mapLen) {
+ mapLen = (code + 256) & ~255;
+ }
+ map = (Unicode *)greallocn(map, mapLen, sizeof(Unicode));
+ for (i = oldLen; i < mapLen; ++i) {
+ map[i] = 0;
+ }
+ }
+ map[code] = u;
+}
+
CharCodeToUnicode::CharCodeToUnicode() {
tag = NULL;
map = NULL;
@@ -433,9 +546,6 @@ CharCodeToUnicode::CharCodeToUnicode() {
sMap = NULL;
sMapLen = sMapSize = 0;
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
CharCodeToUnicode::CharCodeToUnicode(GString *tagA) {
@@ -450,9 +560,6 @@ CharCodeToUnicode::CharCodeToUnicode(GString *tagA) {
sMap = NULL;
sMapLen = sMapSize = 0;
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
CharCodeToUnicode::CharCodeToUnicode(GString *tagA, Unicode *mapA,
@@ -471,9 +578,6 @@ CharCodeToUnicode::CharCodeToUnicode(GString *tagA, Unicode *mapA,
sMapLen = sMapLenA;
sMapSize = sMapSizeA;
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
CharCodeToUnicode::~CharCodeToUnicode() {
@@ -482,18 +586,13 @@ CharCodeToUnicode::~CharCodeToUnicode() {
}
gfree(map);
gfree(sMap);
-#if MULTITHREADED
- gDestroyMutex(&mutex);
-#endif
}
void CharCodeToUnicode::incRefCnt() {
#if MULTITHREADED
- gLockMutex(&mutex);
-#endif
+ gAtomicIncrement(&refCnt);
+#else
++refCnt;
-#if MULTITHREADED
- gUnlockMutex(&mutex);
#endif
}
@@ -501,11 +600,9 @@ void CharCodeToUnicode::decRefCnt() {
GBool done;
#if MULTITHREADED
- gLockMutex(&mutex);
-#endif
+ done = gAtomicDecrement(&refCnt) == 0;
+#else
done = --refCnt == 0;
-#if MULTITHREADED
- gUnlockMutex(&mutex);
#endif
if (done) {
delete this;