Coverage Report

Created: 2026-08-31 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libgit2/deps/reftable/basics.c
Line
Count
Source
1
/*
2
 * Copyright 2020 Google LLC
3
 *
4
 * Use of this source code is governed by a BSD-style
5
 * license that can be found in the LICENSE file or at
6
 * https://developers.google.com/open-source/licenses/bsd
7
 */
8
9
#define REFTABLE_ALLOW_BANNED_ALLOCATORS
10
#include "basics.h"
11
#include "reftable-basics.h"
12
#include "reftable-error.h"
13
14
static void *(*reftable_malloc_ptr)(size_t sz);
15
static void *(*reftable_realloc_ptr)(void *, size_t);
16
static void (*reftable_free_ptr)(void *);
17
18
void *reftable_malloc(size_t sz)
19
0
{
20
0
  if (!sz)
21
0
    return NULL;
22
0
  if (reftable_malloc_ptr)
23
0
    return (*reftable_malloc_ptr)(sz);
24
0
  return malloc(sz);
25
0
}
26
27
void *reftable_realloc(void *p, size_t sz)
28
0
{
29
0
  if (!sz) {
30
0
    reftable_free(p);
31
0
    return NULL;
32
0
  }
33
34
0
  if (reftable_realloc_ptr)
35
0
    return (*reftable_realloc_ptr)(p, sz);
36
0
  return realloc(p, sz);
37
0
}
38
39
void reftable_free(void *p)
40
0
{
41
0
  if (reftable_free_ptr)
42
0
    reftable_free_ptr(p);
43
0
  else
44
0
    free(p);
45
0
}
46
47
void *reftable_calloc(size_t nelem, size_t elsize)
48
0
{
49
0
  void *p;
50
51
0
  if (nelem && elsize > SIZE_MAX / nelem)
52
0
    return NULL;
53
54
0
  p = reftable_malloc(nelem * elsize);
55
0
  if (!p)
56
0
    return NULL;
57
58
0
  memset(p, 0, nelem * elsize);
59
0
  return p;
60
0
}
61
62
char *reftable_strdup(const char *str)
63
0
{
64
0
  size_t len = strlen(str);
65
0
  char *result = reftable_malloc(len + 1);
66
0
  if (!result)
67
0
    return NULL;
68
0
  memcpy(result, str, len + 1);
69
0
  return result;
70
0
}
71
72
void reftable_set_alloc(void *(*malloc)(size_t),
73
      void *(*realloc)(void *, size_t), void (*free)(void *))
