summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordsinclair <dsinclair@chromium.org>2016-10-13 07:54:09 -0700
committerCommit bot <commit-bot@chromium.org>2016-10-13 07:54:09 -0700
commit6e5239c6e3891d78e7b9e8262c23cd129f0cdbb7 (patch)
tree826215286e0cab1f6db50e0c0efe201257dac69a
parentf51e4dc24b3784a3af09278f2d38cf0ba1c4c8cd (diff)
downloadpdfium-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
-rw-r--r--core/fxcodec/jbig2/JBig2_SddProc.cpp19
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) {