119 lines
3.5 KiB
Diff
119 lines
3.5 KiB
Diff
|
From 3b2ad1f24d2e9705481f9feb6835aa3e851726ac Mon Sep 17 00:00:00 2001
|
||
|
From: Robin Watts <Robin.Watts@artifex.com>
|
||
|
Date: Thu, 12 Sep 2019 17:09:50 +0100
|
||
|
Subject: [PATCH] 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.
|
||
|
---
|
||
|
base/srle.c | 78 ++++++++++++++++++++++++++++++-----------------------
|
||
|
1 file 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 */
|
||
|
--
|
||
|
2.46.2
|
||
|
|