summaryrefslogtreecommitdiff
path: root/poppler/JBIG2Stream.cc
diff options
context:
space:
mode:
authorLE GARREC Vincent <gitlab-freedesktop@le-garrec.fr>2019-01-27 10:19:10 +0000
committerAlbert Astals Cid <tsdgeos@yahoo.es>2019-01-27 10:19:10 +0000
commitc3577325de5b9d59539c2413dcc66283df062ffa (patch)
treeaff30816e1b813c13f3d35c1c606227135abd4f9 /poppler/JBIG2Stream.cc
parenta73c80e024e8b2a9613926793165da07017dfbb2 (diff)
ofz-8725: Undefined-shift in JBIG2HuffmanDecoder::buildTable
Diffstat (limited to 'poppler/JBIG2Stream.cc')
-rw-r--r--poppler/JBIG2Stream.cc41
1 files changed, 29 insertions, 12 deletions
diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index a5329aeb..9670e895 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -327,7 +327,7 @@ public:
unsigned int readBit();
// Sort the table by prefix length and assign prefix values.
- void buildTable(JBIG2HuffmanTable *table, unsigned int len);
+ static bool buildTable(JBIG2HuffmanTable *table, unsigned int len);
private:
@@ -412,7 +412,7 @@ unsigned int JBIG2HuffmanDecoder::readBit() {
return (buf >> bufLen) & 1;
}
-void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, unsigned int len) {
+bool JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, unsigned int len) {
unsigned int i, j, k, prefix;
JBIG2HuffmanTable tab;
@@ -448,10 +448,17 @@ void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, unsigned int len)
prefix = 0;
table[i++].prefix = prefix++;
for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
- prefix <<= table[i].prefixLen - table[i-1].prefixLen;
+ if (table[i].prefixLen - table[i-1].prefixLen > 32) {
+ error(errSyntaxError, -1, "Failed to build table for JBIG2 stream");
+ return false;
+ } else {
+ prefix <<= table[i].prefixLen - table[i-1].prefixLen;
+ }
table[i].prefix = prefix++;
}
}
+
+ return true;
}
//------------------------------------------------------------------------
@@ -2007,7 +2014,7 @@ void JBIG2Stream::readTextRegionSeg(unsigned int segNum, bool imm,
unsigned int *refSegs, unsigned int nRefSegs) {
JBIG2Bitmap *bitmap;
JBIG2HuffmanTable runLengthTab[36];
- JBIG2HuffmanTable *symCodeTab;
+ JBIG2HuffmanTable *symCodeTab = nullptr;
JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
@@ -2229,7 +2236,12 @@ void JBIG2Stream::readTextRegionSeg(unsigned int segNum, bool imm,
runLengthTab[34].rangeLen = 7;
runLengthTab[35].prefixLen = 0;
runLengthTab[35].rangeLen = jbig2HuffmanEOT;
- huffDecoder->buildTable(runLengthTab, 35);
+ if (!JBIG2HuffmanDecoder::buildTable(runLengthTab, 35)) {
+ huff = false;
+ }
+ }
+
+ if (huff) {
symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1,
sizeof(JBIG2HuffmanTable));
for (i = 0; i < numSyms; ++i) {
@@ -2255,12 +2267,17 @@ void JBIG2Stream::readTextRegionSeg(unsigned int segNum, bool imm,
}
symCodeTab[numSyms].prefixLen = 0;
symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
- huffDecoder->buildTable(symCodeTab, numSyms);
+ if (!JBIG2HuffmanDecoder::buildTable(symCodeTab, numSyms)) {
+ huff = false;
+ gfree(symCodeTab);
+ symCodeTab = nullptr;
+ }
huffDecoder->reset();
// set up the arithmetic decoder
- } else {
- symCodeTab = nullptr;
+ }
+
+ if (!huff) {
resetIntStats(symCodeLen);
arithDecoder->start();
}
@@ -4130,10 +4147,10 @@ void JBIG2Stream::readCodeTableSeg(unsigned int segNum, unsigned int length) {
huffTab[i].val = 0;
huffTab[i].prefixLen = 0;
huffTab[i].rangeLen = jbig2HuffmanEOT;
- huffDecoder->buildTable(huffTab, i);
-
- // create and store the new table segment
- segments->push_back(new JBIG2CodeTable(segNum, huffTab));
+ if (JBIG2HuffmanDecoder::buildTable(huffTab, i)) {
+ // create and store the new table segment
+ segments->push_back(new JBIG2CodeTable(segNum, huffTab));
+ }
return;