74
2
{
75
2
  reftable_malloc_ptr = malloc;
76
2
  reftable_realloc_ptr = realloc;
77
2
  reftable_free_ptr = free;
78
2
}
79
80
void reftable_buf_init(struct reftable_buf *buf)
81
0
{
82
0
  struct reftable_buf empty = REFTABLE_BUF_INIT;
83
0
  *buf = empty;
84
0
}
85
86
void reftable_buf_release(struct reftable_buf *buf)
87
0
{
88
0
  reftable_free(buf->buf);
89
0
  reftable_buf_init(buf);
90
0
}
91
92
void reftable_buf_reset(struct reftable_buf *buf)
93
0
{
94
0
  if (buf->alloc) {
95
0
    buf->len = 0;
96
0
    buf->buf[0] = '\0';
97
0
  }
98
0
}
99
100
int reftable_buf_setlen(struct reftable_buf *buf, size_t len)
101
0
{
102
0
  if (len > buf->len)
103
0
    return -1;
104
0
  if (len == buf->len)
105
0
    return 0;
106
0
  buf->buf[len] = '\0';
107
0
  buf->len = len;
108
0
  return 0;
109
0
}
110
111
int reftable_buf_cmp(const struct reftable_buf *a, const struct reftable_buf *b)
112
0
{
113
0
  size_t len = a->len < b->len ? a->len : b->len;
114
0
  if (len) {
115
0
    int cmp = memcmp(a->buf, b->buf, len);
116
0
    if (cmp)
117
0
      return cmp;
118
0
  }
119
0
  return a->len < b->len ? -1 : a->len != b->len;
120
0
}
121
122
int reftable_buf_add(struct reftable_buf *buf, const void *data, size_t len)
123
0
{
124
0
  size_t newlen = buf->len + len;
125
126
0
  if (newlen + 1 > buf->alloc) {
127
0
    if (REFTABLE_ALLOC_GROW(buf->buf, newlen + 1, buf->alloc))
128
0
      return REFTABLE_OUT_OF_MEMORY_ERROR;
129
0
  }
130
131
0
  memcpy(buf->buf + buf->len, data, len);
132
0
  buf->buf[newlen] = '\0';
133
0
  buf->len = newlen;
134
135
0
  return 0;
136
0
}
137
138
int reftable_buf_addstr(struct reftable_buf *buf, const char *s)
139
0
{
140
0
  return reftable_buf_add(buf, s, strlen(s));
141
0
}
142
143
char *reftable_buf_detach(struct reftable_buf *buf)
144
0
{
145
0
  char *result = buf->buf;
146
0
  reftable_buf_init(buf);
147
0
  return result;
148
0
}
149
150
size_t binsearch(size_t sz, int (*f)(size_t k, void *args), void *args)
151
0
{
152
0
  size_t lo = 0;
153
0
  size_t hi = sz;
154
155
0
  if (!sz)
156
0
    return 0;
157
158
  /* Invariants:
159
   *
160
   *  (hi == sz) || f(hi) == true
161
   *  (lo == 0 && f(0) == true) || fi(lo) == false
162
   */
163
0
  while (hi - lo > 1) {
164
0
    size_t mid = lo + (hi - lo) / 2;
165
0
    int ret = f(mid, args);
166
0
    if (ret < 0)
167
0
      return sz;
168
169
0
    if (ret > 0)
170
0
      hi = mid;
171
0
    else
172
0
      lo = mid;
173
0
  }
174
175
0
  if (lo)
176
0
    return hi;
177
178
0
  return f(0, args) ? 0 : 1;
179
0
}
180
181
void free_names(char **a)
182
0
{
183
0
  char **p;
184
0
  if (!a) {
185
0
    return;
186
0
  }
187
0
  for (p = a; *p; p++) {
188
0
    reftable_free(*p);
189
0
  }
190
0
  reftable_free(a);
191
0
}
192
193
size_t names_length(const char **names)
194
0
{
195
0
  const char **p = names;
196
0
  while (*p)
197
0
    p++;
198
0
  return p - names;
199
0
}
200
201
int parse_names(char *buf, int size, char ***out)
202
0
{
203
0
  char **names = NULL;
204
0
  size_t names_cap = 0;
205
0
  size_t names_len = 0;
206
0
  char *p = buf;
207
0
  char *end = buf + size;
208
0
  int err = 0;
209
210
0
  while (p < end) {
211
0
    char *next = strchr(p, '\n');
212
0
    if (!next) {
213
0
      err = REFTABLE_FORMAT_ERROR;
214
0
      goto done;
215
0
    } else if (next < end) {
216
0
      *next = '\0';
217
0
    } else {
218
0
      next = end;
219
0
    }
220
221
0
    if (p < next) {
222
0
      if (REFTABLE_ALLOC_GROW(names, names_len + 1,
223
0
            names_cap)) {
224
0
        err = REFTABLE_OUT_OF_MEMORY_ERROR;
225
0
        goto done;
226
0
      }
227
228
0
      names[names_len] = reftable_strdup(p);
229
0
      if (!names[names_len++]) {
230
0
        err = REFTABLE_OUT_OF_MEMORY_ERROR;
231
0
        goto done;
232
0
      }
233
0
    }
234
0
    p = next + 1;
235
0
  }
236
237
0
  if (REFTABLE_ALLOC_GROW(names, names_len + 1, names_cap)) {
238
0
    err = REFTABLE_OUT_OF_MEMORY_ERROR;
239
0
    goto done;
240
0
  }
241
0
  names[names_len] = NULL;
242
243
0
  *out = names;
244
0
  return 0;
245
0
done:
246
0
  for (size_t i = 0; i < names_len; i++)
247
0
    reftable_free(names[i]);
248
0
  reftable_free(names);
249
0
  return err;
250
0
}
251
252
int names_equal(const char **a, const char **b)
253
0
{
254
0
  size_t i = 0;
255
0
  for (; a[i] && b[i]; i++)
256
0
    if (strcmp(a[i], b[i]))
257
0
      return 0;
258
0
  return a[i] == b[i];
259
0
}
260
261
size_t common_prefix_size(struct reftable_buf *a, struct reftable_buf *b)
262
0
{
263
0
  size_t p = 0;
264
0
  for (; p < a->len && p < b->len; p++)
265
0
    if (a->buf[p] != b->buf[p])
266
0
      break;
267
0
  return p;
268
0
}
269
270
uint32_t hash_size(enum reftable_hash id)
271
0
{
272
0
  if (!id)
273
0
    return REFTABLE_HASH_SIZE_SHA1;
274
0
  switch (id) {
275
0
  case REFTABLE_HASH_SHA1:
276
0
    return REFTABLE_HASH_SIZE_SHA1;
277
0
  case REFTABLE_HASH_SHA256:
278
0
    return REFTABLE_HASH_SIZE_SHA256;
279
0
  }
280
0
  abort();
281
0
}