]> git.draconx.ca Git - liblbx.git/blobdiff - src/error.c
liblbx: Properly report errors in lbx_(img_)fopen.
[liblbx.git] / src / error.c
index c32d3b6188e7afb208fb83fa24fdbe38f90292a6..3e47204c76716ea6cd075a80e3423420af77270f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  2ooM: The Master of Orion II Reverse Engineering Project
  *  Utilities for out-of-band error propagation.
- *  Copyright (C) 2010 Nick Bowler
+ *  Copyright © 2010, 2013 Nick Bowler
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -22,6 +22,8 @@
 #include <errno.h>
 #include <string.h>
 #include <assert.h>
+#include <limits.h>
+#include <inttypes.h>
 #include <libintl.h>
 
 #include "error.h"
@@ -36,16 +38,24 @@ static unsigned error_base, error_tip;
 static int error_ring[LBX_ERROR_LIMIT];
 
 static const char **user_errors;
-static unsigned user_error_count;
-static unsigned user_error_max = 2;
+static int user_error_count, user_error_max = 2;
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
 
 int lbx_error_new(const char *str)
 {
-       assert(user_error_count <= user_error_max);
+       assert(user_error_count >= 0 && user_error_count <= user_error_max);
+
        if (!user_errors || user_error_count == user_error_max) {
-               size_t size = sizeof *user_errors * user_error_max * 2;
                const char **new;
+               size_t size;
+
+               if (user_error_max >= MIN(SIZE_MAX, INT_MAX)/2 - LBX_EUBASE)
+                       return -1;
+               if (2 * user_error_max >= SIZE_MAX / sizeof *user_errors)
+                       return -1;
 
+               size = 2 * user_error_max * sizeof *user_errors;
                new = realloc(user_errors, size);
                if (!new)
                        return -1;
@@ -61,8 +71,8 @@ int lbx_error_raise(int code)
 {
        if (code == LBX_EOK) {
                return -1;
-       } else if (code >= LBX_EMAX && code < LBX_EUBASE
-                  || code >= LBX_EUBASE + user_error_count) {
+       } else if (code >= 0 && ((code >= LBX_EMAX && code < LBX_EUBASE)
+                                 || code >= LBX_EUBASE + user_error_count)) {
                fprintf(stderr, "%s: invalid error code %d\n", __func__, code);
                return -1;
        }