diff options
Diffstat (limited to 'Build/source/libs/poppler/poppler-src/goo/gmem.h')
-rw-r--r-- | Build/source/libs/poppler/poppler-src/goo/gmem.h | 184 |
1 files changed, 136 insertions, 48 deletions
diff --git a/Build/source/libs/poppler/poppler-src/goo/gmem.h b/Build/source/libs/poppler/poppler-src/goo/gmem.h index 4c76f0fb65e..9b187c1dafc 100644 --- a/Build/source/libs/poppler/poppler-src/goo/gmem.h +++ b/Build/source/libs/poppler/poppler-src/goo/gmem.h @@ -16,6 +16,7 @@ // Copyright (C) 2005 Takashi Iwai <tiwai@suse.de> // Copyright (C) 2007-2010, 2017 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2008 Jonathan Kew <jonathan_kew@sil.org> +// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -25,68 +26,155 @@ #ifndef GMEM_H #define GMEM_H -#include <stdio.h> -#include "poppler-config.h" +#include <cstring> +#include <cstdlib> +#include <cstdio> -#ifdef __cplusplus -extern "C" { -#endif +#include "GooCheckedOps.h" -/* - * Same as malloc, but prints error message and exits if malloc() - * returns NULL. - */ -extern void *gmalloc(size_t size); -extern void *gmalloc_checkoverflow(size_t size); +/// Same as malloc, but prints error message and exits if malloc() returns NULL. +inline void *gmalloc(size_t size, bool checkoverflow = false) { + if (size == 0) { + return nullptr; + } -/* - * Same as realloc, but prints error message and exits if realloc() - * returns NULL. If <p> is NULL, calls malloc instead of realloc(). - */ -extern void *grealloc(void *p, size_t size); -extern void *grealloc_checkoverflow(void *p, size_t size); + if (void *p = std::malloc(size)) { + return p; + } + + std::fputs("Out of memory\n", stderr); + + if (checkoverflow) { + return nullptr; + } + + std::abort(); +} + +inline void *gmalloc_checkoverflow(size_t size) { + return gmalloc(size, true); +} + +/// Same as free, but checks for and ignores NULL pointers. +inline void gfree(void *p) { + if (p) { + std::free(p); + } +} + +/// Same as realloc, but prints error message and exits if realloc() returns NULL. +/// If <p> is NULL, calls malloc() instead of realloc(). +inline void *grealloc(void *p, size_t size, bool checkoverflow = false) { + if (size == 0) { + gfree(p); + return nullptr; + } + + if (void *q = p ? std::realloc(p, size) : std::malloc(size)) { + return q; + } + + std::fputs("Out of memory\n", stderr); + + if (checkoverflow) { + return nullptr; + } + + std::abort(); +} + +inline void *grealloc_checkoverflow(void *p, size_t size) { + return grealloc(p, size, true); +} /* * These are similar to gmalloc and grealloc, but take an object count - * and size. The result is similar to allocating nObjs * objSize + * and size. The result is similar to allocating <count> * <size> * bytes, but there is an additional error check that the total size * doesn't overflow an int. * The gmallocn_checkoverflow variant returns NULL instead of exiting - * the application if a overflow is detected + * the application if a overflow is detected. */ -extern void *gmallocn(int nObjs, int objSize); -extern void *gmallocn_checkoverflow(int nObjs, int objSize); -extern void *gmallocn3(int a, int b, int c); -extern void *gmallocn3_checkoverflow(int a, int b, int c); -extern void *greallocn(void *p, int nObjs, int objSize); -extern void *greallocn_checkoverflow(void *p, int nObjs, int objSize); -/* - * Same as free, but checks for and ignores NULL pointers. - */ -extern void gfree(void *p); +inline void *gmallocn(int count, int size, bool checkoverflow = false) { + if (count == 0) { + return nullptr; + } -#ifdef DEBUG_MEM -/* - * Report on unfreed memory. - */ -extern void gMemReport(FILE *f); -#else -#define gMemReport(f) -#endif + int bytes; + if (count < 0 || size <= 0 || checkedMultiply(count, size, &bytes)) { + std::fputs("Bogus memory allocation size\n", stderr); -/* - * Allocate memory and copy a string into it. - */ -extern char *copyString(const char *s); + if (checkoverflow) { + return nullptr; + } -/* - * Allocate memory and copy a limited-length string to it. - */ -extern char *gstrndup(const char *s, size_t n); + std::abort(); + } + + return gmalloc(bytes, checkoverflow); +} + +inline void *gmallocn_checkoverflow(int count, int size) { + return gmallocn(count, size, true); +} + +inline void *gmallocn3(int width, int height, int size, bool checkoverflow = false) { + if (width == 0 || height == 0) { + return nullptr; + } + + int count; + int bytes; + if (width < 0 || height < 0 || size <= 0 || checkedMultiply(width, height, &count) || checkedMultiply(count, size, &bytes)) { + std::fputs("Bogus memory allocation size\n", stderr); + + if (checkoverflow) { + return nullptr; + } + + std::abort(); + } + + return gmalloc(bytes, checkoverflow); +} + +inline void *greallocn(void *p, int count, int size, bool checkoverflow = false) { + if (count == 0) { + gfree(p); + return nullptr; + } + + int bytes; + if (count < 0 || size <= 0 || checkedMultiply(count, size, &bytes)) { + std::fputs("Bogus memory allocation size\n", stderr); + + if (checkoverflow) { + gfree(p); + return nullptr; + } + + std::abort(); + } + + return grealloc(p, bytes, checkoverflow); +} + +inline void *greallocn_checkoverflow(void *p, int count, int size) { + return greallocn(p, count, size, true); +} + +/// Allocate memory and copy a string into it. +inline char *copyString(const char *s) { + char *r = static_cast<char *>(gmalloc(std::strlen(s) + 1, false)); + return std::strcpy(r, s); +} -#ifdef __cplusplus +/// Allocate memory and copy a limited-length string to it. +inline char *copyString(const char *s, size_t n) { + char *r = static_cast<char *>(gmalloc(n + 1, false)); + r[n] = '\0'; + return std::strncpy(r, s, n); } -#endif -#endif +#endif // GMEM_H |