diff options
author | LE GARREC Vincent <gitlab-freedesktop@le-garrec.fr> | 2019-01-27 10:19:10 +0000 |
---|---|---|
committer | Albert Astals Cid <tsdgeos@yahoo.es> | 2019-01-27 10:19:10 +0000 |
commit | c3577325de5b9d59539c2413dcc66283df062ffa (patch) | |
tree | aff30816e1b813c13f3d35c1c606227135abd4f9 /poppler/JBIG2Stream.cc | |
parent | a73c80e024e8b2a9613926793165da07017dfbb2 (diff) |
ofz-8725: Undefined-shift in JBIG2HuffmanDecoder::buildTable
Diffstat (limited to 'poppler/JBIG2Stream.cc')
-rw-r--r-- | poppler/JBIG2Stream.cc | 41 |
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; |