shithub: jbig2

Download patch

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;
                 }