Coverage Report

Created: 2025-01-28 06:17

/src/mupdf/thirdparty/extract/src/alloc.c
Line
Count
Source (jump to first uncovered line)
1
#include "extract/alloc.h"
2
3
#include <assert.h>
4
#include <errno.h>
5
#include <stdlib.h>
6
#include <string.h>
7
8
9
struct extract_alloc_t
10
{
11
  extract_realloc_fn_t     *realloc_fn;
12
  extract_caller_context_t *realloc_state;
13
  size_t                    exp_min_alloc_size;
14
  extract_alloc_stats_t     stats;
15
};
16
17
int
18
extract_alloc_create( extract_realloc_fn_t *realloc_fn,
19
      void     *realloc_state,
20
      extract_alloc_t  **palloc)
21
0
{
22
0
  assert(realloc_fn);
23
0
  assert(palloc);
24
0
  *palloc = realloc_fn(realloc_state, NULL /*ptr*/, sizeof(**palloc));
25
0
  if (!*palloc) {
26
0
    errno = ENOMEM;
27
0
    return -1;
28
0
  }
29
0
  memset(*palloc, 0, sizeof(**palloc));
30
0
  (*palloc)->realloc_fn = realloc_fn;
31
0
  (*palloc)->realloc_state = realloc_state;
32
0
  (*palloc)->exp_min_alloc_size = 0;
33
0
  return 0;
34
0
}
35
36
void extract_alloc_destroy(extract_alloc_t **palloc)
37
0
{
38
0
  if (!*palloc) return;
39
0
  (*palloc)->realloc_fn((*palloc)->realloc_state, *palloc, 0 /*newsize*/);
40
0
  *palloc = NULL;
41
0
}
42
43
extract_alloc_stats_t *extract_alloc_stats(extract_alloc_t *alloc)
44
0
{
45
0
  return &alloc->stats;
46
0
}
47
48
static size_t round_up(extract_alloc_t *alloc, size_t n)
49
0
{
50
0
  size_t ret;
51
52
0
  if (alloc == NULL || alloc->exp_min_alloc_size || n == 0)
53
0
    return n;
54
55
  /* Round up to power of two. */
56
0
  ret = alloc->exp_min_alloc_size;
57
0
  while (ret < n) {
58
0
    size_t ret_old = ret;
59
0
    ret *= 2;
60
0
    if (ret <= ret_old)
61
0
      ret = n;
62
0
  }
63
64
0
  return ret;
65
0
}
66
67
int (extract_malloc)(extract_alloc_t *alloc, void **pptr, size_t size)
68
0
{
69
0
  void *p;
70
71
0
  size = round_up(alloc, size);
72
0
  p = (alloc) ? alloc->realloc_fn(alloc->realloc_state, NULL, size) : malloc(size);
73
0
  *pptr = p;
74
0
  if (!p && size)
75
0
  {
76
0
    if (alloc) errno = ENOMEM;
77
0
    return -1;
78
0
  }
79
0
  if (alloc)  alloc->stats.num_malloc += 1;
80
0
  return 0;
81
0
}
82
83
int (extract_realloc)(extract_alloc_t *alloc, void **pptr, size_t newsize)
84
0
{
85
0
  void *p = (alloc) ? alloc->realloc_fn(alloc->realloc_state, *pptr, newsize) : realloc(*pptr, newsize);
86
0
  if (!p && newsize)
87
0
  {
88
0
    if (alloc) errno = ENOMEM;
89
0
    return -1;
90
0
  }
91
0
  *pptr = p;
92
0
  if (alloc) alloc->stats.num_realloc += 1;
93
0
  return 0;
94
0
}
95
96
int (extract_realloc2)(extract_alloc_t *alloc, void **pptr, size_t oldsize, size_t newsize)
97
0
{
98
  /* We ignore <oldsize> if <ptr> is NULL - allows callers to not worry
99
  about edge cases e.g. with strlen+1. */
100
0
  oldsize = (*pptr) ? round_up(alloc, oldsize) : 0;
101
0
  newsize = round_up(alloc, newsize);
102
0
  if (newsize == oldsize) return 0;
103
0
  return (extract_realloc)(alloc, pptr, newsize);
104
0
}
105
106
void (extract_free)(extract_alloc_t *alloc, void **pptr)
107
0
{
108
0
  if (alloc)
109
0
    (void)alloc->realloc_fn(alloc->realloc_state, *pptr, 0);
110
0
  else
111
0
    free(*pptr);
112
0
  *pptr = NULL;
113
0
  if (alloc) alloc->stats.num_free += 1;
114
0
}
115
116
void extract_alloc_exp_min(extract_alloc_t *alloc, size_t size)
117
0
{
118
0
  alloc->exp_min_alloc_size = size;
119
0
}