From 2f0b62b1c02cb6826168ad73023697980b251fe6 Mon Sep 17 00:00:00 2001
From: Tor Andersson <tor.andersson@artifex.com>
Date: Thu, 29 Oct 2015 13:42:40 +0100
Subject: Fix 696303: Off-by-one error when checking for exception stack
 overflow.

---
 source/fitz/error.c | 48 ++++++++++++++++++------------------------------
 1 file changed, 18 insertions(+), 30 deletions(-)

(limited to 'source')

diff --git a/source/fitz/error.c b/source/fitz/error.c
index 6d0b831d..a34e5b79 100644
--- a/source/fitz/error.c
+++ b/source/fitz/error.c
@@ -80,47 +80,35 @@ void fz_warn(fz_context *ctx, const char *fmt, ...)
  *             catch region entered with code = 1.
  */
 
-FZ_NORETURN static void throw(fz_error_context *ex);
-
-static void throw(fz_error_context *ex)
+FZ_NORETURN static void throw(fz_context *ctx)
 {
-	if (ex->top >= 0)
+	if (ctx->error->top >= 0)
 	{
-		ex->stack[ex->top].code += 2;
-		fz_longjmp(ex->stack[ex->top].buffer, ex->stack[ex->top].code);
+		ctx->error->stack[ctx->error->top].code += 2;
+		fz_longjmp(ctx->error->stack[ctx->error->top].buffer, ctx->error->stack[ctx->error->top].code);
 	}
 	else
 	{
-		fprintf(stderr, "uncaught exception: %s\n", ex->message);
-		LOGE("uncaught exception: %s\n", ex->message);
+		fprintf(stderr, "uncaught exception: %s\n", ctx->error->message);
+		LOGE("uncaught exception: %s\n", ctx->error->message);
 #ifdef USE_OUTPUT_DEBUG_STRING
 		OutputDebugStringA("uncaught exception: ");
-		OutputDebugStringA(ex->message);
+		OutputDebugStringA(ctx->error->message);
 		OutputDebugStringA("\n");
 #endif
 		exit(EXIT_FAILURE);
 	}
 }
 
-void fz_push_try(fz_error_context *ex)
+void fz_push_try(fz_context *ctx)
 {
-	ex->top++;
-	/* Normal case, get out of here quick */
-	if (ex->top < nelem(ex->stack)-1)
-	{
-		ex->stack[ex->top].code = 0;
-		return;
-	}
-	/* We reserve the top slot on the exception stack purely to cope with
-	 * the case when we overflow. If we DO hit this, then we 'throw'
-	 * immediately. */
-	assert(ex->top == nelem(ex->stack));
-	ex->top--;
-	ex->errcode = FZ_ERROR_GENERIC;
-	strcpy(ex->message, "exception stack overflow!");
-	fprintf(stderr, "error: %s\n", ex->message);
-	LOGE("error: %s\n", ex->message);
-	throw(ex);
+	/* If we would overflow the exception stack, throw an exception instead
+	 * of entering the try block. */
+	if (ctx->error->top + 1 >= nelem(ctx->error->stack))
+		fz_throw(ctx, FZ_ERROR_GENERIC, "exception stack overflow!");
+
+	ctx->error->top++;
+	ctx->error->stack[ctx->error->top].code = 0;
 }
 
 int fz_caught(fz_context *ctx)
@@ -155,13 +143,13 @@ void fz_throw(fz_context *ctx, int code, const char *fmt, ...)
 #endif
 	}
 
-	throw(ctx->error);
+	throw(ctx);
 }
 
 void fz_rethrow(fz_context *ctx)
 {
 	assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
-	throw(ctx->error);
+	throw(ctx);
 }
 
 void fz_rethrow_message(fz_context *ctx, const char *fmt, ...)
@@ -186,7 +174,7 @@ void fz_rethrow_message(fz_context *ctx, const char *fmt, ...)
 #endif
 	}
 
-	throw(ctx->error);
+	throw(ctx);
 }
 
 void fz_rethrow_if(fz_context *ctx, int err)
-- 
cgit v1.2.3