diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/filter-basic.c | 268 | ||||
-rw-r--r-- | source/fitz/filter-dct.c | 25 | ||||
-rw-r--r-- | source/fitz/filter-fax.c | 54 | ||||
-rw-r--r-- | source/fitz/filter-flate.c | 35 | ||||
-rw-r--r-- | source/fitz/filter-jbig2.c | 19 | ||||
-rw-r--r-- | source/fitz/filter-lzw.c | 23 | ||||
-rw-r--r-- | source/fitz/filter-predict.c | 23 | ||||
-rw-r--r-- | source/fitz/stream-open.c | 85 | ||||
-rw-r--r-- | source/fitz/stream-prog.c | 19 | ||||
-rw-r--r-- | source/fitz/stream-read.c | 97 | ||||
-rw-r--r-- | source/pdf/pdf-op-run.c | 25 |
11 files changed, 395 insertions, 278 deletions
diff --git a/source/fitz/filter-basic.c b/source/fitz/filter-basic.c index 3a64ee93..5defe066 100644 --- a/source/fitz/filter-basic.c +++ b/source/fitz/filter-basic.c @@ -14,21 +14,34 @@ struct null_filter { fz_stream *chain; int remain; - int pos; + int offset; + unsigned char buffer[4096]; }; static int -read_null(fz_stream *stm, unsigned char *buf, int len) +next_null(fz_stream *stm, int max) { struct null_filter *state = stm->state; - int amount = fz_mini(len, state->remain); int n; - fz_seek(state->chain, state->pos, 0); - n = fz_read(state->chain, buf, amount); + if (state->remain == 0) + return EOF; + fz_seek(state->chain, state->offset, 0); + n = fz_available(state->chain, max); + if (n > state->remain) + n = state->remain; + if (n > sizeof(state->buffer)) + n = sizeof(state->buffer); + memcpy(state->buffer, state->chain->rp, n); + stm->rp = state->buffer; + stm->wp = stm->rp + n; + if (n == 0) + return EOF; + state->chain->rp += n; state->remain -= n; - state->pos += n; - return n; + state->offset += n; + stm->pos += n; + return *stm->rp++; } static void @@ -60,7 +73,7 @@ fz_open_null(fz_stream *chain, int len, int offset) state = fz_malloc_struct(ctx, struct null_filter); state->chain = chain; state->remain = len; - state->pos = offset; + state->offset = offset; } fz_catch(ctx) { @@ -68,7 +81,7 @@ fz_open_null(fz_stream *chain, int len, int offset) fz_rethrow(ctx); } - return fz_new_stream(ctx, state, read_null, close_null, rebind_null); + return fz_new_stream(ctx, state, next_null, close_null, rebind_null); } /* Concat filter concatenates several streams into one */ @@ -79,48 +92,51 @@ struct concat_filter int count; int current; int pad; /* 1 if we should add whitespace padding between streams */ - int ws; /* 1 if we should send a whitespace padding byte next */ + unsigned char ws_buf; fz_stream *chain[1]; }; static int -read_concat(fz_stream *stm, unsigned char *buf, int len) +next_concat(fz_stream *stm, int max) { struct concat_filter *state = (struct concat_filter *)stm->state; int n; - int read = 0; - if (len <= 0) - return 0; - - while (state->current != state->count && len > 0) + while (state->current < state->count) { - /* If we need to send a whitespace char, do that */ - if (state->ws) + /* Read the next block of underlying data. */ + if (stm->wp == state->chain[state->current]->wp) + state->chain[state->current]->rp = stm->wp; + n = fz_available(state->chain[state->current], max); + if (n) { - *buf++ = 32; - read++; - len--; - state->ws = 0; - continue; + stm->rp = state->chain[state->current]->rp; + stm->wp = state->chain[state->current]->wp; + stm->pos += n; + return *stm->rp++; } - /* Otherwise, read as much data as will fit in the buffer */ - n = fz_read(state->chain[state->current], buf, len); - read += n; - buf += n; - len -= n; - /* If we didn't read any, then we must have hit the end of - * our buffer space. Move to the next stream, and remember to - * pad. */ - if (n == 0) + else { - fz_close(state->chain[state->current]); + if (state->chain[state->current]->error) + { + stm->error = 1; + break; + } state->current++; - state->ws = state->pad; + fz_close(state->chain[state->current-1]); + if (state->pad) + { + stm->rp = &state->ws_buf; + stm->wp = stm->rp + 1; + stm->pos++; + return 32; + } } } - return read; + stm->rp = stm->wp; + + return EOF; } static void @@ -161,9 +177,9 @@ fz_open_concat(fz_context *ctx, int len, int pad) state->count = 0; state->current = 0; state->pad = pad; - state->ws = 0; /* We never send padding byte at the start */ + state->ws_buf = 32; - return fz_new_stream(ctx, state, read_concat, close_concat, rebind_concat); + return fz_new_stream(ctx, state, next_concat, close_concat, rebind_concat); } void @@ -185,6 +201,7 @@ struct fz_ahxd_s { fz_stream *chain; int eod; + unsigned char buffer[256]; }; static inline int iswhite(int a) @@ -213,23 +230,27 @@ static inline int unhex(int a) } static int -read_ahxd(fz_stream *stm, unsigned char *buf, int len) +next_ahxd(fz_stream *stm, int max) { fz_ahxd *state = stm->state; - unsigned char *p = buf; - unsigned char *ep = buf + len; + unsigned char *p = state->buffer; + unsigned char *ep; int a, b, c, odd; + if (max > sizeof(state->buffer)) + max = sizeof(state->buffer); + ep = p + max; + odd = 0; while (p < ep) { if (state->eod) - return p - buf; + break; c = fz_read_byte(state->chain); if (c < 0) - return p - buf; + break; if (ishex(c)) { @@ -250,14 +271,20 @@ read_ahxd(fz_stream *stm, unsigned char *buf, int len) if (odd) *p++ = (a << 4); state->eod = 1; + break; } else if (!iswhite(c)) { fz_throw(stm->ctx, FZ_ERROR_GENERIC, "bad data in ahxd: '%c'", c); } } + stm->rp = state->buffer; + stm->wp = p; + stm->pos += p - state->buffer; - return p - buf; + if (stm->rp != p) + return *stm->rp++; + return EOF; } static void @@ -294,7 +321,7 @@ fz_open_ahxd(fz_stream *chain) fz_rethrow(ctx); } - return fz_new_stream(ctx, state, read_ahxd, close_ahxd, rebind_ahxd); + return fz_new_stream(ctx, state, next_ahxd, close_ahxd, rebind_ahxd); } /* ASCII 85 Decode */ @@ -304,32 +331,32 @@ typedef struct fz_a85d_s fz_a85d; struct fz_a85d_s { fz_stream *chain; - unsigned char bp[4]; - unsigned char *rp, *wp; + unsigned char buffer[256]; int eod; }; static int -read_a85d(fz_stream *stm, unsigned char *buf, int len) +next_a85d(fz_stream *stm, int max) { fz_a85d *state = stm->state; - unsigned char *p = buf; - unsigned char *ep = buf + len; + unsigned char *p = state->buffer; + unsigned char *ep; int count = 0; int word = 0; int c; - while (state->rp < state->wp && p < ep) - *p++ = *state->rp++; + if (state->eod) + return EOF; + + if (max > sizeof(state->buffer)) + max = sizeof(state->buffer); + ep = p + max; while (p < ep) { - if (state->eod) - return p - buf; - c = fz_read_byte(state->chain); if (c < 0) - return p - buf; + break; if (c >= '!' && c <= 'u') { @@ -337,12 +364,10 @@ read_a85d(fz_stream *stm, unsigned char *buf, int len) { word = word * 85 + (c - '!'); - state->bp[0] = (word >> 24) & 0xff; - state->bp[1] = (word >> 16) & 0xff; - state->bp[2] = (word >> 8) & 0xff; - state->bp[3] = (word) & 0xff; - state->rp = state->bp; - state->wp = state->bp + 4; + *p++ = (word >> 24) & 0xff; + *p++ = (word >> 16) & 0xff; + *p++ = (word >> 8) & 0xff; + *p++ = (word) & 0xff; word = 0; count = 0; @@ -356,12 +381,10 @@ read_a85d(fz_stream *stm, unsigned char *buf, int len) else if (c == 'z' && count == 0) { - state->bp[0] = 0; - state->bp[1] = 0; - state->bp[2] = 0; - state->bp[3] = 0; - state->rp = state->bp; - state->wp = state->bp + 4; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; } else if (c == '~') @@ -381,39 +404,38 @@ read_a85d(fz_stream *stm, unsigned char *buf, int len) break; case 2: word = word * (85 * 85 * 85) + 0xffffff; - state->bp[0] = word >> 24; - state->rp = state->bp; - state->wp = state->bp + 1; + *p++ = word >> 24; break; case 3: word = word * (85 * 85) + 0xffff; - state->bp[0] = word >> 24; - state->bp[1] = word >> 16; - state->rp = state->bp; - state->wp = state->bp + 2; + *p++ = word >> 24; + *p++ = word >> 16; break; case 4: word = word * 85 + 0xff; - state->bp[0] = word >> 24; - state->bp[1] = word >> 16; - state->bp[2] = word >> 8; - state->rp = state->bp; - state->wp = state->bp + 3; + *p++ = word >> 24; + *p++ = word >> 16; + *p++ = word >> 8; break; } state->eod = 1; + break; } else if (!iswhite(c)) { fz_throw(stm->ctx, FZ_ERROR_GENERIC, "bad data in a85d: '%c'", c); } - - while (state->rp < state->wp && p < ep) - *p++ = *state->rp++; } - return p - buf; + stm->rp = state->buffer; + stm->wp = p; + stm->pos += p - state->buffer; + + if (p == stm->rp) + return EOF; + + return *stm->rp++; } static void @@ -443,8 +465,6 @@ fz_open_a85d(fz_stream *chain) { state = fz_malloc_struct(ctx, fz_a85d); state->chain = chain; - state->rp = state->bp; - state->wp = state->bp; state->eod = 0; } fz_catch(ctx) @@ -453,7 +473,7 @@ fz_open_a85d(fz_stream *chain) fz_rethrow(ctx); } - return fz_new_stream(ctx, state, read_a85d, close_a85d, rebind_a85d); + return fz_new_stream(ctx, state, next_a85d, close_a85d, rebind_a85d); } /* Run Length Decode */ @@ -464,25 +484,36 @@ struct fz_rld_s { fz_stream *chain; int run, n, c; + unsigned char buffer[256]; }; static int -read_rld(fz_stream *stm, unsigned char *buf, int len) +next_rld(fz_stream *stm, int max) { fz_rld *state = stm->state; - unsigned char *p = buf; - unsigned char *ep = buf + len; + unsigned char *p = state->buffer; + unsigned char *ep; + + if (state->run == 128) + return EOF; + + if (max > sizeof(state->buffer)) + max = sizeof(state->buffer); + ep = p + max; while (p < ep) { if (state->run == 128) - return p - buf; + break; if (state->n == 0) { state->run = fz_read_byte(state->chain); if (state->run < 0) + { state->run = 128; + break; + } if (state->run < 128) state->n = state->run + 1; if (state->run > 128) @@ -516,7 +547,14 @@ read_rld(fz_stream *stm, unsigned char *buf, int len) } } - return p - buf; + stm->rp = state->buffer; + stm->wp = p; + stm->pos += p - state->buffer; + + if (p == stm->rp) + return EOF; + + return *stm->rp++; } static void @@ -556,7 +594,7 @@ fz_open_rld(fz_stream *chain) fz_rethrow(ctx); } - return fz_new_stream(ctx, state, read_rld, close_rld, rebind_rld); + return fz_new_stream(ctx, state, next_rld, close_rld, rebind_rld); } /* RC4 Filter */ @@ -567,15 +605,27 @@ struct fz_arc4c_s { fz_stream *chain; fz_arc4 arc4; + unsigned char buffer[256]; }; static int -read_arc4(fz_stream *stm, unsigned char *buf, int len) +next_arc4(fz_stream *stm, int max) { fz_arc4c *state = stm->state; - int n = fz_read(state->chain, buf, len); - fz_arc4_encrypt(&state->arc4, buf, buf, n); - return n; + int n = fz_available(state->chain, max); + + if (n == 0) + return EOF; + if (n > sizeof(state->buffer)) + n = sizeof(state->buffer); + + stm->rp = state->buffer; + stm->wp = state->buffer + n; + fz_arc4_encrypt(&state->arc4, stm->rp, state->chain->rp, n); + state->chain->rp += n; + stm->pos += n; + + return *stm->rp++; } static void @@ -613,7 +663,7 @@ fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen) fz_rethrow(ctx); } - return fz_new_stream(ctx, state, read_arc4, close_arc4, rebind_arc4c); + return fz_new_stream(ctx, state, next_arc4, close_arc4, rebind_arc4c); } /* AES Filter */ @@ -628,14 +678,19 @@ struct fz_aesd_s int ivcount; unsigned char bp[16]; unsigned char *rp, *wp; + unsigned char buffer[256]; }; static int -read_aesd(fz_stream *stm, unsigned char *buf, int len) +next_aesd(fz_stream *stm, int max) { fz_aesd *state = stm->state; - unsigned char *p = buf; - unsigned char *ep = buf + len; + unsigned char *p = state->buffer; + unsigned char *ep; + + if (max > sizeof(state->buffer)) + max = sizeof(state->buffer); + ep = p + max; while (state->ivcount < 16) { @@ -652,7 +707,7 @@ read_aesd(fz_stream *stm, unsigned char *buf, int len) { int n = fz_read(state->chain, state->bp, 16); if (n == 0) - return p - buf; + break; else if (n < 16) fz_throw(stm->ctx, FZ_ERROR_GENERIC, "partial block in aes filter"); @@ -673,7 +728,14 @@ read_aesd(fz_stream *stm, unsigned char *buf, int len) *p++ = *state->rp++; } - return p - buf; + stm->rp = state->buffer; + stm->wp = p; + stm->pos += p - state->buffer; + + if (p == stm->rp) + return EOF; + + return *stm->rp++; } static void @@ -718,5 +780,5 @@ fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen) fz_rethrow(ctx); } - return fz_new_stream(ctx, state, read_aesd, close_aesd, rebind_aesd); + return fz_new_stream(ctx, state, next_aesd, close_aesd, rebind_aesd); } diff --git a/source/fitz/filter-dct.c b/source/fitz/filter-dct.c index 23665909..86268032 100644 --- a/source/fitz/filter-dct.c +++ b/source/fitz/filter-dct.c @@ -22,6 +22,8 @@ struct fz_dctd_s struct jpeg_error_mgr errmgr; jmp_buf jb; char msg[JMSG_LENGTH_MAX]; + + unsigned char buffer[4096]; }; static void error_exit(j_common_ptr cinfo) @@ -48,10 +50,11 @@ static boolean fill_input_buffer(j_decompress_ptr cinfo) fz_stream *curr_stm = state->curr_stm; fz_context *ctx = curr_stm->ctx; + curr_stm->rp = curr_stm->wp; fz_try(ctx) { - fz_fill_buffer(curr_stm); + src->bytes_in_buffer = fz_available(curr_stm, 1); } fz_catch(ctx) { @@ -59,7 +62,6 @@ static boolean fill_input_buffer(j_decompress_ptr cinfo) return 0; } src->next_input_byte = curr_stm->rp; - src->bytes_in_buffer = curr_stm->wp - curr_stm->rp; if (src->bytes_in_buffer == 0) { @@ -88,12 +90,16 @@ static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) } static int -read_dctd(fz_stream *stm, unsigned char *buf, int len) +next_dctd(fz_stream *stm, int max) { fz_dctd *state = stm->state; j_decompress_ptr cinfo = &state->cinfo; - unsigned char *p = buf; - unsigned char *ep = buf + len; + unsigned char *p = state->buffer; + unsigned char *ep; + + if (max > sizeof(state->buffer)) + max = sizeof(state->buffer); + ep = state->buffer + max; if (setjmp(state->jb)) { @@ -202,8 +208,13 @@ read_dctd(fz_stream *stm, unsigned char *buf, int len) while (state->rp < state->wp && p < ep) *p++ = *state->rp++; } + stm->rp = state->buffer; + stm->wp = p; + stm->pos += (p - state->buffer); + if (p == stm->rp) + return EOF; - return p - buf; + return *stm->rp++; } static void @@ -267,5 +278,5 @@ fz_open_dctd(fz_stream *chain, int color_transform, int l2factor, fz_stream *jpe fz_rethrow(ctx); } - return fz_new_stream(ctx, state, read_dctd, close_dctd, rebind_dctd); + return fz_new_stream(ctx, state, next_dctd, close_dctd, rebind_dctd); } diff --git a/source/fitz/filter-fax.c b/source/fitz/filter-fax.c index 7b35c812..70692338 100644 --- a/source/fitz/filter-fax.c +++ b/source/fitz/filter-fax.c @@ -344,6 +344,8 @@ struct fz_faxd_s unsigned char *ref; unsigned char *dst; unsigned char *rp, *wp; + + unsigned char buffer[4096]; }; static inline void eat_bits(fz_faxd *fax, int nbits) @@ -355,7 +357,10 @@ static inline void eat_bits(fz_faxd *fax, int nbits) static int fill_bits(fz_faxd *fax) { - while (fax->bidx >= 8) + /* The longest length of bits we'll ever need is 13. Never read more + * than we need to avoid unnecessary overreading of the end of the + * stream. */ + while (fax->bidx > (32-13)) { int c = fz_read_byte(fax->chain); if (c == EOF) @@ -551,14 +556,17 @@ dec2d(fz_context *ctx, fz_faxd *fax) } static int -read_faxd(fz_stream *stm, unsigned char *buf, int len) +next_faxd(fz_stream *stm, int max) { fz_context *ctx = stm->ctx; fz_faxd *fax = stm->state; - unsigned char *p = buf; - unsigned char *ep = buf + len; + unsigned char *p = fax->buffer; + unsigned char *ep; unsigned char *tmp; + if (max > sizeof(fax->buffer)) + max = sizeof(fax->buffer); + ep = p + max; if (fax->stage == STATE_INIT && fax->end_of_line) { fill_bits(fax); @@ -576,7 +584,7 @@ read_faxd(fz_stream *stm, unsigned char *buf, int len) fax->stage = STATE_NORMAL; if (fax->stage == STATE_DONE) - return 0; + return EOF; if (fax->stage == STATE_EOL) goto eol; @@ -679,7 +687,14 @@ eol: } if (fax->rp < fax->wp) - return p - buf; + { + stm->rp = fax->buffer; + stm->wp = p; + stm->pos += (p - fax->buffer); + if (p == fax->buffer) + return EOF; + return *stm->rp++; + } tmp = fax->ref; fax->ref = fax->dst; @@ -694,11 +709,8 @@ eol: fax->a = -1; fax->ridx ++; - if (!fax->end_of_block && fax->rows) - { - if (fax->ridx >= fax->rows) - goto rtc; - } + if (!fax->end_of_block && fax->rows && fax->ridx >= fax->rows) + goto rtc; /* we have not read dim from eol, make a guess */ if (fax->k > 0 && !fax->eolc && fax->a == -1) @@ -719,8 +731,15 @@ eol: } /* no more space in output, don't decode the next row yet */ - if (p == buf + len) - return p - buf; + if (p == fax->buffer + max) + { + stm->rp = fax->buffer; + stm->wp = p; + stm->pos += (p - fax->buffer); + if (p == fax->buffer) + return EOF; + return *stm->rp++; + } goto loop; @@ -740,7 +759,12 @@ error: rtc: fax->stage = STATE_DONE; - return p - buf; + stm->rp = fax->buffer; + stm->wp = p; + stm->pos += (p - fax->buffer); + if (p == fax->buffer) + return EOF; + return *stm->rp++; } static void @@ -828,5 +852,5 @@ fz_open_faxd(fz_stream *chain, fz_rethrow(ctx); } - return fz_new_stream(ctx, fax, read_faxd, close_faxd, rebind_faxd); + return fz_new_stream(ctx, fax, next_faxd, close_faxd, rebind_faxd); } diff --git a/source/fitz/filter-flate.c b/source/fitz/filter-flate.c index 022cdb12..b306c9c3 100644 --- a/source/fitz/filter-flate.c +++ b/source/fitz/filter-flate.c @@ -8,6 +8,7 @@ struct fz_flate_s { fz_stream *chain; z_stream z; + unsigned char buffer[4096]; }; static void *zalloc(void *opaque, unsigned int items, unsigned int size) @@ -21,23 +22,27 @@ static void zfree(void *opaque, void *ptr) } static int -read_flated(fz_stream *stm, unsigned char *outbuf, int outlen) +next_flated(fz_stream *stm, int outlen) { fz_flate *state = stm->state; fz_stream *chain = state->chain; z_streamp zp = &state->z; int code; + unsigned char *outbuf = state->buffer; + + if (outlen > sizeof(state->buffer)) + outlen = sizeof(state->buffer); + + if (stm->eof) + return EOF; zp->next_out = outbuf; zp->avail_out = outlen; while (zp->avail_out > 0) { - if (chain->rp == chain->wp) - fz_fill_buffer(chain); - + zp->avail_in = fz_available(chain, 1); zp->next_in = chain->rp; - zp->avail_in = chain->wp - chain->rp; code = inflate(zp, Z_SYNC_FLUSH); @@ -45,23 +50,23 @@ read_flated(fz_stream *stm, unsigned char *outbuf, int outlen) if (code == Z_STREAM_END) { - return outlen - zp->avail_out; + break; } else if (code == Z_BUF_ERROR) { fz_warn(stm->ctx, "premature end of data in flate filter"); - return outlen - zp->avail_out; + break; } else if (code == Z_DATA_ERROR && zp->avail_in == 0) { fz_warn(stm->ctx, "ignoring zlib error: %s", zp->msg); - return outlen - zp->avail_out; + break; } else if (code == Z_DATA_ERROR && !strcmp(zp->msg, "incorrect data check")) { fz_warn(stm->ctx, "ignoring zlib error: %s", zp->msg); chain->rp = chain->wp; - return outlen - zp->avail_out; + break; } else if (code != Z_OK) { @@ -69,7 +74,15 @@ read_flated(fz_stream *stm, unsigned char *outbuf, int outlen) } } - return outlen - zp->avail_out; + stm->rp = state->buffer; + stm->wp = state->buffer + outlen - zp->avail_out; + stm->pos += outlen - zp->avail_out; + if (stm->rp == stm->wp) + { + stm->eof = 1; + return EOF; + } + return *stm->rp++; } static void @@ -126,5 +139,5 @@ fz_open_flated(fz_stream *chain) fz_close(chain); fz_rethrow(ctx); } - return fz_new_stream(ctx, state, read_flated, close_flated, rebind_flated); + return fz_new_stream(ctx, state, next_flated, close_flated, rebind_flated); } diff --git a/source/fitz/filter-jbig2.c b/source/fitz/filter-jbig2.c index 592f7ab6..98919dcb 100644 --- a/source/fitz/filter-jbig2.c +++ b/source/fitz/filter-jbig2.c @@ -17,6 +17,7 @@ struct fz_jbig2d_s fz_jbig2_globals *gctx; Jbig2Image *page; int idx; + unsigned char buffer[4096]; }; static void @@ -39,15 +40,20 @@ close_jbig2d(fz_context *ctx, void *state_) } static int -read_jbig2d(fz_stream *stm, unsigned char *buf, int len) +next_jbig2d(fz_stream *stm, int len) { fz_jbig2d *state = stm->state; unsigned char tmp[4096]; + unsigned char *buf = state->buffer; unsigned char *p = buf; - unsigned char *ep = buf + len; + unsigned char *ep; unsigned char *s; int x, w, n; + if (len > sizeof(state->buffer)) + len = sizeof(state->buffer); + ep = buf + len; + if (!state->page) { while (1) @@ -72,7 +78,12 @@ read_jbig2d(fz_stream *stm, unsigned char *buf, int len) *p++ = s[x++] ^ 0xff; state->idx = x; - return p - buf; + stm->rp = buf; + stm->wp = p; + if (p == buf) + return EOF; + stm->pos += p - buf; + return *stm->rp++; } static fz_stream * @@ -146,5 +157,5 @@ fz_open_jbig2d(fz_stream *chain, fz_jbig2_globals *globals) fz_rethrow(ctx); } - return fz_new_stream(ctx, state, read_jbig2d, close_jbig2d, rebind_jbig2d); + return fz_new_stream(ctx, state, next_jbig2d, close_jbig2d, rebind_jbig2d); } diff --git a/source/fitz/filter-lzw.c b/source/fitz/filter-lzw.c index c78c8c3f..e13b0ef0 100644 --- a/source/fitz/filter-lzw.c +++ b/source/fitz/filter-lzw.c @@ -41,15 +41,18 @@ struct fz_lzwd_s unsigned char bp[MAX_LENGTH]; unsigned char *rp, *wp; + + unsigned char buffer[4096]; }; static int -read_lzwd(fz_stream *stm, unsigned char *buf, int len) +next_lzwd(fz_stream *stm, int len) { fz_lzwd *lzw = stm->state; lzw_code *table = lzw->table; + unsigned char *buf = lzw->buffer; unsigned char *p = buf; - unsigned char *ep = buf + len; + unsigned char *ep; unsigned char *s; int codelen; @@ -58,13 +61,17 @@ read_lzwd(fz_stream *stm, unsigned char *buf, int len) int old_code = lzw->old_code; int next_code = lzw->next_code; + if (len > sizeof(lzw->buffer)) + len = sizeof(lzw->buffer); + ep = buf + len; + while (lzw->rp < lzw->wp && p < ep) *p++ = *lzw->rp++; while (p < ep) { if (lzw->eod) - return 0; + return EOF; code = fz_read_bits(lzw->chain, code_bits); @@ -162,7 +169,13 @@ read_lzwd(fz_stream *stm, unsigned char *buf, int len) lzw->old_code = old_code; lzw->next_code = next_code; - return p - buf; + stm->rp = buf; + stm->wp = p; + if (buf == p) + return EOF; + stm->pos += p - buf; + + return *stm->rp++; } static void @@ -228,5 +241,5 @@ fz_open_lzwd(fz_stream *chain, int early_change) fz_rethrow(ctx); } - return fz_new_stream(ctx, lzw, read_lzwd, close_lzwd, rebind_lzwd); + return fz_new_stream(ctx, lzw, next_lzwd, close_lzwd, rebind_lzwd); } diff --git a/source/fitz/filter-predict.c b/source/fitz/filter-predict.c index 66101753..6862f8c9 100644 --- a/source/fitz/filter-predict.c +++ b/source/fitz/filter-predict.c @@ -19,6 +19,8 @@ struct fz_predict_s unsigned char *out; unsigned char *ref; unsigned char *rp, *wp; + + unsigned char buffer[4096]; }; static inline int getcomponent(unsigned char *line, int x, int bpc) @@ -143,14 +145,19 @@ fz_predict_png(fz_predict *state, unsigned char *out, unsigned char *in, int len } static int -read_predict(fz_stream *stm, unsigned char *buf, int len) +next_predict(fz_stream *stm, int len) { fz_predict *state = stm->state; + unsigned char *buf = state->buffer; unsigned char *p = buf; - unsigned char *ep = buf + len; + unsigned char *ep; int ispng = state->predictor >= 10; int n; + if (len >= sizeof(state->buffer)) + len = sizeof(state->buffer); + ep = buf + len; + while (state->rp < state->wp && p < ep) *p++ = *state->rp++; @@ -158,7 +165,7 @@ read_predict(fz_stream *stm, unsigned char *buf, int len) { n = fz_read(state->chain, state->in, state->stride + ispng); if (n == 0) - return p - buf; + break; if (state->predictor == 1) memcpy(state->out, state->in, n); @@ -177,7 +184,13 @@ read_predict(fz_stream *stm, unsigned char *buf, int len) *p++ = *state->rp++; } - return p - buf; + stm->rp = buf; + stm->wp = p; + if (stm->rp == stm->wp) + return EOF; + stm->pos += p - buf; + + return *stm->rp++; } static void @@ -267,5 +280,5 @@ fz_open_predict(fz_stream *chain, int predictor, int columns, int colors, int bp fz_rethrow(ctx); } - return fz_new_stream(ctx, state, read_predict, close_predict, rebind_predict); + return fz_new_stream(ctx, state, next_predict, close_predict, rebind_predict); } diff --git a/source/fitz/stream-open.c b/source/fitz/stream-open.c index f336a4e4..3e51e733 100644 --- a/source/fitz/stream-open.c +++ b/source/fitz/stream-open.c @@ -12,7 +12,7 @@ void fz_rebind_stream(fz_stream *stm, fz_context *ctx) fz_stream * fz_new_stream(fz_context *ctx, void *state, - fz_stream_read_fn *read, + fz_stream_next_fn *next, fz_stream_close_fn *close, fz_stream_rebind_fn *rebind) { @@ -36,13 +36,11 @@ fz_new_stream(fz_context *ctx, void *state, stm->bits = 0; stm->avail = 0; - stm->bp = stm->buf; - stm->rp = stm->bp; - stm->wp = stm->bp; - stm->ep = stm->buf + sizeof stm->buf; + stm->rp = NULL; + stm->wp = NULL; stm->state = state; - stm->read = read; + stm->next = next; stm->close = close; stm->seek = NULL; stm->rebind = rebind; @@ -75,27 +73,44 @@ fz_close(fz_stream *stm) /* File stream */ -static int read_file(fz_stream *stm, unsigned char *buf, int len) +typedef struct fz_file_stream_s { - int n = read(*(int*)stm->state, buf, len); + int file; + unsigned char buffer[4096]; +} fz_file_stream; + +static int next_file(fz_stream *stm, int n) +{ + fz_file_stream *state = stm->state; + + /* n is only a hint, that we can safely ignore */ + n = read(state->file, state->buffer, sizeof(state->buffer)); if (n < 0) fz_throw(stm->ctx, FZ_ERROR_GENERIC, "read error: %s", strerror(errno)); - return n; + stm->rp = state->buffer; + stm->wp = state->buffer + n; + stm->pos += n; + + if (n == 0) + return EOF; + return *stm->rp++; } static void seek_file(fz_stream *stm, int offset, int whence) { - int n = lseek(*(int*)stm->state, offset, whence); + fz_file_stream *state = stm->state; + int n = lseek(state->file, offset, whence); if (n < 0) fz_throw(stm->ctx, FZ_ERROR_GENERIC, "cannot lseek: %s", strerror(errno)); stm->pos = n; - stm->rp = stm->bp; - stm->wp = stm->bp; + stm->rp = state->buffer; + stm->wp = state->buffer; } -static void close_file(fz_context *ctx, void *state) +static void close_file(fz_context *ctx, void *state_) { - int n = close(*(int*)state); + fz_file_stream *state = state_; + int n = close(state->file); if (n < 0) fz_warn(ctx, "close error: %s", strerror(errno)); fz_free(ctx, state); @@ -105,14 +120,12 @@ fz_stream * fz_open_fd(fz_context *ctx, int fd) { fz_stream *stm; - int *state; - - state = fz_malloc_struct(ctx, int); - *state = fd; + fz_file_stream *state = fz_malloc_struct(ctx, fz_file_stream); + state->file = fd; fz_try(ctx) { - stm = fz_new_stream(ctx, state, read_file, close_file, NULL); + stm = fz_new_stream(ctx, state, next_file, close_file, NULL); } fz_catch(ctx) { @@ -160,21 +173,29 @@ fz_open_file_w(fz_context *ctx, const wchar_t *name) /* Memory stream */ -static int read_buffer(fz_stream *stm, unsigned char *buf, int len) +static int next_buffer(fz_stream *stm, int max) { - return 0; + return EOF; } static void seek_buffer(fz_stream *stm, int offset, int whence) { - if (whence == 0) - stm->rp = stm->bp + offset; + int pos = stm->pos - (stm->wp - stm->rp); + /* Convert to absolute pos */ if (whence == 1) - stm->rp += offset; - if (whence == 2) - stm->rp = stm->ep - offset; - stm->rp = fz_clampp(stm->rp, stm->bp, stm->ep); - stm->wp = stm->ep; + { + offset += pos; /* Was relative to current pos */ + } + else if (whence == 2) + { + offset += stm->pos; /* Was relative to end */ + } + + if (offset < 0) + offset = 0; + if (offset > stm->pos) + offset = stm->pos; + stm->rp += offset - pos; } static void close_buffer(fz_context *ctx, void *state_) @@ -190,13 +211,11 @@ fz_open_buffer(fz_context *ctx, fz_buffer *buf) fz_stream *stm; fz_keep_buffer(ctx, buf); - stm = fz_new_stream(ctx, buf, read_buffer, close_buffer, NULL); + stm = fz_new_stream(ctx, buf, next_buffer, close_buffer, NULL); stm->seek = seek_buffer; - stm->bp = buf->data; stm->rp = buf->data; stm->wp = buf->data + buf->len; - stm->ep = buf->data + buf->len; stm->pos = buf->len; @@ -208,13 +227,11 @@ fz_open_memory(fz_context *ctx, unsigned char *data, int len) { fz_stream *stm; - stm = fz_new_stream(ctx, NULL, read_buffer, close_buffer, NULL); + stm = fz_new_stream(ctx, NULL, next_buffer, close_buffer, NULL); stm->seek = seek_buffer; - stm->bp = data; stm->rp = data; stm->wp = data + len; - stm->ep = data + len; stm->pos = len; diff --git a/source/fitz/stream-prog.c b/source/fitz/stream-prog.c index 5ec23823..01f3e5ef 100644 --- a/source/fitz/stream-prog.c +++ b/source/fitz/stream-prog.c @@ -24,12 +24,17 @@ typedef struct prog_state int available; int bps; clock_t start_time; + unsigned char buffer[4096]; } prog_state; -static int read_prog(fz_stream *stm, unsigned char *buf, int len) +static int next_prog(fz_stream *stm, int len) { prog_state *ps = (prog_state *)stm->state; int n; + unsigned char *buf = ps->buffer; + + if (len > sizeof(ps->buffer)) + len = sizeof(ps->buffer); /* Simulate more data having arrived */ if (ps->available < ps->length) @@ -53,7 +58,12 @@ static int read_prog(fz_stream *stm, unsigned char *buf, int len) n = (len > 0 ? read(ps->fd, buf, len) : 0); if (n < 0) fz_throw(stm->ctx, FZ_ERROR_GENERIC, "read error: %s", strerror(errno)); - return n; + stm->rp = ps->buffer + stm->pos; + stm->wp = ps->buffer + stm->pos + n; + stm->pos += n; + if (n == 0) + return EOF; + return *stm->rp++; } static void seek_prog(fz_stream *stm, int offset, int whence) @@ -100,8 +110,7 @@ static void seek_prog(fz_stream *stm, int offset, int whence) if (n < 0) fz_throw(stm->ctx, FZ_ERROR_GENERIC, "cannot lseek: %s", strerror(errno)); stm->pos = n; - stm->rp = stm->bp; - stm->wp = stm->bp; + stm->wp = stm->rp; } static void close_prog(fz_context *ctx, void *state) @@ -144,7 +153,7 @@ fz_open_fd_progressive(fz_context *ctx, int fd, int bps) fz_try(ctx) { - stm = fz_new_stream(ctx, state, read_prog, close_prog, NULL); + stm = fz_new_stream(ctx, state, next_prog, close_prog, NULL); } fz_catch(ctx) { diff --git a/source/fitz/stream-read.c b/source/fitz/stream-read.c index 71ae7666..02f186a0 100644 --- a/source/fitz/stream-read.c +++ b/source/fitz/stream-read.c @@ -7,89 +7,26 @@ fz_read(fz_stream *stm, unsigned char *buf, int len) { int count, n; - count = fz_mini(len, stm->wp - stm->rp); - if (count) + count = 0; + do { - memcpy(buf, stm->rp, count); - stm->rp += count; - } - - if (count == len || stm->error || stm->eof) - return count; - - assert(stm->rp == stm->wp); - - if (len - count < stm->ep - stm->bp) - { - n = stm->read(stm, stm->bp, stm->ep - stm->bp); + n = fz_available(stm, len); + if (n > len) + n = len; if (n == 0) - { - stm->eof = 1; - } - else if (n > 0) - { - stm->rp = stm->bp; - stm->wp = stm->bp + n; - stm->pos += n; - } + break; - n = fz_mini(len - count, stm->wp - stm->rp); - if (n) - { - memcpy(buf + count, stm->rp, n); - stm->rp += n; - count += n; - } - } - else - { - n = stm->read(stm, buf + count, len - count); - if (n == 0) - { - stm->eof = 1; - } - else if (n > 0) - { - stm->pos += n; - count += n; - } + memcpy(buf, stm->rp, n); + stm->rp += n; + buf += n; + count += n; + len -= n; } + while (len > 0); return count; } -void -fz_fill_buffer(fz_stream *stm) -{ - int n; - - assert(stm->rp == stm->wp); - - if (stm->error || stm->eof) - return; - - fz_try(stm->ctx) - { - n = stm->read(stm, stm->bp, stm->ep - stm->bp); - if (n == 0) - { - stm->eof = 1; - } - else if (n > 0) - { - stm->rp = stm->bp; - stm->wp = stm->bp + n; - stm->pos += n; - } - } - fz_catch(stm->ctx) - { - fz_rethrow_if(stm->ctx, FZ_ERROR_TRYLATER); - fz_warn(stm->ctx, "read error; treating as end of file"); - stm->error = 1; - } -} - fz_buffer * fz_read_all(fz_stream *stm, int initial) { @@ -196,16 +133,6 @@ fz_seek(fz_stream *stm, int offset, int whence) offset = fz_tell(stm) + offset; whence = 0; } - if (whence == 0) - { - int dist = stm->pos - offset; - if (dist >= 0 && dist <= stm->wp - stm->bp) - { - stm->rp = stm->wp - dist; - stm->eof = 0; - return; - } - } stm->seek(stm, offset, whence); stm->eof = 0; } diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c index f6eda706..0f74667a 100644 --- a/source/pdf/pdf-op-run.c +++ b/source/pdf/pdf-op-run.c @@ -1741,6 +1741,7 @@ static void pdf_run_BI(pdf_csi *csi, void *state) int ch; fz_image *img; pdf_obj *obj; + int found; obj = pdf_parse_dict(csi->doc, file, &csi->doc->lexbuf.base); @@ -1768,11 +1769,27 @@ static void pdf_run_BI(pdf_csi *csi, void *state) fz_drop_image(ctx, img); /* find EI */ + found = 0; ch = fz_read_byte(file); - while (ch != 'E' && ch != EOF) - ch = fz_read_byte(file); - ch = fz_read_byte(file); - if (ch != 'I') + do + { + while (ch != 'E' && ch != EOF) + ch = fz_read_byte(file); + if (ch == 'E') + { + ch = fz_read_byte(file); + if (ch == 'I') + { + ch = fz_peek_byte(file); + if (ch == ' ' || ch <= 32 || ch == EOF || ch == '<' || ch == '/') + { + found = 1; + break; + } + } + } + } while (ch != EOF); + if (!found) fz_throw(ctx, FZ_ERROR_GENERIC, "syntax error after inline image"); } |