diff options
-rw-r--r-- | libass/ass_utils.c | 18 | ||||
-rw-r--r-- | libass/ass_utils.h | 2 |
2 files changed, 20 insertions, 0 deletions
diff --git a/libass/ass_utils.c b/libass/ass_utils.c index 778da80..efb96a6 100644 --- a/libass/ass_utils.c +++ b/libass/ass_utils.c @@ -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; diff --git a/libass/ass_utils.h b/libass/ass_utils.h index 6ae7328..5548a93 100644 --- a/libass/ass_utils.h +++ b/libass/ass_utils.h @@ -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); |