diff options
author | Sebastian Rasmussen <sebras@gmail.com> | 2018-04-06 00:41:01 +0800 |
---|---|---|
committer | Sebastian Rasmussen <sebras@gmail.com> | 2018-04-11 11:45:12 +0800 |
commit | 2b2dcf4ccf401ed210f03c858b304994749fd2b3 (patch) | |
tree | ee354a8558b2d294ec8013ca55cf8ff785481cb1 | |
parent | 7ede8fc2b5e8498619d1e32b6b7fbbf9f926a055 (diff) | |
download | ghostpdl-2b2dcf4ccf401ed210f03c858b304994749fd2b3.tar.gz |
jbig2dec: Improve error handling.
Some functions detected errors but would not return these
to the caller. These functions may now indicate errors:
jbig2_arith_decode(), jbig2_image_resize()
Errors detected by following functions were not always
handled, but they are now handled properly:
jbig2_arith_decode(), jbig2_arith_iaid_decode()
jbig2_arith_int_ctx_new(), jbig2_build_huffman_table()
jbig2_complete_page(), jbig2_image_compose()
jbig2_decode_refinement_region(), jbig2_ctx_new()
jbig2_image_resize(), jbig2_image_write_pbm()
jbig2_image_write_pbm_file(), jbig2_image_write_png()
jbig2_image_write_png_file(), jbig2_metadata_add()
jbig2_page_add_result(), jbig2_renew()
jbig2_strndup()
Some functions detected errors but did not fail early enough:
jbig2_decode_pattern_dict(), jbig2_decode_halftone_region()
jbig2_decode_mmr_line() detected errors but did not produce
suitable error messages. This has been rectified.
Finally, if a subfunction indicates an error by returning an
error code, the calling function will report a warning and
return, indicating failure.
-rw-r--r-- | jbig2dec/jbig2.c | 12 | ||||
-rw-r--r-- | jbig2dec/jbig2_arith.c | 8 | ||||
-rw-r--r-- | jbig2dec/jbig2_arith.h | 2 | ||||
-rw-r--r-- | jbig2dec/jbig2_arith_iaid.c | 11 | ||||
-rw-r--r-- | jbig2dec/jbig2_arith_iaid.h | 2 | ||||
-rw-r--r-- | jbig2dec/jbig2_arith_int.c | 33 | ||||
-rw-r--r-- | jbig2dec/jbig2_arith_int.h | 2 | ||||
-rw-r--r-- | jbig2dec/jbig2_generic.c | 75 | ||||
-rw-r--r-- | jbig2dec/jbig2_halftone.c | 33 | ||||
-rw-r--r-- | jbig2dec/jbig2_image.c | 2 | ||||
-rw-r--r-- | jbig2dec/jbig2_image_pbm.c | 6 | ||||
-rw-r--r-- | jbig2dec/jbig2_image_png.c | 6 | ||||
-rw-r--r-- | jbig2dec/jbig2_metadata.c | 12 | ||||
-rw-r--r-- | jbig2dec/jbig2_mmr.c | 32 | ||||
-rw-r--r-- | jbig2dec/jbig2_page.c | 37 | ||||
-rw-r--r-- | jbig2dec/jbig2_refinement.c | 59 | ||||
-rw-r--r-- | jbig2dec/jbig2_segment.c | 2 | ||||
-rw-r--r-- | jbig2dec/jbig2_symbol_dict.c | 52 | ||||
-rw-r--r-- | jbig2dec/jbig2_text.c | 52 | ||||
-rw-r--r-- | jbig2dec/jbig2dec.c | 41 | ||||
-rw-r--r-- | jbig2dec/pbm2png.c | 10 |
21 files changed, 355 insertions, 134 deletions
diff --git a/jbig2dec/jbig2.c b/jbig2dec/jbig2.c index d0533fdc6..cdc83b8e9 100644 --- a/jbig2dec/jbig2.c +++ b/jbig2dec/jbig2.c @@ -294,7 +294,17 @@ jbig2_data_in(Jbig2Ctx *ctx, const unsigned char *data, size_t size) ctx->buf_rd_ix += header_size; if (ctx->n_segments == ctx->n_segments_max) - ctx->segments = jbig2_renew(ctx, ctx->segments, Jbig2Segment *, (ctx->n_segments_max <<= 2)); + { + Jbig2Segment **segments; + segments = jbig2_renew(ctx, ctx->segments, Jbig2Segment *, (ctx->n_segments_max <<= 2)); + if (segments == NULL) + { + ctx->state = JBIG2_FILE_EOF; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "could not reallocate space for more segments"); + } + ctx->segments = segments; + } + ctx->segments[ctx->n_segments++] = segment; if (ctx->state == JBIG2_FILE_RANDOM_HEADERS) { diff --git a/jbig2dec/jbig2_arith.c b/jbig2dec/jbig2_arith.c index 7567ba1e8..52cc3dbbd 100644 --- a/jbig2dec/jbig2_arith.c +++ b/jbig2dec/jbig2_arith.c @@ -263,7 +263,7 @@ jbig2_arith_renormd(Jbig2ArithState *as) } bool -jbig2_arith_decode(Jbig2ArithState *as, Jbig2ArithCx *pcx) +jbig2_arith_decode(Jbig2ArithState *as, Jbig2ArithCx *pcx, int *code) { Jbig2ArithCx cx = *pcx; const Jbig2ArithQe *pqe; @@ -271,7 +271,8 @@ jbig2_arith_decode(Jbig2ArithState *as, Jbig2ArithCx *pcx) bool D; if (index >= MAX_QE_ARRAY_SIZE) { - return -1; + *code = -1; + return 0; } else { pqe = &jbig2_arith_Qe[index]; } @@ -354,6 +355,7 @@ main(int argc, char **argv) Jbig2ArithState *as; int i; Jbig2ArithCx cx = 0; + int code; ctx = jbig2_ctx_new(NULL, 0, NULL, NULL, NULL); @@ -369,7 +371,7 @@ main(int argc, char **argv) #else (void) #endif - jbig2_arith_decode(as, &cx); + jbig2_arith_decode(as, &cx, &code); #ifdef JBIG2_DEBUG_ARITH fprintf(stderr, "%3d: D = %d, ", i, D); diff --git a/jbig2dec/jbig2_arith.h b/jbig2dec/jbig2_arith.h index 990205c2d..96b7ff387 100644 --- a/jbig2dec/jbig2_arith.h +++ b/jbig2dec/jbig2_arith.h @@ -28,7 +28,7 @@ typedef unsigned char Jbig2ArithCx; Jbig2ArithState *jbig2_arith_new(Jbig2Ctx *ctx, Jbig2WordStream *ws); /* decode a bit */ -bool jbig2_arith_decode(Jbig2ArithState *as, Jbig2ArithCx *pcx); +bool jbig2_arith_decode(Jbig2ArithState *as, Jbig2ArithCx *pcx, int *code); /* returns true if the end of the data stream has been reached (for sanity checks) */ bool jbig2_arith_has_reached_marker(Jbig2ArithState *as); diff --git a/jbig2dec/jbig2_arith_iaid.c b/jbig2dec/jbig2_arith_iaid.c index d79f957d0..3a79c1a7c 100644 --- a/jbig2dec/jbig2_arith_iaid.c +++ b/jbig2dec/jbig2_arith_iaid.c @@ -66,17 +66,20 @@ jbig2_arith_iaid_ctx_new(Jbig2Ctx *ctx, int SBSYMCODELEN) /* A.3 */ /* Return value: -1 on error, 0 on normal value */ int -jbig2_arith_iaid_decode(Jbig2ArithIaidCtx *ctx, Jbig2ArithState *as, int32_t *p_result) +jbig2_arith_iaid_decode(Jbig2Ctx *ctx, Jbig2ArithIaidCtx *actx, Jbig2ArithState *as, int32_t *p_result) { - Jbig2ArithCx *IAIDx = ctx->IAIDx; - int SBSYMCODELEN = ctx->SBSYMCODELEN; + Jbig2ArithCx *IAIDx = actx->IAIDx; + int SBSYMCODELEN = actx->SBSYMCODELEN; int PREV = 1; int D; int i; + int code = 0; /* A.3 (2) */ for (i = 0; i < SBSYMCODELEN; i++) { - D = jbig2_arith_decode(as, &IAIDx[PREV]); + D = jbig2_arith_decode(as, &IAIDx[PREV], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode IAIDx code"); #ifdef VERBOSE fprintf(stderr, "IAID%x: D = %d\n", PREV, D); #endif diff --git a/jbig2dec/jbig2_arith_iaid.h b/jbig2dec/jbig2_arith_iaid.h index a4a17603f..ac2f87724 100644 --- a/jbig2dec/jbig2_arith_iaid.h +++ b/jbig2dec/jbig2_arith_iaid.h @@ -21,6 +21,6 @@ typedef struct _Jbig2ArithIaidCtx Jbig2ArithIaidCtx; Jbig2ArithIaidCtx *jbig2_arith_iaid_ctx_new(Jbig2Ctx *ctx, int SBSYMCODELEN); -int jbig2_arith_iaid_decode(Jbig2ArithIaidCtx *ctx, Jbig2ArithState *as, int32_t *p_result); +int jbig2_arith_iaid_decode(Jbig2Ctx *ctx, Jbig2ArithIaidCtx *actx, Jbig2ArithState *as, int32_t *p_result); void jbig2_arith_iaid_ctx_free(Jbig2Ctx *ctx, Jbig2ArithIaidCtx *iax); diff --git a/jbig2dec/jbig2_arith_int.c b/jbig2dec/jbig2_arith_int.c index d7f68b137..f99132436 100644 --- a/jbig2dec/jbig2_arith_int.c +++ b/jbig2dec/jbig2_arith_int.c @@ -53,34 +53,47 @@ jbig2_arith_int_ctx_new(Jbig2Ctx *ctx) /* A.2 */ /* Return value: -1 on error, 0 on normal value, 1 on OOB return. */ int -jbig2_arith_int_decode(Jbig2ArithIntCtx *ctx, Jbig2ArithState *as, int32_t *p_result) +jbig2_arith_int_decode(Jbig2Ctx *ctx, Jbig2ArithIntCtx *actx, Jbig2ArithState *as, int32_t *p_result) { - Jbig2ArithCx *IAx = ctx->IAx; + Jbig2ArithCx *IAx = actx->IAx; int PREV = 1; int S, V; int bit; int n_tail, offset; int i; + int code = 0; - S = jbig2_arith_decode(as, &IAx[PREV]); + S = jbig2_arith_decode(as, &IAx[PREV], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode IAx S"); PREV = (PREV << 1) | S; - bit = jbig2_arith_decode(as, &IAx[PREV]); + bit = jbig2_arith_decode(as, &IAx[PREV], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode IAx bit 0"); PREV = (PREV << 1) | bit; if (bit) { - bit = jbig2_arith_decode(as, &IAx[PREV]); + bit = jbig2_arith_decode(as, &IAx[PREV], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode IAx bit 1"); PREV = (PREV << 1) | bit; if (bit) { - bit = jbig2_arith_decode(as, &IAx[PREV]); + bit = jbig2_arith_decode(as, &IAx[PREV], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode IAx bit 2"); PREV = (PREV << 1) | bit; if (bit) { - bit = jbig2_arith_decode(as, &IAx[PREV]); + bit = jbig2_arith_decode(as, &IAx[PREV], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode IAx bit 3"); PREV = (PREV << 1) | bit; if (bit) { - bit = jbig2_arith_decode(as, &IAx[PREV]); + bit = jbig2_arith_decode(as, &IAx[PREV], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode IAx bit 4"); PREV = (PREV << 1) | bit; if (bit) { @@ -109,7 +122,9 @@ jbig2_arith_int_decode(Jbig2ArithIntCtx *ctx, Jbig2ArithState *as, int32_t *p_re V = 0; for (i = 0; i < n_tail; i++) { - bit = jbig2_arith_decode(as, &IAx[PREV]); + bit = jbig2_arith_decode(as, &IAx[PREV], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode IAx code 7"); PREV = ((PREV << 1) & 511) | (PREV & 256) | bit; V = (V << 1) | bit; } diff --git a/jbig2dec/jbig2_arith_int.h b/jbig2dec/jbig2_arith_int.h index 4a77e9fbb..e58086bcc 100644 --- a/jbig2dec/jbig2_arith_int.h +++ b/jbig2dec/jbig2_arith_int.h @@ -21,6 +21,6 @@ typedef struct _Jbig2ArithIntCtx Jbig2ArithIntCtx; Jbig2ArithIntCtx *jbig2_arith_int_ctx_new(Jbig2Ctx *ctx); -int jbig2_arith_int_decode(Jbig2ArithIntCtx *ctx, Jbig2ArithState *as, int32_t *p_result); +int jbig2_arith_int_decode(Jbig2Ctx *ctx, Jbig2ArithIntCtx *actx, Jbig2ArithState *as, int32_t *p_result); void jbig2_arith_int_ctx_free(Jbig2Ctx *ctx, Jbig2ArithIntCtx *iax); diff --git a/jbig2dec/jbig2_generic.c b/jbig2dec/jbig2_generic.c index 046b5c4ec..714dc5658 100644 --- a/jbig2dec/jbig2_generic.c +++ b/jbig2dec/jbig2_generic.c @@ -76,6 +76,7 @@ jbig2_decode_generic_template0(Jbig2Ctx *ctx, uint32_t line_m1; uint32_t line_m2; int padded_width = (GBW + 7) & -8; + int code = 0; line_m1 = (y >= 1) ? gbreg_line[-rowstride] : 0; line_m2 = (y >= 2) ? gbreg_line[-(rowstride << 1)] << 6 : 0; @@ -97,7 +98,9 @@ jbig2_decode_generic_template0(Jbig2Ctx *ctx, for (x_minor = 0; x_minor < minor_width; x_minor++) { bool bit; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template0"); result |= bit << (7 - x_minor); CONTEXT = ((CONTEXT & 0x7bf7) << 1) | bit | ((line_m1 >> (7 - x_minor)) & 0x10) | ((line_m2 >> (7 - x_minor)) & 0x800); } @@ -125,6 +128,7 @@ jbig2_decode_generic_template0_unopt(Jbig2Ctx *ctx, uint32_t CONTEXT; int x, y; bool bit; + int code = 0; if (pixel_outside_field(params->gbat[0], params->gbat[1]) || pixel_outside_field(params->gbat[2], params->gbat[3]) || @@ -154,7 +158,9 @@ jbig2_decode_generic_template0_unopt(Jbig2Ctx *ctx, CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 2) << 13; CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 14; CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[6], y + params->gbat[7]) << 15; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template0"); jbig2_image_set_pixel(image, x, y, bit); } } @@ -171,6 +177,7 @@ jbig2_decode_generic_template1(Jbig2Ctx *ctx, const int rowstride = image->stride; int x, y; byte *gbreg_line = (byte *) image->data; + int code = 0; /* todo: currently we only handle the nominal gbat location */ /* when resolved make sure to call jbig2_check_adaptive_pixel_in_field() */ @@ -208,7 +215,9 @@ jbig2_decode_generic_template1(Jbig2Ctx *ctx, for (x_minor = 0; x_minor < minor_width; x_minor++) { bool bit; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template1"); result |= bit << (7 - x_minor); CONTEXT = ((CONTEXT & 0xefb) << 1) | bit | ((line_m1 >> (8 - x_minor)) & 0x8) | ((line_m2 >> (8 - x_minor)) & 0x200); } @@ -233,6 +242,7 @@ jbig2_decode_generic_template2(Jbig2Ctx *ctx, const int rowstride = image->stride; int x, y; byte *gbreg_line = (byte *) image->data; + int code = 0; /* todo: currently we only handle the nominal gbat location */ /* when resolved make sure to call jbig2_check_adaptive_pixel_in_field() */ @@ -270,7 +280,9 @@ jbig2_decode_generic_template2(Jbig2Ctx *ctx, for (x_minor = 0; x_minor < minor_width; x_minor++) { bool bit; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template2"); result |= bit << (7 - x_minor); CONTEXT = ((CONTEXT & 0x1bd) << 1) | bit | ((line_m1 >> (10 - x_minor)) & 0x4) | ((line_m2 >> (10 - x_minor)) & 0x80); } @@ -295,6 +307,7 @@ jbig2_decode_generic_template2a(Jbig2Ctx *ctx, const int rowstride = image->stride; int x, y; byte *gbreg_line = (byte *) image->data; + int code = 0; /* This is a special case for GBATX1 = 3, GBATY1 = -1 */ @@ -331,7 +344,9 @@ jbig2_decode_generic_template2a(Jbig2Ctx *ctx, for (x_minor = 0; x_minor < minor_width; x_minor++) { bool bit; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template2a"); result |= bit << (7 - x_minor); CONTEXT = ((CONTEXT & 0x1b9) << 1) | bit | ((line_m1 >> (10 - x_minor)) & 0x8) | ((line_m1 >> (9 - x_minor)) & 0x4) | ((line_m2 >> (10 - x_minor)) & 0x80); @@ -389,7 +404,9 @@ jbig2_decode_generic_template3(Jbig2Ctx *ctx, for (x_minor = 0; x_minor < minor_width; x_minor++) { bool bit; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template3"); result |= bit << (7 - x_minor); CONTEXT = ((CONTEXT & 0x1f7) << 1) | bit | ((line_m1 >> (10 - x_minor)) & 0x010); } @@ -415,6 +432,7 @@ jbig2_decode_generic_template3_unopt(Jbig2Ctx *ctx, uint32_t CONTEXT; int x, y; bool bit; + int code = 0; if (pixel_outside_field(params->gbat[0], params->gbat[1])) return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, @@ -435,7 +453,9 @@ jbig2_decode_generic_template3_unopt(Jbig2Ctx *ctx, CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 7; CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8; CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 9; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template3"); jbig2_image_set_pixel(image, x, y, bit); } } @@ -467,6 +487,7 @@ jbig2_decode_generic_template0_TPGDON(Jbig2Ctx *ctx, int x, y; bool bit; int LTP = 0; + int code = 0; if (pixel_outside_field(params->gbat[0], params->gbat[1]) || pixel_outside_field(params->gbat[2], params->gbat[3]) || @@ -476,7 +497,9 @@ jbig2_decode_generic_template0_TPGDON(Jbig2Ctx *ctx, "adaptive template pixel is out of field"); for (y = 0; y < GBH; y++) { - LTP ^= jbig2_arith_decode(as, &GB_stats[0x9B25]); + LTP ^= jbig2_arith_decode(as, &GB_stats[0x9B25], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template0 TPGDON1"); if (!LTP) { for (x = 0; x < GBW; x++) { CONTEXT = jbig2_image_get_pixel(image, x - 1, y); @@ -495,7 +518,9 @@ jbig2_decode_generic_template0_TPGDON(Jbig2Ctx *ctx, CONTEXT |= jbig2_image_get_pixel(image, x, y - 2) << 13; CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 14; CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[6], y + params->gbat[7]) << 15; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template0 TPGDON2"); jbig2_image_set_pixel(image, x, y, bit); } } else { @@ -517,13 +542,16 @@ jbig2_decode_generic_template1_TPGDON(Jbig2Ctx *ctx, int x, y; bool bit; int LTP = 0; + int code = 0; if (pixel_outside_field(params->gbat[0], params->gbat[1])) return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "adaptive template pixel is out of field"); for (y = 0; y < GBH; y++) { - LTP ^= jbig2_arith_decode(as, &GB_stats[0x0795]); + LTP ^= jbig2_arith_decode(as, &GB_stats[0x0795], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template1 TPGDON1"); if (!LTP) { for (x = 0; x < GBW; x++) { CONTEXT = jbig2_image_get_pixel(image, x - 1, y); @@ -539,7 +567,9 @@ jbig2_decode_generic_template1_TPGDON(Jbig2Ctx *ctx, CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 10; CONTEXT |= jbig2_image_get_pixel(image, x, y - 2) << 11; CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 12; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template1 TPGDON2"); jbig2_image_set_pixel(image, x, y, bit); } } else { @@ -561,13 +591,16 @@ jbig2_decode_generic_template2_TPGDON(Jbig2Ctx *ctx, int x, y; bool bit; int LTP = 0; + int code = 0; if (pixel_outside_field(params->gbat[0], params->gbat[1])) return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "adaptive template pixel is out of field"); for (y = 0; y < GBH; y++) { - LTP ^= jbig2_arith_decode(as, &GB_stats[0xE5]); + LTP ^= jbig2_arith_decode(as, &GB_stats[0xE5], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template2 TPGDON1"); if (!LTP) { for (x = 0; x < GBW; x++) { CONTEXT = jbig2_image_get_pixel(image, x - 1, y); @@ -580,7 +613,9 @@ jbig2_decode_generic_template2_TPGDON(Jbig2Ctx *ctx, CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 7; CONTEXT |= jbig2_image_get_pixel(image, x, y - 2) << 8; CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 9; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template2 TPGDON2"); jbig2_image_set_pixel(image, x, y, bit); } } else { @@ -602,13 +637,16 @@ jbig2_decode_generic_template3_TPGDON(Jbig2Ctx *ctx, int x, y; bool bit; int LTP = 0; + int code = 0; if (pixel_outside_field(params->gbat[0], params->gbat[1])) return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "adaptive template pixel is out of field"); for (y = 0; y < GBH; y++) { - LTP ^= jbig2_arith_decode(as, &GB_stats[0x0195]); + LTP ^= jbig2_arith_decode(as, &GB_stats[0x0195], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template3 TPGDON1"); if (!LTP) { for (x = 0; x < GBW; x++) { CONTEXT = jbig2_image_get_pixel(image, x - 1, y); @@ -621,7 +659,9 @@ jbig2_decode_generic_template3_TPGDON(Jbig2Ctx *ctx, CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 7; CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8; CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 9; - bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling generic template3 TPGDON2"); jbig2_image_set_pixel(image, x, y, bit); } } else { @@ -791,8 +831,9 @@ jbig2_immediate_generic_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte } if (code >= 0) - jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image, rsi.x, rsi.y, rsi.op); - else + code = jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image, rsi.x, rsi.y, rsi.op); + + if (code < 0) jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "error while decoding immediate_generic_region"); cleanup: diff --git a/jbig2dec/jbig2_halftone.c b/jbig2dec/jbig2_halftone.c index e4dc0a19f..eb09cf056 100644 --- a/jbig2dec/jbig2_halftone.c +++ b/jbig2dec/jbig2_halftone.c @@ -44,7 +44,9 @@ jbig2_hd_new(Jbig2Ctx *ctx, const Jbig2PatternDictParams *params, Jbig2Image *im const int N = params->GRAYMAX + 1; const int HPW = params->HDPW; const int HPH = params->HDPH; + int code; int i; + int j; /* allocate a new struct */ new = jbig2_new(ctx, Jbig2PatternDict, 1); @@ -63,7 +65,6 @@ jbig2_hd_new(Jbig2Ctx *ctx, const Jbig2PatternDictParams *params, Jbig2Image *im for (i = 0; i < N; i++) { new->patterns[i] = jbig2_image_new(ctx, HPW, HPH); if (new->patterns[i] == NULL) { - int j; jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "failed to allocate pattern element image"); for (j = 0; j < i; j++) @@ -74,7 +75,14 @@ jbig2_hd_new(Jbig2Ctx *ctx, const Jbig2PatternDictParams *params, Jbig2Image *im /* compose with the REPLACE operator; the source will be clipped to the destination, selecting the proper sub image */ - jbig2_image_compose(ctx, new->patterns[i], image, -i * HPW, 0, JBIG2_COMPOSE_REPLACE); + code = jbig2_image_compose(ctx, new->patterns[i], image, -i * HPW, 0, JBIG2_COMPOSE_REPLACE); + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "failed to compose image into collective bitmap dictionary"); + for (j = 0; j < i; j++) + jbig2_free(ctx->allocator, new->patterns[j]); + jbig2_free(ctx->allocator, new); + return NULL; + } } } else { jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to allocate collective bitmap dictionary"); @@ -169,6 +177,8 @@ jbig2_decode_pattern_dict(Jbig2Ctx *ctx, Jbig2Segment *segment, if (code == 0) hd = jbig2_hd_new(ctx, params, image); + else + jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "error while decoding immediate_generic_region"); jbig2_image_release(ctx, image); return hd; @@ -452,6 +462,7 @@ jbig2_decode_halftone_region(Jbig2Ctx *ctx, Jbig2Segment *segment, uint32_t mg, ng; int32_t x, y; uint8_t gray_val; + int code; /* 6.6.5 point 1. Fill bitmap with HDEFPIXEL */ memset(image->data, params->HDEFPIXEL, image->stride * image->height); @@ -498,7 +509,11 @@ jbig2_decode_halftone_region(Jbig2Ctx *ctx, Jbig2Segment *segment, /* use highest available pattern */ gray_val = HNUMPATS - 1; } - jbig2_image_compose(ctx, image, HPATS->patterns[gray_val], x, y, params->op); + code = jbig2_image_compose(ctx, image, HPATS->patterns[gray_val], x, y, params->op); + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to compose pattern with gray-scale image"); + return -1; + } } } @@ -592,13 +607,23 @@ jbig2_halftone_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segment_ } code = jbig2_decode_halftone_region(ctx, segment, ¶ms, segment_data + offset, segment->data_length - offset, image, GB_stats); + if (code < 0) { + jbig2_image_release(ctx, image); + return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "unable to decode halftone region"); + } /* todo: retain GB_stats? */ if (!params.HMMR) { jbig2_free(ctx->allocator, GB_stats); } - jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image, region_info.x, region_info.y, region_info.op); + code = jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image, region_info.x, region_info.y, region_info.op); + if (code < 0) + { + jbig2_image_release(ctx, image); + return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "unable add halftone region to page"); + } + jbig2_image_release(ctx, image); return code; diff --git a/jbig2dec/jbig2_image.c b/jbig2dec/jbig2_image.c index ce0d38fcd..91977ee44 100644 --- a/jbig2dec/jbig2_image.c +++ b/jbig2dec/jbig2_image.c @@ -132,7 +132,7 @@ jbig2_image_resize(Jbig2Ctx *ctx, Jbig2Image *image, uint32_t width, uint32_t he jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "jbig2_image_resize called with a different width (NYI)"); } - return NULL; + return image; } /* composite one jbig2_image onto another diff --git a/jbig2dec/jbig2_image_pbm.c b/jbig2dec/jbig2_image_pbm.c index 36f334fcf..7775c8bb8 100644 --- a/jbig2dec/jbig2_image_pbm.c +++ b/jbig2dec/jbig2_image_pbm.c @@ -35,17 +35,17 @@ int jbig2_image_write_pbm_file(Jbig2Image *image, char *filename) { FILE *out; - int error; + int code; if ((out = fopen(filename, "wb")) == NULL) { fprintf(stderr, "unable to open '%s' for writing", filename); return 1; } - error = jbig2_image_write_pbm(image, out); + code = jbig2_image_write_pbm(image, out); fclose(out); - return (error); + return (code); } /* write out an image struct as a pbm stream to an open file pointer */ diff --git a/jbig2dec/jbig2_image_png.c b/jbig2dec/jbig2_image_png.c index 44b42662a..8b64469d6 100644 --- a/jbig2dec/jbig2_image_png.c +++ b/jbig2dec/jbig2_image_png.c @@ -138,15 +138,15 @@ int jbig2_image_write_png_file(Jbig2Image *image, char *filename) { FILE *out; - int error; + int code; if ((out = fopen(filename, "wb")) == NULL) { fprintf(stderr, "unable to open '%s' for writing\n", filename); return 1; } - error = jbig2_image_write_png(image, out); + code = jbig2_image_write_png(image, out); fclose(out); - return (error); + return (code); } diff --git a/jbig2dec/jbig2_metadata.c b/jbig2dec/jbig2_metadata.c index 7d7de1620..872a36a0d 100644 --- a/jbig2dec/jbig2_metadata.c +++ b/jbig2dec/jbig2_metadata.c @@ -107,6 +107,11 @@ jbig2_metadata_add(Jbig2Ctx *ctx, Jbig2Metadata *md, const char *key, const int /* copy the passed key,value pair */ md->keys[md->entries] = jbig2_strndup(ctx, key, key_length); md->values[md->entries] = jbig2_strndup(ctx, value, value_length); + if (md->keys[md->entries] == NULL || md->values[md->entries] == NULL) + { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "unable to accomodate more metadata"); + return -1; + } md->entries++; return 0; @@ -120,6 +125,7 @@ jbig2_comment_ascii(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment char *end = (char *)(segment_data + segment->data_length); Jbig2Metadata *comment; char *key, *value; + int code; jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number, "ASCII comment data"); @@ -139,7 +145,11 @@ jbig2_comment_ascii(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment if (!s) goto too_short; s++; - jbig2_metadata_add(ctx, comment, key, value - key, value, s - value); + code = jbig2_metadata_add(ctx, comment, key, value - key, value, s - value); + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "unable to add ascii comment data"); + return -1; + } jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number, "'%s'\t'%s'", key, value); } diff --git a/jbig2dec/jbig2_mmr.c b/jbig2dec/jbig2_mmr.c index ac1ab20e4..bc1d17af1 100644 --- a/jbig2dec/jbig2_mmr.c +++ b/jbig2dec/jbig2_mmr.c @@ -831,7 +831,7 @@ jbig2_decode_get_run(Jbig2MmrCtx *mmr, const mmr_table_node *table, int initial_ } static int -jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) +jbig2_decode_mmr_line(Jbig2Ctx *ctx, Jbig2MmrCtx *mmr, const byte *ref, byte *dst) { uint32_t a0 = MINUS1; uint32_t a1, a2, b1, b2; @@ -863,7 +863,7 @@ jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) if (a2 > mmr->width) a2 = mmr->width; if (a1 == MINUS1 || a2 < a1) - return -1; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "negative black run"); jbig2_set_bits(dst, a1, a2); a0 = a2; /* printf ("H %d %d\n", white_run, black_run); */ @@ -877,7 +877,7 @@ jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) if (a2 > mmr->width) a2 = mmr->width; if (a0 == MINUS1 || a1 < a0) - return -1; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "negative white run"); jbig2_set_bits(dst, a0, a1); a0 = a2; /* printf ("H %d %d\n", black_run, white_run); */ @@ -891,7 +891,7 @@ jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) b2 = jbig2_find_changing_element(ref, b1, mmr->width); if (c) { if (a0 == MINUS1 || b2 < a0) - return -1; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "negative white run"); jbig2_set_bits(dst, a0, b2); } a0 = b2; @@ -903,7 +903,7 @@ jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c); if (c) { if (a0 == MINUS1 || b1 < a0) - return -1; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "negative white run"); jbig2_set_bits(dst, a0, b1); } a0 = b1; @@ -918,7 +918,7 @@ jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) break; if (c) { if (a0 == MINUS1 || b1 + 1 < a0) - return -1; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "negative white run"); jbig2_set_bits(dst, a0, b1 + 1); } a0 = b1 + 1; @@ -933,7 +933,7 @@ jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) break; if (c) { if (a0 == MINUS1 || b1 + 2 < a0) - return -1; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "negative white run"); jbig2_set_bits(dst, a0, b1 + 2); } a0 = b1 + 2; @@ -948,7 +948,7 @@ jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) break; if (c) { if (a0 == MINUS1 || b1 + 3 < a0) - return -1; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "negative white run"); jbig2_set_bits(dst, a0, b1 + 3); } a0 = b1 + 3; @@ -963,7 +963,7 @@ jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) break; if (c) { if (a0 == MINUS1 || b1 - 1 < a0) - return -1; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "negative white run"); jbig2_set_bits(dst, a0, b1 - 1); } a0 = b1 - 1; @@ -978,7 +978,7 @@ jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) break; if (c) { if (a0 == MINUS1 || b1 - 2 < a0) - return -1; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "negative white run"); jbig2_set_bits(dst, a0, b1 - 2); } a0 = b1 - 2; @@ -993,7 +993,7 @@ jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst) break; if (c) { if (a0 == MINUS1 || b1 - 3 < a0) - return -1; + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "negative white run"); jbig2_set_bits(dst, a0, b1 - 3); } a0 = b1 - 3; @@ -1021,9 +1021,12 @@ jbig2_decode_generic_mmr(Jbig2Ctx *ctx, Jbig2Segment *segment, const Jbig2Generi for (y = 0; y < image->height; y++) { memset(dst, 0, rowstride); - code = jbig2_decode_mmr_line(&mmr, ref, dst); + code = jbig2_decode_mmr_line(ctx, &mmr, ref, dst); if (code < 0) + { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "failed to decode mmr line"); return code; + } ref = dst; dst += rowstride; } @@ -1060,9 +1063,12 @@ jbig2_decode_halftone_mmr(Jbig2Ctx *ctx, const Jbig2GenericRegionParams *params, for (y = 0; y < image->height; y++) { memset(dst, 0, rowstride); - code = jbig2_decode_mmr_line(&mmr, ref, dst); + code = jbig2_decode_mmr_line(ctx, &mmr, ref, dst); if (code < 0) + { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "failed to decode halftone mmr line"); return code; + } ref = dst; dst += rowstride; } diff --git a/jbig2dec/jbig2_page.c b/jbig2dec/jbig2_page.c index 3a32ab6fe..fa057a17b 100644 --- a/jbig2dec/jbig2_page.c +++ b/jbig2dec/jbig2_page.c @@ -59,7 +59,7 @@ dump_page_info(Jbig2Ctx *ctx, Jbig2Segment *segment, Jbig2Page *page) int jbig2_page_info(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data) { - Jbig2Page *page; + Jbig2Page *page, *pages; /* a new page info segment implies the previous page is finished */ page = &(ctx->pages[ctx->current_page]); @@ -77,7 +77,11 @@ jbig2_page_info(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_dat index++; if (index >= ctx->max_page_index) { /* grow the list */ - ctx->pages = jbig2_renew(ctx, ctx->pages, Jbig2Page, (ctx->max_page_index <<= 2)); + pages = jbig2_renew(ctx, ctx->pages, Jbig2Page, (ctx->max_page_index <<= 2)); + if (pages == NULL) { + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to reallocate space for more pages"); + } + ctx->pages = pages; for (j = index; j < ctx->max_page_index; j++) { ctx->pages[j].state = JBIG2_PAGE_FREE; ctx->pages[j].number = 0; @@ -200,7 +204,7 @@ jbig2_complete_page(Jbig2Ctx *ctx) } /* ensure image exists before marking page as complete */ - if (ctx->pages[ctx->current_page].image != NULL) { + if (!code && ctx->pages[ctx->current_page].image != NULL) { ctx->pages[ctx->current_page].state = JBIG2_PAGE_COMPLETE; } @@ -214,6 +218,7 @@ int jbig2_end_of_page(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data) { uint32_t page_number = ctx->pages[ctx->current_page].number; + int code; if (segment->page_association != page_number) { jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, @@ -222,10 +227,17 @@ jbig2_end_of_page(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_d jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number, "end of page %d", page_number); - jbig2_complete_page(ctx); + code = jbig2_complete_page(ctx); + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to complete page"); + return -1; + } #ifdef OUTPUT_PBM - jbig2_image_write_pbm(ctx->pages[ctx->current_page].image, stdout); + code = jbig2_image_write_pbm(ctx->pages[ctx->current_page].image, stdout); + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "failed to write page image"); + } #endif return 0; @@ -240,6 +252,8 @@ jbig2_end_of_page(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_d int jbig2_page_add_result(Jbig2Ctx *ctx, Jbig2Page *page, Jbig2Image *image, int x, int y, Jbig2ComposeOp op) { + int code; + /* ensure image exists first */ if (page->image == NULL) { jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "page info possibly missing, no image defined"); @@ -251,12 +265,21 @@ jbig2_page_add_result(Jbig2Ctx *ctx, Jbig2Page *page, Jbig2Image *image, int x, uint32_t new_height = y + image->height + page->end_row; if (page->image->height < new_height) { + Jbig2Image *resized_image = NULL; jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "growing page buffer to %d rows " "to accomodate new stripe", new_height); - jbig2_image_resize(ctx, page->image, page->image->width, new_height); + resized_image = jbig2_image_resize(ctx, page->image, page->image->width, new_height); + if (resized_image == NULL) { + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "unable to resize image to accomodate new stripe"); + } + page->image = resized_image; } } - jbig2_image_compose(ctx, page->image, image, x, y + page->end_row, op); + code = jbig2_image_compose(ctx, page->image, image, x, y + page->end_row, op); + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "failed to compose image with page"); + return -1; + } return 0; } diff --git a/jbig2dec/jbig2_refinement.c b/jbig2dec/jbig2_refinement.c index 626b2d822..8e874b337 100644 --- a/jbig2dec/jbig2_refinement.c +++ b/jbig2dec/jbig2_refinement.c @@ -60,6 +60,7 @@ jbig2_decode_refinement_template0_unopt(Jbig2Ctx *ctx, uint32_t CONTEXT; int x, y; bool bit; + int code = 0; for (y = 0; y < GRH; y++) { for (x = 0; x < GRW; x++) { @@ -77,7 +78,9 @@ jbig2_decode_refinement_template0_unopt(Jbig2Ctx *ctx, CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 1, y - dy - 1) << 10; CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 0, y - dy - 1) << 11; CONTEXT |= jbig2_image_get_pixel(ref, x - dx + params->grat[2], y - dy + params->grat[3]) << 12; - bit = jbig2_arith_decode(as, &GR_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GR_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling refinement template0"); jbig2_image_set_pixel(image, x, y, bit); } } @@ -85,11 +88,16 @@ jbig2_decode_refinement_template0_unopt(Jbig2Ctx *ctx, { static count = 0; char name[32]; + int code; snprintf(name, 32, "refin-%d.pbm", count); - jbig2_image_write_pbm_file(ref, name); + code = jbig2_image_write_pbm_file(ref, name); + if (code < 0) + return jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "failed write refinement input"); snprintf(name, 32, "refout-%d.pbm", count); - jbig2_image_write_pbm_file(image, name); + code = jbig2_image_write_pbm_file(image, name); + if (code < 0) + return jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "failed write refinement output"); count++; } #endif @@ -110,6 +118,7 @@ jbig2_decode_refinement_template1_unopt(Jbig2Ctx *ctx, uint32_t CONTEXT; int x, y; bool bit; + int code = 0; for (y = 0; y < GRH; y++) { for (x = 0; x < GRW; x++) { @@ -124,7 +133,9 @@ jbig2_decode_refinement_template1_unopt(Jbig2Ctx *ctx, CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 0, y - dy + 0) << 7; CONTEXT |= jbig2_image_get_pixel(ref, x - dx - 1, y - dy + 0) << 8; CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 0, y - dy - 1) << 9; - bit = jbig2_arith_decode(as, &GR_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GR_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling refinement template0"); jbig2_image_set_pixel(image, x, y, bit); } } @@ -135,9 +146,13 @@ jbig2_decode_refinement_template1_unopt(Jbig2Ctx *ctx, char name[32]; snprintf(name, 32, "refin-%d.pbm", count); - jbig2_image_write_pbm_file(ref, name); + code = jbig2_image_write_pbm_file(ref, name); + if (code < 0) + jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "failed to write refinement input"); snprintf(name, 32, "refout-%d.pbm", count); - jbig2_image_write_pbm_file(image, name); + code = jbig2_image_write_pbm_file(image, name); + if (code < 0) + jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "failed to write refinement output"); count++; } #endif @@ -159,6 +174,7 @@ jbig2_decode_refinement_template1(Jbig2Ctx *ctx, byte *grreg_line = (byte *) image->data; byte *grref_line = (byte *) params->reference->data; int x, y; + int code = 0; for (y = 0; y < GRH; y++) { const int padded_width = (GRW + 7) & -8; @@ -195,7 +211,9 @@ jbig2_decode_refinement_template1(Jbig2Ctx *ctx, for (x_minor = 0; x_minor < minor_width; x_minor++) { bool bit; - bit = jbig2_arith_decode(as, &GR_stats[CONTEXT]); + bit = jbig2_arith_decode(as, &GR_stats[CONTEXT], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling refinement template1"); result |= bit << (7 - x_minor); CONTEXT = ((CONTEXT & 0x0d6) << 1) | bit | ((line_m1 >> (9 - x_minor)) & 0x002) | @@ -281,26 +299,33 @@ mkctx1(const Jbig2RefinementRegionParams *params, Jbig2Image *image, int x, int } static int -jbig2_decode_refinement_TPGRON(const Jbig2RefinementRegionParams *params, Jbig2ArithState *as, Jbig2Image *image, Jbig2ArithCx *GR_stats) +jbig2_decode_refinement_TPGRON(Jbig2Ctx *ctx, const Jbig2RefinementRegionParams *params, Jbig2ArithState *as, Jbig2Image *image, Jbig2ArithCx *GR_stats) { const int GRW = image->width; const int GRH = image->height; int x, y, iv, bit, LTP = 0; uint32_t start_context = (params->GRTEMPLATE ? 0x40 : 0x100); ContextBuilder mkctx = (params->GRTEMPLATE ? mkctx1 : mkctx0); + int code = 0; for (y = 0; y < GRH; y++) { - LTP ^= jbig2_arith_decode(as, &GR_stats[start_context]); + LTP ^= jbig2_arith_decode(as, &GR_stats[start_context], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling refinement TPGRON1"); if (!LTP) { for (x = 0; x < GRW; x++) { - bit = jbig2_arith_decode(as, &GR_stats[mkctx(params, image, x, y)]); + bit = jbig2_arith_decode(as, &GR_stats[mkctx(params, image, x, y)], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling refinement TPGRON1"); jbig2_image_set_pixel(image, x, y, bit); } } else { for (x = 0; x < GRW; x++) { iv = implicit_value(params, image, x, y); if (iv < 0) { - bit = jbig2_arith_decode(as, &GR_stats[mkctx(params, image, x, y)]); + bit = jbig2_arith_decode(as, &GR_stats[mkctx(params, image, x, y)], &code); + if (code) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to decode arithmetic code when handling refinement TPGRON1"); jbig2_image_set_pixel(image, x, y, bit); } else jbig2_image_set_pixel(image, x, y, iv); @@ -340,7 +365,7 @@ jbig2_decode_refinement_region(Jbig2Ctx *ctx, } if (params->TPGRON) - return jbig2_decode_refinement_TPGRON(params, as, image, GR_stats); + return jbig2_decode_refinement_TPGRON(ctx, params, as, image, GR_stats); if (params->GRTEMPLATE) return jbig2_decode_refinement_template1_unopt(ctx, segment, params, as, image, GR_stats); @@ -485,6 +510,10 @@ jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segmen } code = jbig2_decode_refinement_region(ctx, segment, ¶ms, as, image, GR_stats); + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "unable to decode refinement region"); + goto cleanup; + } if ((segment->flags & 63) == 40) { /* intermediate region. save the result for later */ @@ -493,7 +522,11 @@ jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segmen /* immediate region. composite onto the page */ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "composing %dx%d decoded refinement region onto page at (%d, %d)", rsi.width, rsi.height, rsi.x, rsi.y); - jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image, rsi.x, rsi.y, rsi.op); + code = jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image, rsi.x, rsi.y, rsi.op); + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "unable to add refinement region to page"); + goto cleanup; + } } cleanup: diff --git a/jbig2dec/jbig2_segment.c b/jbig2dec/jbig2_segment.c index 5e124af9a..74aeb375c 100644 --- a/jbig2dec/jbig2_segment.c +++ b/jbig2dec/jbig2_segment.c @@ -76,7 +76,7 @@ jbig2_parse_segment_header(Jbig2Ctx *ctx, uint8_t *buf, size_t buf_size, size_t referred_to_segment_size = result->number <= 256 ? 1 : result->number <= 65536 ? 2 : 4; /* 7.2.5 */ pa_size = result->flags & 0x40 ? 4 : 1; /* 7.2.6 */ if (offset + referred_to_segment_count * referred_to_segment_size + pa_size + 4 > buf_size) { - jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, result->number, "jbig2_parse_segment_header() called with insufficient data", -1); + jbig2_error(ctx, JBIG2_SEVERITY_FATAL, result->number, "jbig2_parse_segment_header() called with insufficient data", -1); jbig2_free(ctx->allocator, result); return NULL; } diff --git a/jbig2dec/jbig2_symbol_dict.c b/jbig2dec/jbig2_symbol_dict.c index fd3b54d48..28c2f3899 100644 --- a/jbig2dec/jbig2_symbol_dict.c +++ b/jbig2dec/jbig2_symbol_dict.c @@ -70,6 +70,7 @@ jbig2_dump_symbol_dict(Jbig2Ctx *ctx, Jbig2Segment *segment) Jbig2SymbolDict *dict = (Jbig2SymbolDict *) segment->result; int index; char filename[24]; + int code; if (dict == NULL) return; @@ -78,10 +79,12 @@ jbig2_dump_symbol_dict(Jbig2Ctx *ctx, Jbig2Segment *segment) snprintf(filename, sizeof(filename), "symbol_%02d-%04d.png", segment->number, index); jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "dumping symbol %d/%d as '%s'", index, dict->n_symbols, filename); #ifdef HAVE_LIBPNG - jbig2_image_write_png_file(dict->glyphs[index], filename); + code = jbig2_image_write_png_file(dict->glyphs[index], filename); #else - jbig2_image_write_pbm_file(dict->glyphs[index], filename); + code = jbig2_image_write_pbm_file(dict->glyphs[index], filename); #endif + if (code < 0) + jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number, "failed to dump symbol %d/%d as '%s'", index, dict->n_symbols, filename); } } #endif /* DUMP_SYMDICT */ @@ -318,7 +321,7 @@ jbig2_decode_symbol_dict(Jbig2Ctx *ctx, if (params->SDHUFF) { HCDH = jbig2_huffman_get(hs, params->SDHUFFDH, &code); } else { - code = jbig2_arith_int_decode(IADH, as, &HCDH); + code = jbig2_arith_int_decode(ctx, IADH, as, &HCDH); } if (code != 0) { @@ -350,7 +353,7 @@ jbig2_decode_symbol_dict(Jbig2Ctx *ctx, if (params->SDHUFF) { DW = jbig2_huffman_get(hs, params->SDHUFFDW, &code); } else { - code = jbig2_arith_int_decode(IADW, as, &DW); + code = jbig2_arith_int_decode(ctx, IADW, as, &DW); } if (code < 0) goto cleanup4; @@ -415,7 +418,7 @@ jbig2_decode_symbol_dict(Jbig2Ctx *ctx, if (params->SDHUFF) { REFAGGNINST = jbig2_huffman_get(hs, params->SDHUFFAGGINST, &code); } else { - code = jbig2_arith_int_decode(IAAI, as, (int32_t *) & REFAGGNINST); + code = jbig2_arith_int_decode(ctx, IAAI, as, (int32_t *) & REFAGGNINST); } if (code || (int32_t) REFAGGNINST <= 0) { code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "invalid number of symbols or OOB in aggregate glyph"); @@ -465,6 +468,14 @@ jbig2_decode_symbol_dict(Jbig2Ctx *ctx, tparams->IARDH = jbig2_arith_int_ctx_new(ctx); tparams->IARDX = jbig2_arith_int_ctx_new(ctx); tparams->IARDY = jbig2_arith_int_ctx_new(ctx); + if ((tparams->IAID == NULL) || (tparams->IAFS == NULL) || + (tparams->IADS == NULL) || (tparams->IAIT == NULL) || + (tparams->IAID == NULL) || (tparams->IARDW == NULL) || + (tparams->IARDH == NULL) || (tparams->IARDX == NULL) || + (tparams->IARDY == NULL)) { + jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "out of memory creating text region arith decoder entries"); + goto cleanup4; + } } else { tparams->SBHUFFFS = jbig2_build_huffman_table(ctx, &jbig2_huffman_params_F); /* Table B.6 */ tparams->SBHUFFDS = jbig2_build_huffman_table(ctx, &jbig2_huffman_params_H); /* Table B.8 */ @@ -473,6 +484,13 @@ jbig2_decode_symbol_dict(Jbig2Ctx *ctx, tparams->SBHUFFRDH = jbig2_build_huffman_table(ctx, &jbig2_huffman_params_O); /* Table B.15 */ tparams->SBHUFFRDX = jbig2_build_huffman_table(ctx, &jbig2_huffman_params_O); /* Table B.15 */ tparams->SBHUFFRDY = jbig2_build_huffman_table(ctx, &jbig2_huffman_params_O); /* Table B.15 */ + if ((tparams->SBHUFFFS == NULL) || (tparams->SBHUFFDS == NULL) || + (tparams->SBHUFFDT == NULL) || (tparams->SBHUFFRDW == NULL) || + (tparams->SBHUFFRDH == NULL) || (tparams->SBHUFFRDX == NULL) || + (tparams->SBHUFFRDY == NULL)) { + jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "out of memory creating text region huffman decoder entries"); + goto cleanup4; + } } tparams->SBHUFF = params->SDHUFF; tparams->SBREFINE = 1; @@ -522,9 +540,9 @@ jbig2_decode_symbol_dict(Jbig2Ctx *ctx, BMSIZE = jbig2_huffman_get(hs, SBHUFFRSIZE, &code3); jbig2_huffman_skip(hs); } else { - code1 = jbig2_arith_iaid_decode(IAID, as, (int32_t *) & ID); - code2 = jbig2_arith_int_decode(IARDX, as, &RDX); - code3 = jbig2_arith_int_decode(IARDY, as, &RDY); + code1 = jbig2_arith_iaid_decode(ctx, IAID, as, (int32_t *) & ID); + code2 = jbig2_arith_int_decode(ctx, IARDX, as, &RDX); + code3 = jbig2_arith_int_decode(ctx, IARDY, as, &RDY); } if ((code1 < 0) || (code2 < 0) || (code3 < 0) || (code4 < 0)) { @@ -578,11 +596,15 @@ jbig2_decode_symbol_dict(Jbig2Ctx *ctx, { char name[64]; FILE *out; + int code; snprintf(name, 64, "sd.%04d.%04d.pbm", segment->number, NSYMSDECODED); out = fopen(name, "wb"); - jbig2_image_write_pbm(SDNEWSYMS->glyphs[NSYMSDECODED], out); - jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "writing out glyph as '%s' ...", name); + code = jbig2_image_write_pbm(SDNEWSYMS->glyphs[NSYMSDECODED], out); + if (code < 0) + jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "failed to write glyph"); + else + jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "writing out glyph as '%s' ...", name); fclose(out); } #endif @@ -682,7 +704,13 @@ jbig2_decode_symbol_dict(Jbig2Ctx *ctx, jbig2_image_release(ctx, image); goto cleanup4; } - jbig2_image_compose(ctx, glyph, image, -x, 0, JBIG2_COMPOSE_REPLACE); + code = jbig2_image_compose(ctx, glyph, image, -x, 0, JBIG2_COMPOSE_REPLACE); + if (code) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to compose image into glyph"); + jbig2_image_release(ctx, glyph); + jbig2_image_release(ctx, image); + goto cleanup4; + } x += SDNEWSYMWIDTHS[j]; SDNEWSYMS->glyphs[j] = glyph; } @@ -709,7 +737,7 @@ jbig2_decode_symbol_dict(Jbig2Ctx *ctx, if (params->SDHUFF) exrunlength = jbig2_huffman_get(hs, SBHUFFRSIZE, &code); else - code = jbig2_arith_int_decode(IAEX, as, (int32_t *)&exrunlength); + code = jbig2_arith_int_decode(ctx, IAEX, as, (int32_t *)&exrunlength); /* prevent infinite loop */ zerolength = exrunlength > 0 ? 0 : zerolength + 1; if (code || (exrunlength > limit - i) || (zerolength > 4) || (exflag && (exrunlength + j > params->SDNUMEXSYMS))) { diff --git a/jbig2dec/jbig2_text.c b/jbig2dec/jbig2_text.c index 7f2fada73..69e1ceab3 100644 --- a/jbig2dec/jbig2_text.c +++ b/jbig2dec/jbig2_text.c @@ -207,10 +207,12 @@ cleanup1: if (params->SBHUFF) { STRIPT = jbig2_huffman_get(hs, params->SBHUFFDT, &code); } else { - code = jbig2_arith_int_decode(params->IADT, as, &STRIPT); + code = jbig2_arith_int_decode(ctx, params->IADT, as, &STRIPT); } - if (code < 0) + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to obtain strip T"); goto cleanup2; + } /* 6.4.5 (2) */ STRIPT *= -(params->SBSTRIPS); @@ -223,10 +225,12 @@ cleanup1: if (params->SBHUFF) { DT = jbig2_huffman_get(hs, params->SBHUFFDT, &code); } else { - code = jbig2_arith_int_decode(params->IADT, as, &DT); + code = jbig2_arith_int_decode(ctx, params->IADT, as, &DT); } - if (code < 0) + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to obtain delta T"); goto cleanup2; + } DT *= params->SBSTRIPS; STRIPT += DT; @@ -239,10 +243,12 @@ cleanup1: if (params->SBHUFF) { DFS = jbig2_huffman_get(hs, params->SBHUFFFS, &code); } else { - code = jbig2_arith_int_decode(params->IAFS, as, &DFS); + code = jbig2_arith_int_decode(ctx, params->IAFS, as, &DFS); } - if (code < 0) + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to obtain strip symbol S-difference"); goto cleanup2; + } FIRSTS += DFS; CURS = FIRSTS; first_symbol = FALSE; @@ -255,7 +261,7 @@ cleanup1: if (params->SBHUFF) { IDS = jbig2_huffman_get(hs, params->SBHUFFDS, &code); } else { - code = jbig2_arith_int_decode(params->IADS, as, &IDS); + code = jbig2_arith_int_decode(ctx, params->IADS, as, &IDS); } if (code) { /* decoded an OOB, reached end of strip */ @@ -270,20 +276,24 @@ cleanup1: } else if (params->SBHUFF) { CURT = jbig2_huffman_get_bits(hs, params->LOGSBSTRIPS, &code); } else { - code = jbig2_arith_int_decode(params->IAIT, as, &CURT); + code = jbig2_arith_int_decode(ctx, params->IAIT, as, &CURT); } - if (code < 0) + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to obtain symbol instance T coordinate"); goto cleanup2; + } T = STRIPT + CURT; /* (3b.iv) / 6.4.10 - decode the symbol id */ if (params->SBHUFF) { ID = jbig2_huffman_get(hs, SBSYMCODES, &code); } else { - code = jbig2_arith_iaid_decode(params->IAID, as, (int *)&ID); + code = jbig2_arith_iaid_decode(ctx, params->IAID, as, (int *)&ID); } - if (code < 0) + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to obtain symbol instance symbol ID"); goto cleanup2; + } if (ID >= SBNUMSYMS) { code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "symbol id out of range! (%d/%d)", ID, SBNUMSYMS); goto cleanup2; @@ -307,10 +317,12 @@ cleanup1: if (params->SBHUFF) { RI = jbig2_huffman_get_bits(hs, 1, &code); } else { - code = jbig2_arith_int_decode(params->IARI, as, &RI); + code = jbig2_arith_int_decode(ctx, params->IARI, as, &RI); } - if (code < 0) + if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to obtain symbol bitmap refinement indicator"); goto cleanup2; + } } else { RI = 0; } @@ -328,10 +340,10 @@ cleanup1: /* 6.4.11 (1, 2, 3, 4) */ if (!params->SBHUFF) { - code1 = jbig2_arith_int_decode(params->IARDW, as, &RDW); - code2 = jbig2_arith_int_decode(params->IARDH, as, &RDH); - code3 = jbig2_arith_int_decode(params->IARDX, as, &RDX); - code4 = jbig2_arith_int_decode(params->IARDY, as, &RDY); + code1 = jbig2_arith_int_decode(ctx, params->IARDW, as, &RDW); + code2 = jbig2_arith_int_decode(ctx, params->IARDH, as, &RDH); + code3 = jbig2_arith_int_decode(ctx, params->IARDX, as, &RDX); + code4 = jbig2_arith_int_decode(ctx, params->IARDY, as, &RDY); } else { RDW = jbig2_huffman_get(hs, params->SBHUFFRDW, &code1); RDH = jbig2_huffman_get(hs, params->SBHUFFRDH, &code2); @@ -373,6 +385,7 @@ cleanup1: memcpy(rparams.grat, params->sbrat, 4); code = jbig2_decode_refinement_region(ctx, segment, &rparams, as, refimage, GR_stats); if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode refinement region"); jbig2_image_release(ctx, refimage); jbig2_image_release(ctx, IBO); goto cleanup2; @@ -448,6 +461,7 @@ cleanup1: #endif code = jbig2_image_compose(ctx, image, IB, x, y, params->SBCOMBOP); if (code < 0) { + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to compose symbol instance symbol bitmap into picture"); jbig2_image_release(ctx, IB); goto cleanup2; } @@ -877,7 +891,9 @@ jbig2_text_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segment_data /* otherwise composite onto the page */ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "composing %dx%d decoded text region onto page at (%d, %d)", region_info.width, region_info.height, region_info.x, region_info.y); - jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image, region_info.x, region_info.y, region_info.op); + code = jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image, region_info.x, region_info.y, region_info.op); + if (code < 0) + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "unable to add text region to page"); } cleanup4: diff --git a/jbig2dec/jbig2dec.c b/jbig2dec/jbig2dec.c index 9ab48e726..c1ee4a609 100644 --- a/jbig2dec/jbig2dec.c +++ b/jbig2dec/jbig2dec.c @@ -333,12 +333,10 @@ write_page_image(jbig2dec_params_t *params, Jbig2Image *image) switch (params->output_format) { #ifdef HAVE_LIBPNG case jbig2dec_format_png: - jbig2_image_write_png(image, stdout); - break; + return jbig2_image_write_png(image, stdout); #endif case jbig2dec_format_pbm: - jbig2_image_write_pbm(image, stdout); - break; + return jbig2_image_write_pbm(image, stdout); default: fprintf(stderr, "unsupported output format.\n"); return 1; @@ -349,12 +347,10 @@ write_page_image(jbig2dec_params_t *params, Jbig2Image *image) switch (params->output_format) { #ifdef HAVE_LIBPNG case jbig2dec_format_png: - jbig2_image_write_png_file(image, params->output_file); - break; + return jbig2_image_write_png_file(image, params->output_file); #endif case jbig2dec_format_pbm: - jbig2_image_write_pbm_file(image, params->output_file); - break; + return jbig2_image_write_pbm_file(image, params->output_file); default: fprintf(stderr, "unsupported output format.\n"); return 1; @@ -391,6 +387,7 @@ main(int argc, char **argv) jbig2dec_params_t params; int filearg; int result = 1; + int code; /* set defaults */ params.mode = render; @@ -449,6 +446,12 @@ main(int argc, char **argv) } ctx = jbig2_ctx_new(NULL, (Jbig2Options)(f_page != NULL ? JBIG2_OPTIONS_EMBEDDED : 0), NULL, error_callback, ¶ms); + if (ctx == NULL) { + fclose(f); + if (f_page) + fclose(f_page); + goto cleanup; + } /* pull the whole file/global stream into memory */ for (;;) { @@ -466,13 +469,15 @@ main(int argc, char **argv) Jbig2GlobalCtx *global_ctx = jbig2_make_global_ctx(ctx); ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, global_ctx, error_callback, ¶ms); - for (;;) { - int n_bytes = fread(buf, 1, sizeof(buf), f_page); - - if (n_bytes <= 0) - break; - if (jbig2_data_in(ctx, buf, n_bytes)) - break; + if (ctx != NULL) { + for (;;) { + int n_bytes = fread(buf, 1, sizeof(buf), f_page); + + if (n_bytes <= 0) + break; + if (jbig2_data_in(ctx, buf, n_bytes)) + break; + } } fclose(f_page); jbig2_global_ctx_free(global_ctx); @@ -484,7 +489,11 @@ main(int argc, char **argv) /* work around broken CVision embedded streams */ if (f_page != NULL) - jbig2_complete_page(ctx); + { + code = jbig2_complete_page(ctx); + if (code < 0) + jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "unable to complete page"); + } if (params.output_file == NULL) { #ifdef HAVE_LIBPNG diff --git a/jbig2dec/pbm2png.c b/jbig2dec/pbm2png.c index b49730b74..a174f65f8 100644 --- a/jbig2dec/pbm2png.c +++ b/jbig2dec/pbm2png.c @@ -39,7 +39,7 @@ main(int argc, char *argv[]) { Jbig2Ctx *ctx; Jbig2Image *image; - int error; + int code; /* we need a context for the allocators */ ctx = jbig2_ctx_new(NULL, 0, NULL, NULL, NULL); @@ -57,10 +57,10 @@ main(int argc, char *argv[]) fprintf(stderr, "converting %dx%d image to png format\n", image->width, image->height); } - error = jbig2_image_write_png_file(image, argv[2]); - if (error) { - fprintf(stderr, "error writing png file '%s' error %d\n", argv[2], error); + code = jbig2_image_write_png_file(image, argv[2]); + if (code) { + fprintf(stderr, "error writing png file '%s' error %d\n", argv[2], code); } - return (error); + return (code); } |