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;