diff options
author | L Peter Deutsch <lpd@ghostscript.com> | 2000-11-01 22:36:13 +0000 |
---|---|---|
committer | L Peter Deutsch <lpd@ghostscript.com> | 2000-11-01 22:36:13 +0000 |
commit | eacb10b0c024ebb6baca8f6176d4b2dcc3e61cd7 (patch) | |
tree | b5bd2ec75addd400b9524f18ac7fcd0272b46abb | |
parent | e6c20f5615250cbde2d197e069f668492b4aeac9 (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.htm | 3 | ||||
-rw-r--r-- | gs/src/sa85d.h | 2 | ||||
-rw-r--r-- | gs/src/sbhc.c | 5 | ||||
-rw-r--r-- | gs/src/scfd.c | 1 | ||||
-rw-r--r-- | gs/src/scommon.h | 1 | ||||
-rw-r--r-- | gs/src/sfilter1.c | 2 | ||||
-rw-r--r-- | gs/src/slzwd.c | 1 | ||||
-rw-r--r-- | gs/src/srlx.h | 2 | ||||
-rw-r--r-- | gs/src/sstring.h | 2 | ||||
-rw-r--r-- | gs/src/stream.c | 11 | ||||
-rw-r--r-- | gs/src/strimpl.h | 8 | ||||
-rw-r--r-- | gs/src/szlibd.c | 1 | ||||
-rw-r--r-- | gs/src/zfile.c | 4 | ||||
-rw-r--r-- | gs/src/zfproc.c | 1 |
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); |