diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2017-09-06 17:03:04 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2018-10-26 15:29:11 +0200 |
commit | b3ceba9fa1d19c1004aec38b0a8870154a865ea4 (patch) | |
tree | bc94d586b4fc6af72ba347ebf1d8ef5c4fd74c61 /source | |
parent | 4f8796cafcd5c15247fb85e7febd1bb591d0a853 (diff) | |
download | mupdf-b3ceba9fa1d19c1004aec38b0a8870154a865ea4.tar.xz |
Rewrite try/always/catch macros to allow fz_context to be opaque.
Hide fz_stack_slot and exception handling details too.
Also make sure we have an initialized jmp_buf so we can safely throw from
the always block even in the exception stack overflow case.
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/error.c | 60 |
1 files changed, 34 insertions, 26 deletions
diff --git a/source/fitz/error.c b/source/fitz/error.c index fe1045dd..8f4d6f50 100644 --- a/source/fitz/error.c +++ b/source/fitz/error.c @@ -123,19 +123,17 @@ FZ_NORETURN static void throw(fz_context *ctx) } } -/* Only called when we hit the bottom of the exception stack. - * Do the same as fz_throw, but don't actually throw. */ -static int fz_fake_throw(fz_context *ctx, int code, const char *fmt, ...) +void *fz_push_try(fz_context *ctx) { - va_list args; - ctx->error->errcode = code; - va_start(args, fmt); - fz_vsnprintf(ctx->error->message, sizeof ctx->error->message, fmt, args); - ctx->error->message[sizeof(ctx->error->message) - 1] = 0; - va_end(args); - - if (code != FZ_ERROR_ABORT) + /* If we would overflow the exception stack, throw an exception instead + * of entering the try block. We assume that we always have room for + * 1 extra level on the stack here - i.e. we throw the error on us + * starting to use the last level. */ + if (ctx->error->top + 2 >= ctx->error->stack + nelem(ctx->error->stack)) { + ctx->error->errcode = FZ_ERROR_GENERIC; + fz_strlcpy(ctx->error->message, "exception stack overflow!", sizeof ctx->error->message); + fz_flush_warnings(ctx); fprintf(stderr, "error: %s\n", ctx->error->message); #ifdef USE_OUTPUT_DEBUG_STRING @@ -146,27 +144,37 @@ static int fz_fake_throw(fz_context *ctx, int code, const char *fmt, ...) #ifdef USE_ANDROID_LOG __android_log_print(ANDROID_LOG_ERROR, "libmupdf", "%s", ctx->error->message); #endif + + /* We need to arrive in the always/catch block as if throw had taken place. */ + ctx->error->top++; + ctx->error->top->code = 2; + } + else + { + ctx->error->top++; + ctx->error->top->code = 0; } + return ctx->error->top->buffer; +} - /* We need to arrive in the always/catch block as if throw - * had taken place. */ - ctx->error->top++; - ctx->error->top->code = 2; - return 0; +int fz_do_try(fz_context *ctx) +{ + return ctx->error->top->code == 0; } -int fz_push_try(fz_context *ctx) +int fz_do_always(fz_context *ctx) { - /* If we would overflow the exception stack, throw an exception instead - * of entering the try block. We assume that we always have room for - * 1 extra level on the stack here - i.e. we throw the error on us - * starting to use the last level. */ - if (ctx->error->top + 2 >= ctx->error->stack + nelem(ctx->error->stack)) - return fz_fake_throw(ctx, FZ_ERROR_GENERIC, "exception stack overflow!"); + if (ctx->error->top->code < 3) + { + ctx->error->top->code++; + return 1; + } + return 0; +} - ctx->error->top++; - ctx->error->top->code = 0; - return 1; +int fz_do_catch(fz_context *ctx) +{ + return (ctx->error->top--)->code > 1; } int fz_caught(fz_context *ctx) |