shithub: jbig2

Download patch

ref: 43bece48d92766da751635b9faa7e5f01b846e44
parent: e28c2f1eb04f1c3a472f50ceef6aab62e40b4d73
author: Sebastian Rasmussen <sebras@gmail.com>
date: Sat Jun 30 20:36:28 EDT 2018

jbig2dec: Cap runlength for exported symbols, don't error out.

Capping is necessary because the preceding symbol dictionary segment header
stated that a specific number of symbols will be exported to succeeding symbol
dictionaries. By capping overly long runlengths of exported symbol instead of
reporting fatal errors somewhat corrupt JBIG2 bitstreams may still partially
render, albeit with a warning about the capping taking place.

--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -762,30 +762,26 @@
                 break;
             }
 
-            /* prevent infinite loop */
-            if (EXRUNLENGTH > limit - i || (exflag && (EXRUNLENGTH + j > params->SDNUMEXSYMS))) {
-                /* 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 > 0) {
-                    emptyruns = 0;
-                }
+            /* 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, "runlength too small in export symbol table (%u == 0 i = %u limit = %u)", EXRUNLENGTH, i, limit);
+                /* skip to the cleanup code and return SDEXSYMS = NULL */
+                jbig2_sd_release(ctx, SDEXSYMS);
+                SDEXSYMS = NULL;
+                break;
+            } 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;
-                    break;
-                } else if (EXRUNLENGTH < limit - i) {
-                    jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "runlength too large in export symbol table, limiting export (%u > %u - %u)", EXRUNLENGTH, params->SDNUMEXSYMS, j);
-                    jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "old=%u new=%u limit=%u", EXRUNLENGTH, params->SDNUMEXSYMS - j, limit);
-                    EXRUNLENGTH = params->SDNUMEXSYMS - j;
-                }
+            if (EXRUNLENGTH > limit - i) {
+                jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "exporting more symbols than available (%u > %u), capping", i + EXRUNLENGTH, limit);
+                EXRUNLENGTH = limit - i;
             }
+            if (exflag && j + EXRUNLENGTH > params->SDNUMEXSYMS) {
+                jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "exporting more symbols than may be exported (%u > %u), capping", j + EXRUNLENGTH, params->SDNUMEXSYMS);
+                EXRUNLENGTH = params->SDNUMEXSYMS - j;
+            }
+
             for (k = 0; k < EXRUNLENGTH; k++) {
                 if (exflag) {
                     Jbig2Image *img;