source: trunk/poppler/mypoppler/goo/gmem.cc @ 277

Last change on this file since 277 was 277, checked in by rbri, 12 years ago

PDF plugin: Poppler library updated to version 0.12.3

File size: 7.5 KB
RevLine 
[2]1/*
2 * gmem.c
3 *
4 * Memory routines with out-of-memory checking.
5 *
6 * Copyright 1996-2003 Glyph & Cog, LLC
7 */
8
[257]9//========================================================================
10//
11// Modified under the Poppler project - http://poppler.freedesktop.org
12//
13// All changes made under the Poppler project to this file are licensed
14// under GPL version 2 or later
15//
16// Copyright (C) 2005 Takashi Iwai <tiwai@suse.de>
[277]17// Copyright (C) 2007-2009 Albert Astals Cid <aacid@kde.org>
[257]18// Copyright (C) 2008 Jonathan Kew <jonathan_kew@sil.org>
19//
20// To see a description of the changes please see the Changelog file that
21// came with your tarball or type make ChangeLog if you are building from git
22//
23//========================================================================
24
[2]25#include <config.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <stddef.h>
29#include <string.h>
30#include <limits.h>
31#include "gmem.h"
32
33#ifdef DEBUG_MEM
34
35typedef struct _GMemHdr {
[250]36  unsigned int magic;
[2]37  int size;
38  int index;
[250]39  struct _GMemHdr *next, *prev;
[2]40} GMemHdr;
41
42#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
43#define gMemTrlSize (sizeof(long))
44
[250]45#define gMemMagic 0xabcd9999
46
[2]47#if gmemTrlSize==8
48#define gMemDeadVal 0xdeadbeefdeadbeefUL
49#else
50#define gMemDeadVal 0xdeadbeefUL
51#endif
52
53/* round data size so trailer will be aligned */
54#define gMemDataSize(size) \
55  ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
56
[250]57static GMemHdr *gMemHead = NULL;
58static GMemHdr *gMemTail = NULL;
[2]59
60static int gMemIndex = 0;
61static int gMemAlloc = 0;
62static int gMemInUse = 0;
63
64#endif /* DEBUG_MEM */
65
[277]66inline static void *gmalloc(size_t size, bool checkoverflow) GMEM_EXCEP {
[2]67#ifdef DEBUG_MEM
[250]68  int size1;
[2]69  char *mem;
70  GMemHdr *hdr;
71  void *data;
72  unsigned long *trl, *p;
73
[250]74  if (size <= 0) {
[2]75    return NULL;
[250]76  }
[2]77  size1 = gMemDataSize(size);
78  if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
[250]79#if USE_EXCEPTIONS
80    throw GMemException();
81#else
[2]82    fprintf(stderr, "Out of memory\n");
[277]83    if (checkoverflow) return NULL;
84    else exit(1);
[250]85#endif
[2]86  }
87  hdr = (GMemHdr *)mem;
88  data = (void *)(mem + gMemHdrSize);
89  trl = (unsigned long *)(mem + gMemHdrSize + size1);
[250]90  hdr->magic = gMemMagic;
[2]91  hdr->size = size;
92  hdr->index = gMemIndex++;
[250]93  if (gMemTail) {
94    gMemTail->next = hdr;
95    hdr->prev = gMemTail;
96    gMemTail = hdr;
97  } else {
98    hdr->prev = NULL;
99    gMemHead = gMemTail = hdr;
100  }
101  hdr->next = NULL;
[2]102  ++gMemAlloc;
103  gMemInUse += size;
[250]104  for (p = (unsigned long *)data; p <= trl; ++p) {
[2]105    *p = gMemDeadVal;
[250]106  }
[2]107  return data;
108#else
109  void *p;
110
[250]111  if (size <= 0) {
[2]112    return NULL;
[250]113  }
[2]114  if (!(p = malloc(size))) {
[250]115#if USE_EXCEPTIONS
116    throw GMemException();
117#else
[2]118    fprintf(stderr, "Out of memory\n");
[277]119    if (checkoverflow) return NULL;
120    else exit(1);
[250]121#endif
[2]122  }
123  return p;
124#endif
125}
126
[277]127void *gmalloc(size_t size) GMEM_EXCEP {
128  return gmalloc(size, false);
129}
130
131void *gmalloc_checkoverflow(size_t size) GMEM_EXCEP {
132  return gmalloc(size, true);
133}
134
135inline static void *grealloc(void *p, size_t size, bool checkoverflow) GMEM_EXCEP {
[2]136#ifdef DEBUG_MEM
137  GMemHdr *hdr;
138  void *q;
[250]139  int oldSize;
[2]140
141  if (size <= 0) {
[250]142    if (p) {
[2]143      gfree(p);
[250]144    }
[2]145    return NULL;
146  }
147  if (p) {
148    hdr = (GMemHdr *)((char *)p - gMemHdrSize);
149    oldSize = hdr->size;
[277]150    q = gmalloc(size, checkoverflow);
[2]151    memcpy(q, p, size < oldSize ? size : oldSize);
152    gfree(p);
153  } else {
[277]154    q = gmalloc(size, checkoverflow);
[2]155  }
156  return q;
157#else
158  void *q;
159
160  if (size <= 0) {
[250]161    if (p) {
[2]162      free(p);
[250]163    }
[2]164    return NULL;
165  }
[250]166  if (p) {
[2]167    q = realloc(p, size);
[250]168  } else {
[2]169    q = malloc(size);
[250]170  }
[2]171  if (!q) {
[250]172#if USE_EXCEPTIONS
173    throw GMemException();
174#else
[2]175    fprintf(stderr, "Out of memory\n");
[277]176    if (checkoverflow) return NULL;
177    else exit(1);
[250]178#endif
[2]179  }
180  return q;
181#endif
182}
183
[277]184void *grealloc(void *p, size_t size) GMEM_EXCEP {
185  return grealloc(p, size, false);
186}
187
188void *grealloc_checkoverflow(void *p, size_t size) GMEM_EXCEP {
189  return grealloc(p, size, true);
190}
191
192inline static void *gmallocn(int nObjs, int objSize, bool checkoverflow) GMEM_EXCEP {
[2]193  int n;
194
[250]195  if (nObjs == 0) {
196    return NULL;
197  }
[2]198  n = nObjs * objSize;
[250]199  if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
200#if USE_EXCEPTIONS
201    throw GMemException();
202#else
[2]203    fprintf(stderr, "Bogus memory allocation size\n");
[277]204    if (checkoverflow) return NULL;
205    else exit(1);
[250]206#endif
[2]207  }
[277]208  return gmalloc(n, checkoverflow);
[2]209}
210
[277]211void *gmallocn(int nObjs, int objSize) GMEM_EXCEP {
212  return gmallocn(nObjs, objSize, false);
213}
214
[250]215void *gmallocn_checkoverflow(int nObjs, int objSize) GMEM_EXCEP {
[277]216  return gmallocn(nObjs, objSize, true);
217}
[2]218
[277]219inline static void *gmallocn3(int a, int b, int c, bool checkoverflow) GMEM_EXCEP {
220  int n = a * b;
221  if (b <= 0 || a < 0 || a >= INT_MAX / b) {
[250]222#if USE_EXCEPTIONS
223    throw GMemException();
224#else
[2]225    fprintf(stderr, "Bogus memory allocation size\n");
[277]226    if (checkoverflow) return NULL;
227    else exit(1);
[250]228#endif
229  }
[277]230  return gmallocn(n, c, checkoverflow);
[250]231}
232
[277]233void *gmallocn3(int a, int b, int c) GMEM_EXCEP {
234  return gmallocn3(a, b, c, false);
235}
[250]236
[277]237void *gmallocn3_checkoverflow(int a, int b, int c) GMEM_EXCEP {
238  return gmallocn3(a, b, c, true);
[2]239}
240
[277]241inline static void *greallocn(void *p, int nObjs, int objSize, bool checkoverflow) GMEM_EXCEP {
[257]242  int n;
243
244  if (nObjs == 0) {
245    if (p) {
246      gfree(p);
247    }
248    return NULL;
249  }
250  n = nObjs * objSize;
251  if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
252#if USE_EXCEPTIONS
253    throw GMemException();
254#else
255    fprintf(stderr, "Bogus memory allocation size\n");
[277]256    if (checkoverflow) return NULL;
257    else exit(1);
[257]258#endif
259  }
[277]260  return grealloc(p, n, checkoverflow);
[257]261}
262
[277]263void *greallocn(void *p, int nObjs, int objSize) GMEM_EXCEP {
264  return greallocn(p, nObjs, objSize, false);
265}
266
267void *greallocn_checkoverflow(void *p, int nObjs, int objSize) GMEM_EXCEP {
268  return greallocn(p, nObjs, objSize, true);
269}
270
[2]271void gfree(void *p) {
272#ifdef DEBUG_MEM
[250]273  int size;
[2]274  GMemHdr *hdr;
275  unsigned long *trl, *clr;
276
277  if (p) {
278    hdr = (GMemHdr *)((char *)p - gMemHdrSize);
[250]279    if (hdr->magic == gMemMagic &&
280        ((hdr->prev == NULL) == (hdr == gMemHead)) &&
281        ((hdr->next == NULL) == (hdr == gMemTail))) {
282      if (hdr->prev) {
283        hdr->prev->next = hdr->next;
284      } else {
285        gMemHead = hdr->next;
286      }
287      if (hdr->next) {
288        hdr->next->prev = hdr->prev;
289      } else {
290        gMemTail = hdr->prev;
291      }
[2]292      --gMemAlloc;
293      gMemInUse -= hdr->size;
294      size = gMemDataSize(hdr->size);
295      trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
296      if (*trl != gMemDeadVal) {
297        fprintf(stderr, "Overwrite past end of block %d at address %p\n",
298                hdr->index, p);
299      }
[250]300      for (clr = (unsigned long *)hdr; clr <= trl; ++clr) {
[2]301        *clr = gMemDeadVal;
[250]302      }
[2]303      free(hdr);
304    } else {
305      fprintf(stderr, "Attempted to free bad address %p\n", p);
306    }
307  }
308#else
[250]309  if (p) {
[2]310    free(p);
[250]311  }
[2]312#endif
313}
314
315#ifdef DEBUG_MEM
316void gMemReport(FILE *f) {
317  GMemHdr *p;
318
319  fprintf(f, "%d memory allocations in all\n", gMemIndex);
320  if (gMemAlloc > 0) {
321    fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
322    fprintf(f, " index     size\n");
323    fprintf(f, "-------- --------\n");
[250]324    for (p = gMemHead; p; p = p->next) {
325      fprintf(f, "%8d %8d\n", p->index, p->size);
[2]326    }
327  } else {
328    fprintf(f, "No memory blocks left allocated\n");
329  }
330}
331#endif
332
333char *copyString(char *s) {
334  char *s1;
335
336  s1 = (char *)gmalloc(strlen(s) + 1);
337  strcpy(s1, s);
338  return s1;
339}
[250]340
341char *gstrndup(const char *s, size_t n) {
342  char *s1 = (char*)gmalloc(n + 1); /* cannot return NULL for size > 0 */
343  s1[n] = '\0';
344  memcpy(s1, s, n);
345  return s1;
346}
Note: See TracBrowser for help on using the repository browser.