summaryrefslogtreecommitdiff
path: root/Build/source/libs/poppler/poppler-src/goo/gmem.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/poppler/poppler-src/goo/gmem.h')
-rw-r--r--Build/source/libs/poppler/poppler-src/goo/gmem.h184
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