diff options
author | dsinclair <dsinclair@chromium.org> | 2016-10-13 07:54:09 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-10-13 07:54:09 -0700 |
commit | 6e5239c6e3891d78e7b9e8262c23cd129f0cdbb7 (patch) | |
tree | 826215286e0cab1f6db50e0c0efe201257dac69a /core/fxcodec | |
parent | f51e4dc24b3784a3af09278f2d38cf0ba1c4c8cd (diff) | |
download | pdfium-6e5239c6e3891d78e7b9e8262c23cd129f0cdbb7.tar.xz |
Verify number of ex flags matches number of ex items.
Currently the JBig2 decoder can leak subimages in the case where we mark
more items in EXFLAGS then we have SDNUMEXSYMS. This Cl checks for this
condition and fails the decode if it happens.
BUG=chromium:654365
Review-Url: https://codereview.chromium.org/2419553002
Diffstat (limited to 'core/fxcodec')
-rw-r--r-- | core/fxcodec/jbig2/JBig2_SddProc.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/core/fxcodec/jbig2/JBig2_SddProc.cpp b/core/fxcodec/jbig2/JBig2_SddProc.cpp index 1a7e96d26b..f6afb13497 100644 --- a/core/fxcodec/jbig2/JBig2_SddProc.cpp +++ b/core/fxcodec/jbig2/JBig2_SddProc.cpp @@ -38,6 +38,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith( uint32_t SBNUMSYMS; uint8_t SBSYMCODELEN; int32_t RDXI, RDYI; + uint32_t num_ex_syms; CJBig2_Image** SBSYMS; std::unique_ptr<CJBig2_ArithIaidDecoder> IAID; std::unique_ptr<CJBig2_SymbolDict> pDict; @@ -235,6 +236,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith( EXINDEX = 0; CUREXFLAG = 0; EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS); + num_ex_syms = 0; while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) { IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH); if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) { @@ -243,12 +245,19 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith( } if (EXRUNLENGTH != 0) { for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) { + if (CUREXFLAG) + num_ex_syms++; EXFLAGS[I] = CUREXFLAG; } } EXINDEX = EXINDEX + EXRUNLENGTH; CUREXFLAG = !CUREXFLAG; } + if (num_ex_syms > SDNUMEXSYMS) { + FX_Free(EXFLAGS); + goto failed; + } + pDict.reset(new CJBig2_SymbolDict); I = J = 0; for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) { @@ -303,6 +312,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman( int32_t RDXI, RDYI; uint32_t BMSIZE; uint32_t stride; + uint32_t num_ex_syms; CJBig2_Image** SBSYMS; std::unique_ptr<CJBig2_HuffmanDecoder> pHuffmanDecoder( new CJBig2_HuffmanDecoder(pStream)); @@ -555,6 +565,7 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman( pTable.reset(new CJBig2_HuffmanTable(HuffmanTable_B1, HuffmanTable_B1_Size, HuffmanTable_HTOOB_B1)); EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS); + num_ex_syms = 0; while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) { if (pHuffmanDecoder->decodeAValue(pTable.get(), (int*)&EXRUNLENGTH) != 0) { FX_Free(EXFLAGS); @@ -566,12 +577,20 @@ CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman( } if (EXRUNLENGTH != 0) { for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) { + if (CUREXFLAG) + num_ex_syms++; + EXFLAGS[I] = CUREXFLAG; } } EXINDEX = EXINDEX + EXRUNLENGTH; CUREXFLAG = !CUREXFLAG; } + if (num_ex_syms > SDNUMEXSYMS) { + FX_Free(EXFLAGS); + goto failed; + } + I = J = 0; for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) { if (EXFLAGS[I] && J < SDNUMEXSYMS) { |