diff options
-rw-r--r-- | apps/pdfclean.c | 2 | ||||
-rw-r--r-- | apps/pdfdraw.c | 2 | ||||
-rw-r--r-- | apps/pdfextract.c | 2 | ||||
-rw-r--r-- | apps/pdfshow.c | 2 | ||||
-rw-r--r-- | apps/win_main.c | 2 | ||||
-rw-r--r-- | apps/xpsdraw.c | 2 | ||||
-rw-r--r-- | fitz/base_context.c | 18 | ||||
-rw-r--r-- | fitz/base_memory.c | 135 | ||||
-rw-r--r-- | fitz/fitz.h | 16 | ||||
-rw-r--r-- | scripts/cmapdump.c | 2 |
10 files changed, 139 insertions, 44 deletions
diff --git a/apps/pdfclean.c b/apps/pdfclean.c index 4b76afa2..c77139ff 100644 --- a/apps/pdfclean.c +++ b/apps/pdfclean.c @@ -739,7 +739,7 @@ int main(int argc, char **argv) if (argc - fz_optind > 0) subset = 1; - ctx = fz_new_context(); + ctx = fz_new_context(&fz_alloc_default); if (ctx == NULL) die(fz_error_note(1, "failed to initialise context")); diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c index af21b9ea..790c7eaa 100644 --- a/apps/pdfdraw.c +++ b/apps/pdfdraw.c @@ -352,7 +352,7 @@ int main(int argc, char **argv) if (accelerate) fz_accelerate(); - ctx = fz_new_context(); + ctx = fz_new_context(&fz_alloc_default); if (ctx == NULL) { fprintf(stderr, "Failed to init context\n"); diff --git a/apps/pdfextract.c b/apps/pdfextract.c index 5aa5fa09..bf0a74ed 100644 --- a/apps/pdfextract.c +++ b/apps/pdfextract.c @@ -207,7 +207,7 @@ int main(int argc, char **argv) infile = argv[fz_optind++]; - ctx = fz_new_context(); + ctx = fz_new_context(&fz_alloc_default); if (ctx == NULL) die(fz_error_note(1, "failed to initialise context")); diff --git a/apps/pdfshow.c b/apps/pdfshow.c index 21c3a8e1..fee20d2f 100644 --- a/apps/pdfshow.c +++ b/apps/pdfshow.c @@ -229,7 +229,7 @@ int main(int argc, char **argv) filename = argv[fz_optind++]; - ctx = fz_new_context(); + ctx = fz_new_context(&fz_alloc_default); if (ctx == NULL) die(fz_error_note(1, "failed to initialise context")); diff --git a/apps/win_main.c b/apps/win_main.c index a77347e4..3e293957 100644 --- a/apps/win_main.c +++ b/apps/win_main.c @@ -858,7 +858,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShow fz_accelerate(); - ctx = fz_new_context(/*&fz_alloc_default*/); + ctx = fz_new_context(&fz_alloc_default); if (ctx == NULL) { fprintf(stderr, "Failed to init context"); diff --git a/apps/xpsdraw.c b/apps/xpsdraw.c index 19cf600a..c91e8702 100644 --- a/apps/xpsdraw.c +++ b/apps/xpsdraw.c @@ -314,7 +314,7 @@ int main(int argc, char **argv) if (accelerate) fz_accelerate(); - ctx = fz_new_context(); + ctx = fz_new_context(&fz_alloc_default); if (ctx == NULL) { fprintf(stderr, "failed to initialise context"); diff --git a/fitz/base_context.c b/fitz/base_context.c index 66811cf9..c64d09e7 100644 --- a/fitz/base_context.c +++ b/fitz/base_context.c @@ -11,37 +11,39 @@ fz_obj *(*fz_resolve_indirect)(fz_obj*) = fz_resolve_indirect_null; void fz_free_context(fz_context *ctx) { - assert(ctx != NULL); + if (ctx == NULL) + return; /* Other finalisation calls go here (in reverse order) */ if (ctx->error) { assert(ctx->error->top == -1); - free(ctx->error); + fz_free(ctx, ctx->error); } /* Free the context itself */ - free(ctx); + ctx->alloc->free(ctx->alloc->user, ctx); } fz_context * -fz_new_context(void) +fz_new_context(fz_alloc_context *alloc) { fz_context *ctx; - ctx = malloc(sizeof(fz_context)); + ctx = alloc->malloc(alloc->user, sizeof(fz_context)); if (!ctx) return NULL; memset(ctx, 0, sizeof *ctx); + ctx->alloc = alloc; - ctx->error = malloc(sizeof(fz_error_context)); + ctx->error = fz_malloc_no_throw(ctx, sizeof(fz_error_context)); if (!ctx->error) goto cleanup; ctx->error->top = -1; ctx->error->message[0] = 0; - ctx->warn = malloc(sizeof(fz_warn_context)); + ctx->warn = fz_malloc_no_throw(ctx, sizeof(fz_warn_context)); if (!ctx->warn) goto cleanup; ctx->warn->message[0] = 0; @@ -60,5 +62,5 @@ cleanup: fz_context * fz_clone_context(fz_context *ctx) { - return fz_new_context(); + return fz_new_context(ctx->alloc); } diff --git a/fitz/base_memory.c b/fitz/base_memory.c index cf972542..43ec0dd9 100644 --- a/fitz/base_memory.c +++ b/fitz/base_memory.c @@ -3,16 +3,19 @@ void * fz_malloc(fz_context *ctx, unsigned int size) { - void *p = malloc(size); - if (!p) - { - fprintf(stderr, "fatal error: out of memory\n"); - abort(); - } + void *p = ctx->alloc->malloc(ctx->alloc->user, size); + if (p == NULL) + fz_throw(ctx, "malloc of %d bytes failed", size); return p; } void * +fz_malloc_no_throw(fz_context *ctx, unsigned int size) +{ + return ctx->alloc->malloc(ctx->alloc->user, size); +} + +void * fz_malloc_array(fz_context *ctx, unsigned int count, unsigned int size) { void *p; @@ -21,22 +24,53 @@ fz_malloc_array(fz_context *ctx, unsigned int count, unsigned int size) return 0; if (count > UINT_MAX / size) + fz_throw(ctx, "malloc of array (%d x %d bytes) failed (integer overflow)", count, size); + + p = ctx->alloc->malloc(ctx->alloc->user, count * size); + if (p == NULL) + fz_throw(ctx, "malloc of array (%d x %d bytes) failed", count, size); + return p; +} + +void * +fz_malloc_array_no_throw(fz_context *ctx, unsigned int count, unsigned int size) +{ + if (count == 0 || size == 0) + return 0; + + if (count > UINT_MAX / size) { - fprintf(stderr, "fatal error: out of memory (integer overflow)\n"); - abort(); + fprintf(stderr, "error: malloc of array (%d x %d bytes) failed (integer overflow)", count, size); + return NULL; } - p = malloc(count * size); - if (!p) + return ctx->alloc->malloc(ctx->alloc->user, count * size); +} + +void * +fz_calloc(fz_context *ctx, unsigned int count, unsigned int size) +{ + void *p; + + if (count == 0 || size == 0) + return 0; + + if (count > UINT_MAX / size) { - fprintf(stderr, "fatal error: out of memory\n"); - abort(); + fz_throw(ctx, "calloc (%d x %d bytes) failed (integer overflow)", count, size); } + + p = ctx->alloc->malloc(ctx->alloc->user, count * size); + if (p == NULL) + { + fz_throw(ctx, "calloc (%d x %d bytes) failed", count, size); + } + memset(p, 0, count*size); return p; } void * -fz_calloc(fz_context *ctx, unsigned int count, unsigned int size) +fz_calloc_no_throw(fz_context *ctx, unsigned int count, unsigned int size) { void *p; @@ -45,15 +79,14 @@ fz_calloc(fz_context *ctx, unsigned int count, unsigned int size) if (count > UINT_MAX / size) { - fprintf(stderr, "fatal error: out of memory (integer overflow)\n"); - abort(); + fprintf(stderr, "error: calloc (%d x %d bytes) failed (integer overflow)\n", count, size); + return NULL; } - p = calloc(count, size); - if (!p) + p = ctx->alloc->malloc(ctx->alloc->user, count * size); + if (p != NULL) { - fprintf(stderr, "fatal error: out of memory\n"); - abort(); + memset(p, 0, count*size); } return p; } @@ -70,24 +103,36 @@ fz_resize_array(fz_context *ctx, void *p, unsigned int count, unsigned int size) } if (count > UINT_MAX / size) + fz_throw(ctx, "resize array (%d x %d bytes) failed (integer overflow)", count, size); + + np = ctx->alloc->realloc(ctx->alloc->user, p, count * size); + if (np == NULL) + fz_throw(ctx, "resize array (%d x %d bytes) failed", count, size); + return np; +} + +void * +fz_resize_array_no_throw(fz_context *ctx, void *p, unsigned int count, unsigned int size) +{ + if (count == 0 || size == 0) { - fprintf(stderr, "fatal error: out of memory (integer overflow)\n"); - abort(); + fz_free(ctx, p); + return 0; } - np = realloc(p, count * size); - if (np == NULL) + if (count > UINT_MAX / size) { - fprintf(stderr, "fatal error: out of memory\n"); - abort(); + fprintf(stderr, "error: resize array (%d x %d bytes) failed (integer overflow)\n", count, size); + return NULL; } - return np; + + return ctx->alloc->realloc(ctx->alloc->user, p, count * size); } void fz_free(fz_context *ctx, void *p) { - free(p); + ctx->alloc->free(ctx->alloc->user, p); } char * @@ -98,3 +143,39 @@ fz_strdup(fz_context *ctx, char *s) memcpy(ns, s, len); return ns; } + +char * +fz_strdup_no_throw(fz_context *ctx, char *s) +{ + int len = strlen(s) + 1; + char *ns = fz_malloc_no_throw(ctx, len); + if (ns != NULL) + memcpy(ns, s, len); + return ns; +} + +static void * +fz_malloc_default(void *opaque, unsigned int size) +{ + return malloc(size); +} + +static void * +fz_realloc_default(void *opaque, void *old, unsigned int size) +{ + return realloc(old, size); +} + +static void +fz_free_default(void *opaque, void *ptr) +{ + free(ptr); +} + +fz_alloc_context fz_alloc_default = +{ + NULL, + fz_malloc_default, + fz_realloc_default, + fz_free_default +} ;
\ No newline at end of file diff --git a/fitz/fitz.h b/fitz/fitz.h index aa9ff222..83eade3b 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -145,9 +145,12 @@ struct fz_alloc_context_s void *user; void *(*malloc)(void *, unsigned int); void *(*realloc)(void *, void *, unsigned int); - void *(*free)(void *, void *, unsigned int); + void (*free)(void *, void *); }; +/* Default allocator */ +extern fz_alloc_context fz_alloc_default; + struct fz_error_context_s { int top; @@ -185,11 +188,12 @@ void fz_flush_warnings(fz_context *ctx); struct fz_context_s { + fz_alloc_context *alloc; fz_error_context *error; fz_warn_context *warn; }; -fz_context *fz_new_context(void); +fz_context *fz_new_context(fz_alloc_context *alloc); fz_context *fz_clone_context(fz_context *ctx); void fz_free_context(fz_context *ctx); @@ -208,6 +212,14 @@ char *fz_strdup(fz_context *ctx, char *s); void fz_free(fz_context *ctx, void *p); +/* The following returns NULL on failure to allocate */ +void *fz_malloc_no_throw(fz_context *ctx, unsigned int size); +void *fz_malloc_array_no_throw(fz_context *ctx, unsigned int count, unsigned int size); +void *fz_calloc_no_throw(fz_context *ctx, unsigned int count, unsigned int size); +void *fz_resize_array_no_throw(fz_context *ctx, void *p, unsigned int count, unsigned int size); +char *fz_strdup_no_throw(fz_context *ctx, char *s); + + /* runtime (hah!) test for endian-ness */ int fz_is_big_endian(void); diff --git a/scripts/cmapdump.c b/scripts/cmapdump.c index 7f031b5f..9827fff5 100644 --- a/scripts/cmapdump.c +++ b/scripts/cmapdump.c @@ -50,7 +50,7 @@ main(int argc, char **argv) return 1; } - ctx = fz_new_context(); + ctx = fz_new_context(&fz_alloc_default); if (ctx == NULL) { fprintf(stderr, "failed to initialise!\n"); |