ref: a61cbd41c67f7aef893075a3521090659887a995
parent: 8aa97f4267efe94b814bd5fa9c9b0ce6312fc095
author: Sebastian Rasmussen <sebras@gmail.com>
date: Tue Apr 24 09:39:46 EDT 2018
jbig2dec: Print errors when out of boundary values occur. According to the specification in 6.4.5 when decoding text regions, where OOB values in IDS indicate that the last symbol in a strip has been decoded, or in 6.5.5 when decoding symbol dictionaries, where OOB values in DW indicate that all the symbols in a height class have been decoded. When decoding any other symbols than IDS or DW, OOB values are not expected, so report these as fatal errors.
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -330,9 +330,9 @@
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode height class delta");
goto cleanup2;
}
-
- if (code != 0) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "error or OOB decoding height class delta (%d)", code);
+ if (code > 0) {
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "OOB decoding height class delta");
+ goto cleanup2;
}
if (!params->SDHUFF && jbig2_arith_has_reached_marker(as)) {
@@ -367,10 +367,9 @@
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode DW");
goto cleanup4;
}
-
/* 6.5.5 (4c.i) */
- if (code == 1) {
- jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, " OOB signals end of height class %d", HCHEIGHT);
+ if (code > 0) {
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "OOB when decoding DW signals end of height class %d", HCHEIGHT);
break;
}
@@ -435,10 +434,14 @@
code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode number of symbols in aggregate glyph");
goto cleanup4;
}
- if (code || (int32_t) REFAGGNINST <= 0) {
- code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "invalid number of symbols or OOB in aggregate glyph");
+ if (code > 0) {
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB in number of symbols in aggregate glyph");
goto cleanup4;
}
+ if ((int32_t) REFAGGNINST <= 0) {
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "invalid number of symbols in aggregate glyph");
+ goto cleanup4;
+ }
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "aggregate symbol coding (%d instances)", REFAGGNINST);
@@ -567,6 +570,10 @@
code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode data");
goto cleanup4;
}
+ if (code1 > 0 || code2 > 0 || code3 > 0 || code4 > 0) {
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB in single refinement/aggregate coded symbol data");
+ goto cleanup4;
+ }
if (ID >= ninsyms + NSYMSDECODED) {
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "refinement references unknown symbol %d", ID);
@@ -656,6 +663,10 @@
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "error decoding size of collective bitmap");
goto cleanup4;
}
+ if (code > 0) {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB obtained when decoding size of collective bitmap");
+ goto cleanup4;
+ }
/* skip any bits before the next byte boundary */
jbig2_huffman_skip(hs);
@@ -766,12 +777,18 @@
SDEXSYMS = NULL;
break;
}
+ if (code > 0) {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB when decoding runlength for exported symbols");
+ /* skip to the cleanup code and return SDEXSYMS = NULL */
+ jbig2_sd_release(ctx, SDEXSYMS);
+ SDEXSYMS = NULL;
+ break;
+ }
+
/* prevent infinite loop */
zerolength = exrunlength > 0 ? 0 : zerolength + 1;
- if (code || exrunlength > limit - i || zerolength > 4 || (exflag && (exrunlength + j > params->SDNUMEXSYMS))) {
- if (code)
- jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode exrunlength for exported symbols");
- else if (exrunlength <= 0)
+ if (exrunlength > limit - i || zerolength > 4 || (exflag && (exrunlength + j > params->SDNUMEXSYMS))) {
+ if (exrunlength <= 0)
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "runlength too small in export symbol table (%d <= 0)", exrunlength);
else
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -112,6 +112,10 @@
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to read huffman runcode lengths");
goto cleanup1;
}
+ if (code > 0) {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB decoding huffman runcode lengths");
+ goto cleanup1;
+ }
runcodelengths[index].RANGELEN = 0;
runcodelengths[index].RANGELOW = index;
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, " read runcode%d length %d", index, runcodelengths[index].PREFLEN);
@@ -138,6 +142,10 @@
code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "error reading symbol ID huffman table");
goto cleanup1;
}
+ if (err > 0) {
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB decoding symbol ID huffman table");
+ goto cleanup1;
+ }
if (code < 0 || code >= 35) {
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "symbol ID huffman table out of range");
goto cleanup1;
@@ -167,6 +175,10 @@
code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to read huffman code");
goto cleanup1;
}
+ if (err > 0) {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB decoding huffman code");
+ goto cleanup1;
+ }
}
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, " read runcode%d at index %d (length %d range %d)", code, index, len, range);
if (index + range > SBNUMSYMS) {
@@ -219,6 +231,10 @@
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode strip T");
goto cleanup2;
}
+ if (code > 0) {
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB obtained when decoding strip T");
+ goto cleanup2;
+ }
/* 6.4.5 (2) */
STRIPT *= -(params->SBSTRIPS);
@@ -237,6 +253,10 @@
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode delta T");
goto cleanup2;
}
+ if (code > 0) {
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB obtained when decoding delta T");
+ goto cleanup2;
+ }
DT *= params->SBSTRIPS;
STRIPT += DT;
@@ -255,6 +275,10 @@
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode strip symbol S-difference");
goto cleanup2;
}
+ if (code > 0) {
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB obtained when decoding strip symbol S-difference");
+ goto cleanup2;
+ }
FIRSTS += DFS;
CURS = FIRSTS;
first_symbol = FALSE;
@@ -273,8 +297,8 @@
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode symbol instance S coordinate");
goto cleanup2;
}
- if (code) {
- /* decoded an OOB, reached end of strip */
+ if (code > 0) {
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "OOB obtained when decoding symbol instance S coordinate signals end of strip with T value %d", DT);
break;
}
CURS += IDS + params->SBDSOFFSET;
@@ -292,6 +316,10 @@
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode symbol instance T coordinate");
goto cleanup2;
}
+ if (code > 0) {
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "OOB obtained when decoding symbol instance T coordinate");
+ goto cleanup2;
+ }
T = STRIPT + CURT;
/* (3b.iv) / 6.4.10 - decode the symbol id */
@@ -304,6 +332,10 @@
code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to obtain symbol instance symbol ID");
goto cleanup2;
}
+ if (code > 0) {
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB obtained when decoding symbol instance symbol ID");
+ goto cleanup2;
+ }
if (ID >= SBNUMSYMS) {
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "symbol id out of range! (%d/%d)", ID, SBNUMSYMS);
goto cleanup2;
@@ -333,6 +365,10 @@
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode symbol bitmap refinement indicator");
goto cleanup2;
}
+ if (code > 0) {
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB obtained when decoding symbol bitmap refinement indicator");
+ goto cleanup2;
+ }
} else {
RI = 0;
}
@@ -366,6 +402,11 @@
if (code1 < 0 || code2 < 0 || code3 < 0 || code4 < 0 || code5 < 0) {
jbig2_image_release(ctx, IB);
code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode data");
+ goto cleanup2;
+ }
+ if (code1 > 0 || code2 > 0 || code3 > 0 || code4 > 0 || code5 > 0) {
+ jbig2_image_release(ctx, IB);
+ code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "OOB obtained when decoding symbol instance refinement data");
goto cleanup2;
}