summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorL Peter Deutsch <lpd@ghostscript.com>2000-11-01 22:36:13 +0000
committerL Peter Deutsch <lpd@ghostscript.com>2000-11-01 22:36:13 +0000
commiteacb10b0c024ebb6baca8f6176d4b2dcc3e61cd7 (patch)
treeb5bd2ec75addd400b9524f18ac7fcd0272b46abb
parente6c20f5615250cbde2d197e069f668492b4aeac9 (diff)
Fix: Decoding filters that didn't detect an EOD in the source data still
tried to look 1 byte ahead, occasionally causing obscure errors. The fix unfortunately required adding a new architectural requirement to the implementation of such filters. (fix from igor@artifex.com) git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@851 a1074d23-0009-0410-80fe-cf8c14f379e6
-rw-r--r--gs/doc/News.htm3
-rw-r--r--gs/src/sa85d.h2
-rw-r--r--gs/src/sbhc.c5
-rw-r--r--gs/src/scfd.c1
-rw-r--r--gs/src/scommon.h1
-rw-r--r--gs/src/sfilter1.c2
-rw-r--r--gs/src/slzwd.c1
-rw-r--r--gs/src/srlx.h2
-rw-r--r--gs/src/sstring.h2
-rw-r--r--gs/src/stream.c11
-rw-r--r--gs/src/strimpl.h8
-rw-r--r--gs/src/szlibd.c1
-rw-r--r--gs/src/zfile.c4
-rw-r--r--gs/src/zfproc.c1
14 files changed, 32 insertions, 12 deletions
diff --git a/gs/doc/News.htm b/gs/doc/News.htm
index 48d989688..26ba9fc45 100644
--- a/gs/doc/News.htm
+++ b/gs/doc/News.htm
@@ -75,6 +75,9 @@ metrics computed from FontBBox rather than the horizontal metrics.
(PDF interpreter)
- The interpreter now skips to the next EOL after reading the data
following the ID operator.
+(Streams)
+ - All decoding filters that recognize an EOD in the source data
+must now have an init procedure that sets state->min_left = 1.
</pre>
diff --git a/gs/src/sa85d.h b/gs/src/sa85d.h
index e3ccaa9f3..63dc76a5a 100644
--- a/gs/src/sa85d.h
+++ b/gs/src/sa85d.h
@@ -36,7 +36,7 @@ typedef struct stream_A85D_state_s {
/* We define the initialization procedure here, so that the scanner */
/* can avoid a procedure call. */
#define s_A85D_init_inline(ss)\
- ((ss)->word = 0, (ss)->odd = 0)
+ ((ss)->min_left = 1, (ss)->word = 0, (ss)->odd = 0)
extern const stream_template s_A85D_template;
#endif /* sa85d_INCLUDED */
diff --git a/gs/src/sbhc.c b/gs/src/sbhc.c
index 342c42c88..763a2282c 100644
--- a/gs/src/sbhc.c
+++ b/gs/src/sbhc.c
@@ -183,13 +183,14 @@ s_BHCD_init(register stream_state * st)
min(hcd_initial_bits, ss->definition.num_counts);
uint dsize = hc_sizeof_decoding(&ss->definition, initial_bits);
hcd_code *decode = ss->decode.codes =
- (hcd_code *) gs_alloc_byte_array(st->memory, dsize,
- sizeof(hcd_code), "BHCD decode");
+ (hcd_code *) gs_alloc_byte_array(st->memory, dsize,
+ sizeof(hcd_code), "BHCD decode");
if (decode == 0)
return ERRC;
/****** WRONG ******/
hc_make_decoding(decode, &ss->definition, initial_bits);
+ st->min_left = 1;
return s_BHCD_reinit(st);
}
diff --git a/gs/src/scfd.c b/gs/src/scfd.c
index c06389fe1..8b3cff7f0 100644
--- a/gs/src/scfd.c
+++ b/gs/src/scfd.c
@@ -75,6 +75,7 @@ s_CFD_init(stream_state * st)
ss->rpos = ss->wpos = raster - 1;
ss->eol_count = 0;
ss->invert = white;
+ ss->min_left = 1;
return 0;
}
diff --git a/gs/src/scommon.h b/gs/src/scommon.h
index 7dd0318c9..897fcef5b 100644
--- a/gs/src/scommon.h
+++ b/gs/src/scommon.h
@@ -157,6 +157,7 @@ stream_proc_report_error(s_no_report_error);
const stream_template *template;\
gs_memory_t *memory;\
stream_proc_report_error((*report_error));\
+ int min_left; /* required bytes for lookahead */ \
char error_string[STREAM_MAX_ERROR_STRING + 1]
struct stream_state_s {
stream_state_common;
diff --git a/gs/src/sfilter1.c b/gs/src/sfilter1.c
index 9bd802f20..c2d86748f 100644
--- a/gs/src/sfilter1.c
+++ b/gs/src/sfilter1.c
@@ -169,6 +169,8 @@ s_SFD_init(stream_state * st)
ss->match = 0;
ss->copy_count = 0;
+ ss->min_left = (ss->eod.size != 0);
+
return 0;
}
diff --git a/gs/src/slzwd.c b/gs/src/slzwd.c
index 0e1b264a6..1cb79f5d9 100644
--- a/gs/src/slzwd.c
+++ b/gs/src/slzwd.c
@@ -84,6 +84,7 @@ s_LZWD_init(stream_state * st)
return ERRC;
/****** WRONG ******/
ss->table.decode = dc;
+ ss->min_left = 1;
return s_LZWD_reset(st);
}
diff --git a/gs/src/srlx.h b/gs/src/srlx.h
index 74579bb19..5937392e2 100644
--- a/gs/src/srlx.h
+++ b/gs/src/srlx.h
@@ -66,7 +66,7 @@ typedef struct stream_RLD_state_s {
#define s_RLD_set_defaults_inline(ss)\
((ss)->EndOfData = true)
#define s_RLD_init_inline(ss)\
- ((ss)->copy_left = 0)
+ ((ss)->min_left = ((ss)->EndOfData ? 1 : 0), (ss)->copy_left = 0)
extern const stream_template s_RLD_template;
#endif /* srlx_INCLUDED */
diff --git a/gs/src/sstring.h b/gs/src/sstring.h
index 79f557ca9..a2168c26a 100644
--- a/gs/src/sstring.h
+++ b/gs/src/sstring.h
@@ -48,7 +48,7 @@ typedef struct stream_AXD_state_s {
gs_private_st_simple(st_AXD_state, stream_AXD_state,\
"ASCIIHexDecode state")
#define s_AXD_init_inline(ss)\
- ((ss)->odd = -1, 0)
+ ((ss)->min_left = 1, (ss)->odd = -1, 0)
extern const stream_template s_AXD_template;
/* PSStringDecode */
diff --git a/gs/src/stream.c b/gs/src/stream.c
index 6d5a7f059..af31172d5 100644
--- a/gs/src/stream.c
+++ b/gs/src/stream.c
@@ -106,6 +106,7 @@ s_init(stream *s, gs_memory_t * mem)
{
s->memory = mem;
s->report_error = s_no_report_error;
+ s->min_left = 0;
s->error_string[0] = 0;
s->prev = s->next = 0; /* clean for GC */
s->file_name.data = 0; /* ibid. */
@@ -133,6 +134,7 @@ s_init_state(stream_state *st, const stream_template *template,
st->template = template;
st->memory = mem;
st->report_error = s_no_report_error;
+ st->min_left = 0;
}
stream_state *
s_alloc_state(gs_memory_t * mem, gs_memory_type_ptr_t stype,
@@ -420,15 +422,14 @@ sclose(register stream * s)
/*
* Define the minimum amount of data that must be left in an input buffer
* after a read operation to handle filter read-ahead. This is 1 byte for
- * filters (including procedure data sources) that haven't reached EOD,
- * 0 for files.
+ * filters (including procedure data sources) that require EOD but
+ * haven't reached EOD, 0 for files and for filters that have no EOD.
*/
int
sbuf_min_left(const stream *s)
{
- return
- (s->strm == 0 ? (s->end_status != CALLC ? 0 : 1) :
- s->end_status == EOFC || s->end_status == ERRC ? 0 : 1);
+ return
+ (s->end_status == EOFC || s->end_status == ERRC ? 0 : s->state->min_left);
}
/*
diff --git a/gs/src/strimpl.h b/gs/src/strimpl.h
index d4f894832..45ba3485c 100644
--- a/gs/src/strimpl.h
+++ b/gs/src/strimpl.h
@@ -109,6 +109,14 @@
*/
/*
+ * Note that all decoding filters that require an explicit EOD in the
+ * source data must have an init procedure that sets min_left = 1.
+ * This effectively provides a 1-byte lookahead in the source data,
+ * which is required so that the stream can close itself "after reading
+ * the last byte of data" (per Adobe specification), as noted above.
+ */
+
+/*
* Define a template for creating a stream.
*
* The meaning of min_in_size and min_out_size is the following:
diff --git a/gs/src/szlibd.c b/gs/src/szlibd.c
index ea5e3f28a..2007fa900 100644
--- a/gs/src/szlibd.c
+++ b/gs/src/szlibd.c
@@ -40,6 +40,7 @@ s_zlibD_init(stream_state * st)
s_zlib_free_dynamic_state(ss);
return ERRC; /****** WRONG ******/
}
+ st->min_left=1;
return 0;
}
diff --git a/gs/src/zfile.c b/gs/src/zfile.c
index 33fd3b483..951b9ff55 100644
--- a/gs/src/zfile.c
+++ b/gs/src/zfile.c
@@ -848,9 +848,9 @@ filter_open(const char *file_access, uint buffer_size, ref * pfile,
} else if (st != 0) /* might not have client parameters */
memcpy(sst, st, ssize);
s->state = sst;
- sst->template = template;
- sst->memory = mem;
+ s_init_state(sst, template, mem);
sst->report_error = filter_report_error;
+
if (template->init != 0) {
code = (*template->init)(sst);
if (code < 0) {
diff --git a/gs/src/zfproc.c b/gs/src/zfproc.c
index 0b3c46a7f..3cc3c4104 100644
--- a/gs/src/zfproc.c
+++ b/gs/src/zfproc.c
@@ -80,6 +80,7 @@ s_proc_init(ref * sop, stream ** psstrm, uint mode,
sstrm->procs.process = temp->process;
state->template = temp;
state->memory = mem;
+ state->min_left = 1;
state->eof = 0;
state->proc = *sop;
make_empty_string(&state->data, a_all);