From 26ac0d3505530c6782dffeeaa053328a481afcb0 Mon Sep 17 00:00:00 2001 From: Shailesh Mistry Date: Mon, 14 May 2012 18:08:00 +0100 Subject: Bug 693025: Updated patch from Zeniko to fix various crashes and leaks --- gs/jbig2dec/jbig2_halftone.c | 2 +- gs/jbig2dec/jbig2_huffman.c | 8 ++++++++ gs/jbig2dec/jbig2_image.c | 3 +++ gs/jbig2dec/jbig2_refinement.c | 22 +++++++++++++--------- gs/jbig2dec/jbig2_segment.c | 6 ++++++ gs/jbig2dec/jbig2_symbol_dict.c | 2 ++ gs/jbig2dec/jbig2_text.c | 11 +++++------ 7 files changed, 38 insertions(+), 16 deletions(-) diff --git a/gs/jbig2dec/jbig2_halftone.c b/gs/jbig2dec/jbig2_halftone.c index 969608a4c..0aea8a8b4 100644 --- a/gs/jbig2dec/jbig2_halftone.c +++ b/gs/jbig2dec/jbig2_halftone.c @@ -142,7 +142,7 @@ jbig2_decode_pattern_dict(Jbig2Ctx *ctx, Jbig2Segment *segment, rparams.GBTEMPLATE = params->HDTEMPLATE; rparams.TPGDON = 0; /* not used if HDMMR = 1 */ rparams.USESKIP = 0; - rparams.gbat[0] = -params->HDPW; + rparams.gbat[0] = -(int8_t)params->HDPW; rparams.gbat[1] = 0; rparams.gbat[2] = -3; rparams.gbat[3] = -1; diff --git a/gs/jbig2dec/jbig2_huffman.c b/gs/jbig2dec/jbig2_huffman.c index b7420d1a7..ebeef5a3d 100644 --- a/gs/jbig2dec/jbig2_huffman.c +++ b/gs/jbig2dec/jbig2_huffman.c @@ -253,6 +253,12 @@ jbig2_huffman_get (Jbig2HuffmanState *hs, entry = &table->entries[this_word >> (32 - log_table_size)]; flags = entry->flags; PREFLEN = entry->PREFLEN; + if ((flags == (byte)-1) && (PREFLEN == (int)-1) && (entry->u.RANGELOW == -1)) + { + if (oob) + *oob = -1; + return -1; + } next_word = hs->next_word; offset_bits += PREFLEN; @@ -386,6 +392,8 @@ jbig2_build_huffman_table (Jbig2Ctx *ctx, const Jbig2HuffmanParams *params) "couldn't allocate entries storage in jbig2_build_huffman_table"); return NULL; } + /* fill now to catch missing JBIG2Globals later */ + memset(entries, 0xFF, sizeof(Jbig2HuffmanEntry)*max_j); result->entries = entries; LENCOUNT[0] = 0; diff --git a/gs/jbig2dec/jbig2_image.c b/gs/jbig2dec/jbig2_image.c index 1025c62bc..0ab339b7c 100644 --- a/gs/jbig2dec/jbig2_image.c +++ b/gs/jbig2dec/jbig2_image.c @@ -229,6 +229,9 @@ int jbig2_image_compose(Jbig2Ctx *ctx, Jbig2Image *dst, Jbig2Image *src, #endif leftbyte = x >> 3; + if (leftbyte > dst->height * dst->stride) + return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, + "preventing heap overflow in jbig2_image_compose"); rightbyte = (x + w - 1) >> 3; shift = x & 7; diff --git a/gs/jbig2dec/jbig2_refinement.c b/gs/jbig2dec/jbig2_refinement.c index 6b09ab844..840bfb1a0 100644 --- a/gs/jbig2dec/jbig2_refinement.c +++ b/gs/jbig2dec/jbig2_refinement.c @@ -435,6 +435,7 @@ jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment, Jbig2RegionSegmentInfo rsi; int offset = 0; byte seg_flags; + int code = 0; /* 7.4.7 */ if (segment->data_length < 18) @@ -509,12 +510,14 @@ jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment, Jbig2ArithCx *GR_stats = NULL; int stats_size; Jbig2Image *image = NULL; - int code; image = jbig2_image_new(ctx, rsi.width, rsi.height); if (image == NULL) - return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, - "unable to allocate refinement image"); + { + code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, + "unable to allocate refinement image"); + goto cleanup; + } jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "allocated %d x %d image buffer for region decode results", rsi.width, rsi.height); @@ -523,7 +526,7 @@ jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment, GR_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size); if (GR_stats == NULL) { - jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, + code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to allocate GR-stats in jbig2_refinement_region"); goto cleanup; } @@ -533,7 +536,7 @@ jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment, segment->data_length - offset); if (ws == NULL) { - jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, + code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to allocate ws in jbig2_refinement_region"); goto cleanup; } @@ -541,7 +544,7 @@ jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment, as = jbig2_arith_new(ctx, ws); if (as == NULL) { - jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, + code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to allocate as in jbig2_refinement_region"); goto cleanup; } @@ -551,7 +554,7 @@ jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment, if ((segment->flags & 63) == 40) { /* intermediate region. save the result for later */ - segment->result = image; + segment->result = jbig2_image_clone(ctx, image); } else { /* immediate region. composite onto the page */ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, @@ -559,14 +562,15 @@ jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment, 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); - jbig2_image_release(ctx, image); } cleanup: + jbig2_image_release(ctx, image); + jbig2_image_release(ctx, params.reference); jbig2_free(ctx->allocator, as); jbig2_word_stream_buf_free(ctx, ws); jbig2_free(ctx->allocator, GR_stats); } - return 0; + return code; } diff --git a/gs/jbig2dec/jbig2_segment.c b/gs/jbig2dec/jbig2_segment.c index 245def621..86b854a59 100644 --- a/gs/jbig2dec/jbig2_segment.c +++ b/gs/jbig2dec/jbig2_segment.c @@ -25,6 +25,8 @@ #include "jbig2_huffman.h" #include "jbig2_symbol_dict.h" #include "jbig2_metadata.h" +#include "jbig2_arith.h" +#include "jbig2_halftone.h" Jbig2Segment * jbig2_parse_segment_header (Jbig2Ctx *ctx, uint8_t *buf, size_t buf_size, @@ -156,6 +158,10 @@ jbig2_free_segment (Jbig2Ctx *ctx, Jbig2Segment *segment) if (segment->result != NULL) jbig2_image_release(ctx, (Jbig2Image*)segment->result); break; + case 16: /* pattern dictionary */ + if (segment->result != NULL) + jbig2_hd_release(ctx, (Jbig2PatternDict*)segment->result); + break; case 53: /* user-supplied huffman table */ if (segment->result != NULL) jbig2_table_free(ctx, (Jbig2HuffmanParams*)segment->result); diff --git a/gs/jbig2dec/jbig2_symbol_dict.c b/gs/jbig2dec/jbig2_symbol_dict.c index b5a2358e1..a8a5ad359 100644 --- a/gs/jbig2dec/jbig2_symbol_dict.c +++ b/gs/jbig2dec/jbig2_symbol_dict.c @@ -1068,6 +1068,7 @@ jbig2_symbol_dictionary(Jbig2Ctx *ctx, Jbig2Segment *segment, } else { /* todo: free GB_stats, GR_stats */ } + jbig2_free(ctx->allocator, GR_stats); cleanup: if (params.SDHUFF) { @@ -1076,6 +1077,7 @@ cleanup: jbig2_release_huffman_table(ctx, params.SDHUFFBMSIZE); jbig2_release_huffman_table(ctx, params.SDHUFFAGGINST); } + jbig2_sd_release(ctx, params.SDINSYMS); return (segment->result != NULL) ? 0 : -1; diff --git a/gs/jbig2dec/jbig2_text.c b/gs/jbig2dec/jbig2_text.c index 4a2395b56..59838eb79 100644 --- a/gs/jbig2dec/jbig2_text.c +++ b/gs/jbig2dec/jbig2_text.c @@ -280,8 +280,9 @@ cleanup1: if (code < 0) goto cleanup2; } if (ID >= SBNUMSYMS) { - return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, - "symbol id out of range! (%d/%d)", ID, SBNUMSYMS); + code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, + "symbol id out of range! (%d/%d)", ID, SBNUMSYMS); + goto cleanup2; } /* (3c.v) / 6.4.11 - look up the symbol bitmap IB */ @@ -836,7 +837,6 @@ jbig2_text_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segment_data { code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "couldn't allocate text region image"); - jbig2_image_release(ctx, image); goto cleanup2; } if (!params.SBHUFF) { @@ -885,13 +885,12 @@ jbig2_text_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segment_data { jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode text region image data"); - jbig2_image_release(ctx, image); goto cleanup4; } if ((segment->flags & 63) == 4) { /* we have an intermediate region here. save it for later */ - segment->result = image; + segment->result = jbig2_image_clone(ctx, image); } else { /* otherwise composite onto the page */ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, @@ -899,7 +898,6 @@ jbig2_text_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segment_data 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); - jbig2_image_release(ctx, image); } cleanup4: @@ -926,6 +924,7 @@ cleanup2: if (!params.SBHUFF && params.SBREFINE) { jbig2_free(ctx->allocator, GR_stats); } + jbig2_image_release(ctx, image); cleanup1: if (params.SBHUFF) { -- cgit v1.2.3