shithub: jbig2

Download patch

ref: e28c2f1eb04f1c3a472f50ceef6aab62e40b4d73
parent: d652e026e5b90638d13c6bc4f86f499ea85e096b
author: Sebastian Rasmussen <sebras@gmail.com>
date: Sun Jul 1 09:28:26 EDT 2018

jbig2dec: Occasional runlengths may be zero, avoid infinite sequence.

Previously any runlength when exporting symbol dictionary symbols
being zero caused a fatal error. These are not disallowed by the
specification, but if there is an infinite sequence of them the
decoder cannot make any progress in establishing the dictionary
of exported symbols from a symbol dictionary. This may happen
when the huffman or arithmetic integer decoder due to e.g. fuzzed
input data returns an infinite sequence of zeroes when the
decoder attempts to read the runlengths. This case of infinite
zero runlengths is best handled as a fatal error. An arbitrary
limit of 1000 of zero runlengths in sequence (an approximation of
an infinite sequence of zero runlengths) will now cause a fatal
error, but the occasional zero runlength will be accepted without
any kind of message.

--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -250,6 +250,7 @@
     Jbig2TextRegionParams tparams;
     Jbig2Image *image = NULL;
     Jbig2Image *glyph = NULL;
+    uint32_t emptyruns = 0;
 
     memset(&tparams, 0, sizeof(tparams));
 
@@ -763,13 +764,18 @@
 
             /* prevent infinite loop */
             if (EXRUNLENGTH > limit - i || (exflag && (EXRUNLENGTH + j > params->SDNUMEXSYMS))) {
-                if (EXRUNLENGTH <= 0) {
-                    jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "runlength too small in export symbol table (%u <= 0)", EXRUNLENGTH);
+                /* prevent infinite list of empty runs, 1000 is just an arbitrary number */
+                if (EXRUNLENGTH <= 0 && ++emptyruns == 1000) {
+                    jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "runlengths are too small when exporting symbol table");
                     /* skip to the cleanup code and return SDEXSYMS = NULL */
                     jbig2_sd_release(ctx, SDEXSYMS);
                     SDEXSYMS = NULL;
                     break;
-                } else if (EXRUNLENGTH > limit - i) {
+                } else if (EXRUNLENGTH > 0) {
+                    emptyruns = 0;
+                }
+
+                if (EXRUNLENGTH > limit - i) {
                     jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "runlength too large in export symbol table (%u > %u - %u)", EXRUNLENGTH, params->SDNUMEXSYMS, j);
                     jbig2_sd_release(ctx, SDEXSYMS);
                     SDEXSYMS = NULL;