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
Line 
1/*
2 * gmem.c
3 *
4 * Memory routines with out-of-memory checking.
5 *
6 * Copyright 1996-2003 Glyph & Cog, LLC
7 */
8
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>
17// Copyright (C) 2007-2009 Albert Astals Cid <aacid@kde.org>
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
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 {
36  unsigned int magic;
37  int size;
38  int index;
39  struct _GMemHdr *next, *prev;
40} GMemHdr;
41
42#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
43#define gMemTrlSize (sizeof(long))
44
45#define gMemMagic 0xabcd9999
46
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
57static GMemHdr *gMemHead = NULL;
58static GMemHdr *gMemTail = NULL;
59
60static int gMemIndex = 0;
61static int gMemAlloc = 0;
62static int gMemInUse = 0;
63
64#endif /* DEBUG_MEM */
65
66inline static void *gmalloc(size_t size, bool checkoverflow) GMEM_EXCEP {
67#ifdef DEBUG_MEM
68  int size1;
69  char *mem;
70  GMemHdr *hdr;
71  void *data;
72  unsigned long *trl, *p;
73
74  if (size <= 0) {
75    return NULL;
76  }
77  size1 = gMemDataSize(size);
78  if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
79#if USE_EXCEPTIONS
80    throw GMemException();
81#else
82    fprintf(stderr, "Out of memory\n");
83    if (checkoverflow) return NULL;
84    else exit(1);
85#endif
86  }
87  hdr = (GMemHdr *)mem;
88  data = (void *)(mem + gMemHdrSize);
89  trl = (unsigned long *)(mem + gMemHdrSize + size1);
90  hdr->magic = gMemMagic;
91  hdr->size = size;
92  hdr->index = gMemIndex++;
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;
102  ++gMemAlloc;
103  gMemInUse += size;
104  for (p = (unsigned long *)data; p <= trl; ++p) {
105    *p = gMemDeadVal;
106  }
107  return data;
108#else
109  void *p;
110
111  if (size <= 0) {
112    return NULL;
113  }
114  if (!(p = malloc(size))) {
115#if USE_EXCEPTIONS
116    throw GMemException();
117#else
118    fprintf(stderr, "Out of memory\n");
119    if (checkoverflow) return NULL;
120    else exit(1);
121#endif
122  }
123  return p;
124#endif
125}
126
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 {
136#ifdef DEBUG_MEM
137  GMemHdr *hdr;
138  void *q;
139  int oldSize;
140
141  if (size <= 0) {
142    if (p) {
143      gfree(p);
144    }
145    return NULL;
146  }
147  if (p) {
148    hdr = (GMemHdr *)((char *)p - gMemHdrSize);
149    oldSize = hdr->size;
150    q = gmalloc(size, checkoverflow);
151    memcpy(q, p, size < oldSize ? size : oldSize);
152    gfree(p);
153  } else {
154    q = gmalloc(size, checkoverflow);
155  }
156  return q;
157#else
158  void *q;
159
160  if (size <= 0) {
161    if (p) {
162      free(p);
163    }
164    return NULL;
165  }
166  if (p) {
167    q = realloc(p, size);
168  } else {
169    q = malloc(size);
170  }
171  if (!q) {
172#if USE_EXCEPTIONS
173    throw GMemException();
174#else
175    fprintf(stderr, "Out of memory\n");
176    if (checkoverflow) return NULL;
177    else exit(1);
178#endif
179  }
180  return q;
181#endif
182}
183
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 {
193  int n;
194
195  if (nObjs == 0) {
196    return NULL;
197  }
198  n = nObjs * objSize;
199  if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
200#if USE_EXCEPTIONS
201    throw GMemException();
202#else
203    fprintf(stderr, "Bogus memory allocation size\n");
204    if (checkoverflow) return NULL;
205    else exit(1);
206#endif
207  }
208  return gmalloc(n, checkoverflow);
209}
210
211void *gmallocn(int nObjs, int objSize) GMEM_EXCEP {
212  return gmallocn(nObjs, objSize, false);
213}
214
215void *gmallocn_checkoverflow(int nObjs, int objSize) GMEM_EXCEP {
216  return gmallocn(nObjs, objSize, true);
217}
218
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) {
222#if USE_EXCEPTIONS
223    throw GMemException();
224#else
225    fprintf(stderr, "Bogus memory allocation size\n");
226    if (checkoverflow) return NULL;
227    else exit(1);
228#endif
229  }
230  return gmallocn(n, c, checkoverflow);
231}
232
233void *gmallocn3(int a, int b, int c) GMEM_EXCEP {
234  return gmallocn3(a, b, c, false);
235}
236
237void *gmallocn3_checkoverflow(int a, int b, int c) GMEM_EXCEP {
238  return gmallocn3(a, b, c, true);
239}
240
241inline static void *greallocn(void *p, int nObjs, int objSize, bool checkoverflow) GMEM_EXCEP {
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");
256    if (checkoverflow) return NULL;
257    else exit(1);
258#endif
259  }
260  return grealloc(p, n, checkoverflow);
261}
262
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
271void gfree(void *p) {
272#ifdef DEBUG_MEM
273  int size;
274  GMemHdr *hdr;
275  unsigned long *trl, *clr;
276
277  if (p) {
278    hdr = (GMemHdr *)((char *)p - gMemHdrSize);
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      }
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      }
300      for (clr = (unsigned long *)hdr; clr <= trl; ++clr) {
301        *clr = gMemDeadVal;
302      }
303      free(hdr);
304    } else {
305      fprintf(stderr, "Attempted to free bad address %p\n", p);
306    }
307  }
308#else
309  if (p) {
310    free(p);
311  }
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");
324    for (p = gMemHead; p; p = p->next) {
325      fprintf(f, "%8d %8d\n", p->index, p->size);
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}
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.