Coverage Report

Created: 2023-09-25 06:30

/src/xpdf-4.04/goo/gmem.cc
Line
Count
Source (jump to first uncovered 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
#include <aconf.h>
10
#include <stdio.h>
11
#include <stdlib.h>
12
#include <stddef.h>
13
// older compilers won't define SIZE_MAX in stdint.h without this
14
#ifndef __STDC_LIMIT_MACROS
15
#  define __STDC_LIMIT_MACROS 1
16
#endif
17
#include <stdint.h>
18
#include <string.h>
19
#include <limits.h>
20
#if MULTITHREADED && defined(_WIN32)
21
#  include <windows.h>
22
#endif
23
#include "gmem.h"
24
25
#ifdef DEBUG_MEM
26
27
typedef struct _GMemHdr {
28
  unsigned int magic;
29
  int index;
30
  size_t size;
31
  struct _GMemHdr *next, *prev;
32
} GMemHdr;
33
34
#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
35
#define gMemTrlSize (sizeof(long))
36
37
#define gMemMagic 0xabcd9999
38
39
#if ULONG_MAX > 0xffffffffL
40
#define gMemDeadVal 0xdeadbeefdeadbeefUL
41
#else
42
#define gMemDeadVal 0xdeadbeefUL
43
#endif
44
45
/* round data size so trailer will be aligned */
46
#define gMemDataSize(size) \
47
  (int)(((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize))
48
49
#define gMemDataSize64(size) \
50
  (size_t)(((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize))
51
52
static GMemHdr *gMemHead = NULL;
53
static GMemHdr *gMemTail = NULL;
54
55
static int gMemIndex = 0;
56
static int gMemAlloc = 0;
57
static size_t gMemInUse = 0;
58
static size_t gMaxMemInUse = 0;
59
60
#if MULTITHREADED
61
#  ifdef _WIN32
62
     static CRITICAL_SECTION gMemMutex;
63
     static INIT_ONCE gMemMutexInitStruct = INIT_ONCE_STATIC_INIT;
64
     static BOOL CALLBACK gMemMutexInitFunc(PINIT_ONCE initOnce, PVOID param,
65
              PVOID *context) {
66
       InitializeCriticalSection(&gMemMutex);
67
       return TRUE;
68
     }
69
#    define gMemInitMutex InitOnceExecuteOnce(&gMemMutexInitStruct, \
70
                                              &gMemMutexInitFunc, NULL, NULL)
71
#    define gMemLock EnterCriticalSection(&gMemMutex);
72
#    define gMemUnlock LeaveCriticalSection(&gMemMutex);
73
#  else
74
#    include <pthread.h>
75
     static pthread_mutex_t gMemMutex = PTHREAD_MUTEX_INITIALIZER;
76
#    define gMemInitMutex
77
#    define gMemLock pthread_mutex_lock(&gMemMutex)
78
#    define gMemUnlock pthread_mutex_unlock(&gMemMutex)
79
#  endif
80
#else
81
#  define gMemInitMutex
82
#  define gMemLock
83
#  define gMemUnlock
84
#endif
85
86
#endif /* DEBUG_MEM */
87
88
#ifdef DEBUG_MEM
89
void *gmalloc(int size, int ignore) GMEM_EXCEP {
90
  int size1;
91
  char *mem;
92
  GMemHdr *hdr;
93
  void *data;
94
  unsigned long *trl, *p;
95
96
  gMemInitMutex;
97
  if (size < 0) {
98
    gMemError("Invalid memory allocation size");
99
  }
100
  if (size == 0) {
101
    return NULL;
102
  }
103
  size1 = gMemDataSize(size);
104
  if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
105
    gMemError("Out of memory");
106
  }
107
  hdr = (GMemHdr *)mem;
108
  data = (void *)(mem + gMemHdrSize);
109
  trl = (unsigned long *)(mem + gMemHdrSize + size1);
110
  hdr->magic = gMemMagic;
111
  hdr->size = size;
112
  gMemLock;
113
  if (ignore) {
114
    hdr->index = -1;
115
  } else {
116
    hdr->index = gMemIndex++;
117
  }
118
  if (gMemTail) {
119
    gMemTail->next = hdr;
120
    hdr->prev = gMemTail;
121
    gMemTail = hdr;
122
  } else {
123
    hdr->prev = NULL;
124
    gMemHead = gMemTail = hdr;
125
  }
126
  hdr->next = NULL;
127
  ++gMemAlloc;
128
  gMemInUse += size;
129
  if (gMemInUse > gMaxMemInUse) {
130
    gMaxMemInUse = gMemInUse;
131
  }
132
  gMemUnlock;
133
  for (p = (unsigned long *)data; p <= trl; ++p) {
134
    *p = gMemDeadVal;
135
  }
136
  return data;
137
}
138
#else
139
1.19M
void *gmalloc(int size) GMEM_EXCEP {
140
1.19M
  void *p;
141
142
1.19M
  if (size < 0) {
143
0
    gMemError("Invalid memory allocation size");
144
0
  }
145
1.19M
  if (size == 0) {
146
0
    return NULL;
147
0
  }
148
1.19M
  if (!(p = malloc(size))) {
149
0
    gMemError("Out of memory");
150
0
  }
151
1.19M
  return p;
152
1.19M
}
153
#endif
154
155
0
void *grealloc(void *p, int size) GMEM_EXCEP {
156
#ifdef DEBUG_MEM
157
  GMemHdr *hdr;
158
  void *q;
159
  int oldSize;
160
161
  if (size < 0) {
162
    gMemError("Invalid memory allocation size");
163
  }
164
  if (size == 0) {
165
    if (p) {
166
      gfree(p);
167
    }
168
    return NULL;
169
  }
170
  if (p) {
171
    hdr = (GMemHdr *)((char *)p - gMemHdrSize);
172
    oldSize = (int)hdr->size;
173
    q = gmalloc(size);
174
    memcpy(q, p, size < oldSize ? size : oldSize);
175
    gfree(p);
176
  } else {
177
    q = gmalloc(size);
178
  }
179
  return q;
180
#else
181
0
  void *q;
182
183
0
  if (size < 0) {
184
0
    gMemError("Invalid memory allocation size");
185
0
  }
186
0
  if (size == 0) {
187
0
    if (p) {
188
0
      free(p);
189
0
    }
190
0
    return NULL;
191
0
  }
192
0
  if (p) {
193
0
    q = realloc(p, size);
194
0
  } else {
195
0
    q = malloc(size);
196
0
  }
197
0
  if (!q) {
198
0
    gMemError("Out of memory");
199
0
  }
200
0
  return q;
201
0
#endif
202
0
}
203
204
1.19M
void *gmallocn(int nObjs, int objSize) GMEM_EXCEP {
205
1.19M
  int n;
206
207
1.19M
  if (nObjs == 0) {
208
0
    return NULL;
209
0
  }
210
1.19M
  n = nObjs * objSize;
211
1.19M
  if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
212
0
    gMemError("Bogus memory allocation size");
213
0
  }
214
1.19M
  return gmalloc(n);
215
1.19M
}
216
217
#ifdef DEBUG_MEM
218
void *gmalloc64(size_t size, int ignore) GMEM_EXCEP {
219
  size_t size1;
220
  char *mem;
221
  GMemHdr *hdr;
222
  void *data;
223
  unsigned long *trl, *p;
224
225
  gMemInitMutex;
226
  if (size == 0) {
227
    return NULL;
228
  }
229
  size1 = gMemDataSize64(size);
230
  if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
231
    gMemError("Out of memory");
232
  }
