diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2019-09-12 17:09:50 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2019-09-18 09:20:20 +0100 |
commit | 89f3d6001728678755aca8c5a02e57bba72a0813 (patch) | |
tree | 396c52073786023946562aca7e0babcc4d5a975a | |
parent | f394c0722d3415ba03f57dc32dcd8484d3173b62 (diff) | |
download | ghostpdl-89f3d6001728678755aca8c5a02e57bba72a0813.tar.gz |
Bug 701568 followup: Fix RLE compressor.
The previous fix to the RLE compressor reveals an additional
existing issue to do with us not checking whether we have
space in the buffer to write the EOD byte.
Fixed here.
-rw-r--r-- | base/srle.c | 78 |
1 files changed, 45 insertions, 33 deletions
diff --git a/base/srle.c b/base/srle.c index 50de0d847..0c0186e04 100644 --- a/base/srle.c +++ b/base/srle.c @@ -59,7 +59,13 @@ enum { state_gt_012, /* -n bytes into a repeated run, n0 and n1 read. */ - state_lt_01 + state_lt_01, + + /* We have reached the end of data, but not written the marker. */ + state_eod_unmarked, + + /* We have reached the end of data, and written the marker. */ + state_eod }; #ifdef DEBUG_RLE @@ -294,43 +300,49 @@ run_len_0_n0_read: } } } - } - /* n1 is never valid here */ + /* n1 is never valid here */ - if (last) { - if (run_len == 0) { - /* EOD */ - if (wlimit - q < 1) { - ss->state = state_0; - goto no_output_room; - } - } else if (run_len > 0) { - /* Flush literal run + EOD */ - if (wlimit - q < run_len+2) { - ss->state = state_0; - goto no_output_room; + if (last) { + if (run_len == 0) { + /* EOD */ + if (wlimit - q < 1) { + ss->state = state_0; + goto no_output_room; + } + } else if (run_len > 0) { + /* Flush literal run + EOD */ + if (wlimit - q < run_len+2) { + ss->state = state_0; + goto no_output_room; + } + *++q = run_len; + memcpy(q+1, ss->literals, run_len); + q += run_len; + *++q = n0; + } else if (run_len < 0) { + /* Flush repeated run + EOD */ + if (wlimit - q < 3) { + ss->state = state_0; + goto no_output_room; + } + *++q = 257+run_len; /* Repeated run */ + *++q = n0; } - *++q = run_len; - memcpy(q+1, ss->literals, run_len); - q += run_len; - *++q = n0; - } else if (run_len < 0) { - /* Flush repeated run + EOD */ - if (wlimit - q < 3) { - ss->state = state_0; + case state_eod_unmarked: + if (wlimit - q < 1) { + ss->state = state_eod_unmarked; goto no_output_room; } - *++q = 257+run_len; /* Repeated run */ - *++q = n0; + *++q = 128; /* EOD */ + case state_eod: + ss->run_len = 0; + ss->state = state_0; + pr->ptr = p; + pw->ptr = q; + ss->record_left = rlimit - p; + debug_ate(pinit, p, qinit, q, EOFC); + return EOFC; } - *++q = 128; /* EOD */ - ss->run_len = 0; - ss->state = state_0; - pr->ptr = p; - pw->ptr = q; - ss->record_left = rlimit - p; - debug_ate(pinit, p, qinit, q, EOFC); - return EOFC; } /* Normal exit */ |