]> granicus.if.org Git - libass/commitdiff
Add ass_realloc_array()
authorwm4 <wm4@nowhere>
Tue, 11 Nov 2014 10:44:54 +0000 (11:44 +0100)
committerwm4 <wm4@nowhere>
Tue, 11 Nov 2014 18:47:08 +0000 (19:47 +0100)
Helps with overflow and allocation failure checking.

libass/ass_utils.c
libass/ass_utils.h

index 778da8083b9d72d406fb16e0045923c1aeb622f7..efb96a67105436e25e6beb264dd40611e71b84eb 100644 (file)
@@ -89,6 +89,24 @@ void ass_aligned_free(void *ptr)
         free(*((void **)ptr - 1));
 }
 
+/**
+ * This works similar to realloc(ptr, nmemb * size), but checks for overflow.
+ *
+ * Unlike some implementations of realloc, this never acts as a call to free().
+ * If the total size is 0, it is bumped up to 1. This means a NULL return always
+ * means allocation failure, and the unportable realloc(0, 0) case is avoided.
+ */
+void *ass_realloc_array(void *ptr, size_t nmemb, size_t size)
+{
+    if (nmemb > (SIZE_MAX / size))
+        return NULL;
+    size *= nmemb;
+    if (size < 1)
+        size = 1;
+
+    return realloc(ptr, size);
+}
+
 void skip_spaces(char **str)
 {
     char *p = *str;
index 6ae732871da7d57ec44bd672e8d17ee0079cdeeb..5548a931e5abf787cf5f36b180325d0e293d2adb 100644 (file)
@@ -56,6 +56,8 @@ int has_avx2(void);
 void *ass_aligned_alloc(size_t alignment, size_t size);
 void ass_aligned_free(void *ptr);
 
+void *ass_realloc_array(void *ptr, size_t nmemb, size_t size);
+
 void skip_spaces(char **str);
 void rskip_spaces(char **str, char *limit);
 int mystrtoi(char **p, int *res);