233
  hdr = (GMemHdr *)mem;
234
  data = (void *)(mem + gMemHdrSize);
235
  trl = (unsigned long *)(mem + gMemHdrSize + size1);
236
  hdr->magic = gMemMagic;
237
  hdr->size = size;
238
  gMemLock;
239
  if (ignore) {
240
    hdr->index = -1;
241
  } else {
242
    hdr->index = gMemIndex++;
243
  }
244
  if (gMemTail) {
245
    gMemTail->next = hdr;
246
    hdr->prev = gMemTail;
247
    gMemTail = hdr;
248
  } else {
249
    hdr->prev = NULL;
250
    gMemHead = gMemTail = hdr;
251
  }
252
  hdr->next = NULL;
253
  ++gMemAlloc;
254
  gMemInUse += size;
255
  if (gMemInUse > gMaxMemInUse) {
256
    gMaxMemInUse = gMemInUse;
257
  }
258
  gMemUnlock;
259
  for (p = (unsigned long *)data; p <= trl; ++p) {
260
    *p = gMemDeadVal;
261
  }
262
  return data;
263
}
264
#else
265
0
void *gmalloc64(size_t size) GMEM_EXCEP {
266
0
  void *p;
267
268
0
  if (size == 0) {
269
0
    return NULL;
270
0
  }
271
0
  if (!(p = malloc(size))) {
272
0
    gMemError("Out of memory");
273
0
  }
274
0
  return p;
275
0
}
276
#endif
277
278
0
void *gmallocn64(int nObjs, size_t objSize) GMEM_EXCEP {
279
0
  size_t n;
280
281
0
  if (nObjs == 0) {
282
0
    return NULL;
283
0
  }
284
0
  n = nObjs * objSize;
285
0
  if (nObjs < 0 || (size_t)nObjs >= SIZE_MAX / objSize) {
286
0
    gMemError("Bogus memory allocation size");
287
0
  }
288
0
  return gmalloc64(n);
289
0
}
290
291
0
void *greallocn(void *p, int nObjs, int objSize) GMEM_EXCEP {
292
0
  int n;
293
294
0
  if (nObjs == 0) {
295
0
    if (p) {
296
0
      gfree(p);
297
0
    }
298
0
    return NULL;
299
0
  }
300
0
  n = nObjs * objSize;
301
0
  if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
302
0
    gMemError("Bogus memory allocation size");
303
0
  }
