diff options
author | Sebastian Rasmussen <sebras@gmail.com> | 2019-02-09 13:34:17 +0100 |
---|---|---|
committer | Sebastian Rasmussen <sebras@gmail.com> | 2019-02-12 19:06:46 +0100 |
commit | 660eaabf87a143b5217dc875550968883d8e4fc0 (patch) | |
tree | b18ef3b21216911b96b89f5c39b3796386583862 | |
parent | 0d942b34ae4a5385f5cd3cfa9b2c708f56c65860 (diff) | |
download | ghostpdl-660eaabf87a143b5217dc875550968883d8e4fc0.tar.gz |
Bug 700554: jbig2: Use custom allocator for jbig2dec/luratech decoders.
-rw-r--r-- | base/sjbig2.c | 88 | ||||
-rw-r--r-- | base/sjbig2.h | 2 | ||||
-rw-r--r-- | base/sjbig2_luratech.c | 32 | ||||
-rw-r--r-- | base/sjbig2_luratech.h | 2 | ||||
-rw-r--r-- | psi/zfjbig2.c | 2 |
5 files changed, 98 insertions, 28 deletions
diff --git a/base/sjbig2.c b/base/sjbig2.c index f8817e16a..73a9b1bef 100644 --- a/base/sjbig2.c +++ b/base/sjbig2.c @@ -172,13 +172,37 @@ s_jbig2decode_invert_buffer(unsigned char *buf, int length) *buf++ ^= 0xFF; } +typedef struct { + Jbig2Allocator allocator; + gs_memory_t *mem; +} s_jbig2decode_allocator_t; + +static void *s_jbig2decode_alloc(Jbig2Allocator *_allocator, size_t size) +{ + s_jbig2decode_allocator_t *allocator = (s_jbig2decode_allocator_t *) _allocator; + return gs_alloc_bytes(allocator->mem, size, "s_jbig2decode_alloc"); +} + +static void s_jbig2decode_free(Jbig2Allocator *_allocator, void *p) +{ + s_jbig2decode_allocator_t *allocator = (s_jbig2decode_allocator_t *) _allocator; + gs_free_object(allocator->mem, p, "s_jbig2decode_free"); +} + +static void *s_jbig2decode_realloc(Jbig2Allocator *_allocator, void *p, size_t size) +{ + s_jbig2decode_allocator_t *allocator = (s_jbig2decode_allocator_t *) _allocator; + return gs_resize_object(allocator->mem, p, size, "s_jbig2decode_realloc"); +} + /* parse a globals stream packed into a gs_bytestring for us by the postscript layer and stuff the resulting context into a pointer for use in later decoding */ int -s_jbig2decode_make_global_data(byte *data, uint length, void **result) +s_jbig2decode_make_global_data(gs_memory_t *mem, byte *data, uint length, void **result) { Jbig2Ctx *ctx = NULL; int code; + s_jbig2decode_allocator_t *allocator; /* the cvision encoder likes to include empty global streams */ if (length == 0) { @@ -187,19 +211,34 @@ s_jbig2decode_make_global_data(byte *data, uint length, void **result) return 0; } + allocator = (s_jbig2decode_allocator_t *) gs_alloc_bytes(mem, + sizeof (s_jbig2decode_allocator_t), "s_jbig2_make_global_data"); + if (allocator == NULL) { + *result = NULL; + return_error(gs_error_VMerror); + } + + allocator->allocator.alloc = s_jbig2decode_alloc; + allocator->allocator.free = s_jbig2decode_free; + allocator->allocator.realloc = s_jbig2decode_realloc; + allocator->mem = mem; + /* allocate a context with which to parse our global segments */ - ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, NULL, - s_jbig2decode_error, NULL); - if (ctx == NULL) return 0; + ctx = jbig2_ctx_new((Jbig2Allocator *) allocator, JBIG2_OPTIONS_EMBEDDED, + NULL, s_jbig2decode_error, NULL); + if (ctx == NULL) { + gs_free_object(mem, allocator, "s_jbig2_make_global_data"); + return_error(gs_error_VMerror); + } /* parse the global bitstream */ code = jbig2_data_in(ctx, data, length); - if (code) { /* error parsing the global stream */ - jbig2_ctx_free(ctx); + allocator = (s_jbig2decode_allocator_t *) jbig2_ctx_free(ctx); + gs_free_object(allocator->mem, allocator, "s_jbig2_make_global_data"); *result = NULL; - return code; + return_error(gs_error_ioerror); } /* canonize and store our global state */ @@ -213,8 +252,11 @@ void s_jbig2decode_free_global_data(void *data) { Jbig2GlobalCtx *global_ctx = (Jbig2GlobalCtx*)data; + s_jbig2decode_allocator_t *allocator; + + allocator = (s_jbig2decode_allocator_t *) jbig2_global_ctx_free(global_ctx); - jbig2_global_ctx_free(global_ctx); + gs_free_object(allocator->mem, allocator, "s_jbig2decode_free_global_data"); } /* store a global ctx pointer in our state structure */ @@ -237,6 +279,7 @@ s_jbig2decode_init(stream_state * ss) stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss; Jbig2GlobalCtx *global_ctx = state->global_ctx; /* may be NULL */ int code = 0; + s_jbig2decode_allocator_t *allocator = NULL; state->callback_data = (s_jbig2_callback_data_t *)gs_alloc_bytes( ss->memory->non_gc_memory, @@ -247,9 +290,26 @@ s_jbig2decode_init(stream_state * ss) state->callback_data->error = 0; state->callback_data->last_message = NULL; state->callback_data->repeats = 0; - /* initialize the decoder with the parsed global context if any */ - state->decode_ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, - global_ctx, s_jbig2decode_error, state->callback_data); + + allocator = (s_jbig2decode_allocator_t *) gs_alloc_bytes(ss->memory->non_gc_memory, sizeof (s_jbig2decode_allocator_t), "s_jbig2decode_init(allocator)"); + if (allocator == NULL) { + s_jbig2decode_error(state->callback_data, "failed to allocate custom jbig2dec allocator", JBIG2_SEVERITY_FATAL, -1); + } + else { + allocator->allocator.alloc = s_jbig2decode_alloc; + allocator->allocator.free = s_jbig2decode_free; + allocator->allocator.realloc = s_jbig2decode_realloc; + allocator->mem = ss->memory->non_gc_memory; + + /* initialize the decoder with the parsed global context if any */ + state->decode_ctx = jbig2_ctx_new((Jbig2Allocator *) allocator, JBIG2_OPTIONS_EMBEDDED, + global_ctx, s_jbig2decode_error, state->callback_data); + + if (state->decode_ctx == NULL) { + gs_free_object(allocator->mem, allocator, "s_jbig2decode_release"); + } + + } code = state->callback_data->error; } @@ -323,11 +383,15 @@ s_jbig2decode_release(stream_state *ss) stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss; if (state->decode_ctx) { + s_jbig2decode_allocator_t *allocator = NULL; + if (state->image) jbig2_release_page(state->decode_ctx, state->image); state->image = NULL; s_jbig2decode_flush_errors(state->callback_data); - jbig2_ctx_free(state->decode_ctx); + allocator = (s_jbig2decode_allocator_t *) jbig2_ctx_free(state->decode_ctx); state->decode_ctx = NULL; + + gs_free_object(allocator->mem, allocator, "s_jbig2decode_release"); } if (state->callback_data) { gs_memory_t *mem = state->callback_data->memory; diff --git a/base/sjbig2.h b/base/sjbig2.h index 6819a0221..4c046bdbd 100644 --- a/base/sjbig2.h +++ b/base/sjbig2.h @@ -62,7 +62,7 @@ extern const stream_template s_jbig2decode_template; /* call ins to process the JBIG2Globals parameter */ int -s_jbig2decode_make_global_data(byte *data, uint length, void **result); +s_jbig2decode_make_global_data(gs_memory_t *mem, byte *data, uint length, void **result); int s_jbig2decode_set_global_data(stream_state *ss, s_jbig2_global_data_t *gd); void diff --git a/base/sjbig2_luratech.c b/base/sjbig2_luratech.c index b6b25de3f..9efabe4c7 100644 --- a/base/sjbig2_luratech.c +++ b/base/sjbig2_luratech.c @@ -55,24 +55,28 @@ private_st_jbig2decode_state(); /* our implementation of the "parsed" /JBIG2Globals filter parameter */ typedef struct s_jbig2decode_global_data_s { + gs_memory_t *mem; unsigned char *data; unsigned long size; } s_jbig2decode_global_data; /* create a global data struct and copy data into it */ int -s_jbig2decode_make_global_data(byte *data, uint size, void **result) +s_jbig2decode_make_global_data(gs_memory_t *mem, byte *data, uint size, void **result) { s_jbig2decode_global_data *global = NULL; - global = malloc(sizeof(*global)); + global = gs_alloc_bytes(mem, sizeof (*global), "s_jbig2decode_make_global_data(global)"); if (global == NULL) return_error(gs_error_VMerror); - global->data = malloc(size); + global->mem = mem; + + global->data = gs_alloc_bytes(global->mem, size, "s_jbig2decode_make_global_data(global_data)"); if (global->data == NULL) { - free(global); + gs_free_object(global->mem, global, "s_jbig2decode_make_global_data(global)"); return_error(gs_error_VMerror); } + memcpy(global->data, data, size); global->size = size; @@ -87,10 +91,11 @@ s_jbig2decode_free_global_data(void *data) s_jbig2decode_global_data *global = (s_jbig2decode_global_data*)data; if (global->size && global->data) { - free(global->data); + gs_free_object(global->mem, global->data, "s_jbig2decode_free_global_data(global_data)"); global->size = 0; } - free(global); + + gs_free_object(global->mem, global, "s_jbig2decode_free_global_data(global)"); } /* store a global ctx pointer in our state structure */ @@ -131,15 +136,16 @@ s_jbig2_invert_buffer(unsigned char *buf, int length) static void * JB2_Callback s_jbig2_alloc(unsigned long size, void *userdata) { - void *result = malloc(size); - return result; + gs_memory_t *mem = (gs_memory_t *) userdata; + return gs_alloc_bytes(mem, size, "s_jbig2_alloc"); } /* memory release */ static JB2_Error JB2_Callback s_jbig2_free(void *ptr, void *userdata) { - free(ptr); + gs_memory_t *mem = (gs_memory_t *) userdata; + gs_free_object(mem, ptr, "s_jbig2_free"); return cJB2_Error_OK; } @@ -312,8 +318,8 @@ s_jbig2decode_process(stream_state * ss, stream_cursor_read * pr, /* initialize the codec state and pass our callbacks */ error = JB2_Document_Start( &(state->doc), - s_jbig2_alloc, ss, /* alloc and its data */ - s_jbig2_free, ss, /* free and its data */ + s_jbig2_alloc, ss->memory->non_gc_memory, /* alloc and its data */ + s_jbig2_free, ss->memory->non_gc_memory, /* free and its data */ s_jbig2_read, ss, /* read callback and data */ s_jbig2_message, ss); /* message callback and data */ if (error != cJB2_Error_OK) return ERRC; @@ -404,8 +410,8 @@ s_jbig2encode_start(stream_jbig2encode_state *state) /* initialize the compression handle */ err = JB2_Compress_Start(&(state->cmp), - s_jbig2_alloc, state, /* alloc and its parameter data */ - s_jbig2_free, state, /* free callback */ + s_jbig2_alloc, state->memory, /* alloc and its parameter data */ + s_jbig2_free, state->memory, /* free callback */ s_jbig2_message, state);/* message callback */ if (err != cJB2_Error_OK) return err; diff --git a/base/sjbig2_luratech.h b/base/sjbig2_luratech.h index 367c45ad7..73725ac4a 100644 --- a/base/sjbig2_luratech.h +++ b/base/sjbig2_luratech.h @@ -54,7 +54,7 @@ extern const stream_template s_jbig2decode_template; /* call in to process the JBIG2Globals parameter */ int -s_jbig2decode_make_global_data(byte *data, uint size, void **result); +s_jbig2decode_make_global_data(gs_memory_t *mem, byte *data, uint size, void **result); int s_jbig2decode_set_global_data(stream_state *ss, s_jbig2_global_data_t *gs); void diff --git a/psi/zfjbig2.c b/psi/zfjbig2.c index 596a86f8b..2208a4183 100644 --- a/psi/zfjbig2.c +++ b/psi/zfjbig2.c @@ -104,7 +104,7 @@ z_jbig2makeglobalctx(i_ctx_t * i_ctx_p) size = gs_object_size(imemory, op->value.pstruct); data = r_ptr(op, byte); - code = s_jbig2decode_make_global_data(data, size, + code = s_jbig2decode_make_global_data(imemory->non_gc_memory, data, size, &global); if (size > 0 && global == NULL) { dmlprintf(imemory, "failed to create parsed JBIG2GLOBALS object."); |