ref: e0a50f1db9dc9adfe4b9001bed4c55a7dee56b31
parent: a9da05ed8eb0b63f6d6c378412f725100f9dd0fd
author: Shailesh Mistry <shailesh.mistry@hotmail.co.uk>
date: Sat May 25 23:01:24 EDT 2013
Bug 694021: Patch for seg fault related issues The seg fault is due to the the image decoder trying to use an uninitialized GR_stats. This also uncovered a few other errors that are covered here :- 1) GR_stats is now initialised in all places to prevent it reaching jbig2_arith_decode with fake values 2) jbig2_arith_decode has been updated to prevent access outside of the jbig2_arith_Qe array which now returns an error in such cases. 3) all uses of jbig2_decode_refinement_region now check for a returning error and act accordingly.
--- a/jbig2_arith.c
+++ b/jbig2_arith.c
@@ -229,6 +229,8 @@
return result;
}
+#define MAX_QE_ARRAY_SIZE 47
+
/* could put bit fields in to minimize memory usage */
typedef struct {
unsigned short Qe;
@@ -236,7 +238,7 @@
byte lps_xor; /* lps_xor = index ^ NLPS ^ (SWITCH << 7) */
} Jbig2ArithQe;
-const Jbig2ArithQe jbig2_arith_Qe[] = {
+const Jbig2ArithQe jbig2_arith_Qe[MAX_QE_ARRAY_SIZE] = {
{ 0x5601, 1 ^ 0, 1 ^ 0 ^ 0x80 },
{ 0x3401, 2 ^ 1, 6 ^ 1 },
{ 0x1801, 3 ^ 2, 9 ^ 2 },
@@ -306,8 +308,18 @@
jbig2_arith_decode (Jbig2ArithState *as, Jbig2ArithCx *pcx)
{
Jbig2ArithCx cx = *pcx;
- const Jbig2ArithQe *pqe = &jbig2_arith_Qe[cx & 0x7f];
+ const Jbig2ArithQe *pqe;
+ unsigned int index = cx & 0x7f;
bool D;
+
+ if (index >= MAX_QE_ARRAY_SIZE)
+ {
+ return -1;
+ }
+ else
+ {
+ pqe = &jbig2_arith_Qe[index];
+ }
/* Figure E.15 */
as->A -= pqe->Qe;
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -619,8 +619,9 @@
rparams.DY = RDY;
rparams.TPGRON = 0;
memcpy(rparams.grat, params->sdrat, 4);
- jbig2_decode_refinement_region(ctx, segment,
+ code = jbig2_decode_refinement_region(ctx, segment,
&rparams, as, image, GR_stats);
+ if (code < 0) goto cleanup4;
SDNEWSYMS->glyphs[NSYMSDECODED] = image;
@@ -1094,20 +1095,18 @@
goto cleanup;
}
memset(GB_stats, 0, stats_size);
- if (params.SDREFAGG) {
- stats_size = params.SDRTEMPLATE ? 1 << 10 : 1 << 13;
- GR_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size);
- if (GR_stats == NULL)
- {
- jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
- "failed to allocate GR_stats in jbig2_symbol_dictionary");
- jbig2_free(ctx->allocator, GB_stats);
- goto cleanup;
- }
- memset(GR_stats, 0, stats_size);
- }
+
+ stats_size = params.SDRTEMPLATE ? 1 << 10 : 1 << 13;
+ GR_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size);
+ if (GR_stats == NULL)
+ {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+ "failed to allocate GR_stats in jbig2_symbol_dictionary");
+ jbig2_free(ctx->allocator, GB_stats);
+ goto cleanup;
+ }
+ memset(GR_stats, 0, stats_size);
}
-
segment->result = (void *)jbig2_decode_symbol_dict(ctx, segment,
¶ms,
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -379,8 +379,9 @@
rparams.DY = (RDH >> 1) + RDY;
rparams.TPGRON = 0;
memcpy(rparams.grat, params->sbrat, 4);
- jbig2_decode_refinement_region(ctx, segment,
+ code = jbig2_decode_refinement_region(ctx, segment,
&rparams, as, refimage, GR_stats);
+ if (code < 0) goto cleanup2;
IB = refimage;
jbig2_image_release(ctx, IBO);
@@ -834,7 +835,7 @@
}
/* 7.4.3.2 (3) */
- if (!params.SBHUFF && params.SBREFINE) {
+ {
int stats_size = params.SBRTEMPLATE ? 1 << 10 : 1 << 13;
GR_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size);
if (GR_stats == NULL)