304
0
  return grealloc(p, n);
305
0
}
306
307
1.19M
void gfree(void *p) {
308
#ifdef DEBUG_MEM
309
  size_t size;
310
  GMemHdr *hdr;
311
  unsigned long *trl, *clr;
312
313
  if (p) {
314
    hdr = (GMemHdr *)((char *)p - gMemHdrSize);
315
    gMemLock;
316
    if (hdr->magic == gMemMagic &&
317
  ((hdr->prev == NULL) == (hdr == gMemHead)) &&
318
  ((hdr->next == NULL) == (hdr == gMemTail))) {
319
      if (hdr->prev) {
320
  hdr->prev->next = hdr->next;
321
      } else {
322
  gMemHead = hdr->next;
323
      }
324
      if (hdr->next) {
325
  hdr->next->prev = hdr->prev;
326
      } else {
327
  gMemTail = hdr->prev;
328
      }
329
      --gMemAlloc;
330
      gMemInUse -= hdr->size;
331
      gMemUnlock;
332
      size = gMemDataSize64(hdr->size);
333
      trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
334
      if (*trl != gMemDeadVal) {
335
  fprintf(stderr, "Overwrite past end of block %d at address %p\n",
336
    hdr->index, p);
337
      }
338
      for (clr = (unsigned long *)hdr; clr <= trl; ++clr) {
339
  *clr = gMemDeadVal;
340
      }
341
      free(hdr);
342
    } else {
343
      gMemUnlock;
344
      fprintf(stderr, "Attempted to free bad address %p\n", p);
345
    }
346
  }
347
#else
348
1.19M
  if (p) {
349
1.19M
    free(p);
350
1.19M
  }
351
1.19M
#endif
352
1.19M
}
353
354
0
void gMemError(const char *msg) GMEM_EXCEP {
355
0
#if USE_EXCEPTIONS
356
0
  throw GMemException();
357
#else
358
  fprintf(stderr, "%s\n", msg);
359
  exit(1);
360
#endif
361
0
}
362
363
#ifdef DEBUG_MEM
364
void gMemReport(FILE *f) {
365
  GMemHdr *p;
366
  int left;
367
368
  fprintf(f, "%d memory allocations in all\n", gMemIndex);
369
  fprintf(f, "maximum memory in use: %zd bytes\n", gMaxMemInUse);
370
  left = 0;
371
  if (gMemAlloc > 0) {
372
    for (p = gMemHead; p; p = p->next) {
373
      if (p->index >= 0) {
374
  if (!left) {
375
    fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
376
    fprintf(f, " index     size\n");
377
    fprintf(f, "-------- --------\n");
378
    left = 1;
379
  }
380
  fprintf(f, "%8d %8zd\n", p->index, p->size);
381
      }
382
    }
383
  }
384
  if (!left) {
385
    fprintf(f, "No memory blocks left allocated\n");
386
  }
387
}
388
#endif
389
390
0
char *copyString(const char *s) {
391
0
  char *s1;
392
393
0
  s1 = (char *)gmalloc((int)strlen(s) + 1);
394
0
  strcpy(s1, s);
395
0
  return s1;
396
0
}