Coverage Report

Created: 2023-05-19 06:16

/src/ntp-dev/lib/isc/buffer.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2004-2008  Internet Systems Consortium, Inc. ("ISC")
3
 * Copyright (C) 1998-2002  Internet Software Consortium.
4
 *
5
 * Permission to use, copy, modify, and/or distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
 * PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
/* $Id: buffer.c,v 1.49 2008/09/25 04:02:39 tbox Exp $ */
19
20
/*! \file */
21
22
#include <config.h>
23
24
#include <isc/buffer.h>
25
#include <isc/mem.h>
26
#include <isc/region.h>
27
#include <isc/string.h>
28
#include <isc/util.h>
29
30
void
31
0
isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length) {
32
  /*
33
   * Make 'b' refer to the 'length'-byte region starting at 'base'.
34
   * XXXDCL see the comment in buffer.h about base being const.
35
   */
36
37
0
  REQUIRE(b != NULL);
38
39
0
  ISC__BUFFER_INIT(b, base, length);
40
0
}
41
42
void
43
0
isc__buffer_initnull(isc_buffer_t *b) {
44
  /*
45
   * Initialize a new buffer which has no backing store.  This can
46
   * later be grown as needed and swapped in place.
47
   */
48
49
0
  ISC__BUFFER_INIT(b, NULL, 0);
50
0
}
51
52
void
53
0
isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length) {
54
  /*
55
   * Re-initialize the buffer enough to reconfigure the base of the
56
   * buffer.  We will swap in the new buffer, after copying any
57
   * data we contain into the new buffer and adjusting all of our
58
   * internal pointers.
59
   *
60
   * The buffer must not be smaller than the length of the original
61
   * buffer.
62
   */
63
0
  REQUIRE(b->length <= length);
64
0
  REQUIRE(base != NULL);
65
66
0
  (void)memmove(base, b->base, b->length);
67
0
  b->base = base;
68
0
  b->length = length;
69
0
}
70
71
void
72
0
isc__buffer_invalidate(isc_buffer_t *b) {
73
  /*
74
   * Make 'b' an invalid buffer.
75
   */
76
77
0
  REQUIRE(ISC_BUFFER_VALID(b));
78
0
  REQUIRE(!ISC_LINK_LINKED(b, link));
79
0
  REQUIRE(b->mctx == NULL);
80
81
0
  ISC__BUFFER_INVALIDATE(b);
82
0
}
83
84
void
85
0
isc__buffer_region(isc_buffer_t *b, isc_region_t *r) {
86
  /*
87
   * Make 'r' refer to the region of 'b'.
88
   */
89
90
0
  REQUIRE(ISC_BUFFER_VALID(b));
91
0
  REQUIRE(r != NULL);
92
93
0
  ISC__BUFFER_REGION(b, r);
94
0
}
95
96
void
97
0
isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r) {
98
  /*
99
   * Make 'r' refer to the used region of 'b'.
100
   */
101
102
0
  REQUIRE(ISC_BUFFER_VALID(b));
103
0
  REQUIRE(r != NULL);
104
105
0
  ISC__BUFFER_USEDREGION(b, r);
106
0
}
107
108
void
109
0
isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r) {
110
  /*
111
   * Make 'r' refer to the available region of 'b'.
112
   */
113
114
0
  REQUIRE(ISC_BUFFER_VALID(b));
115
0
  REQUIRE(r != NULL);
116
117
0
  ISC__BUFFER_AVAILABLEREGION(b, r);
118
0
}
119
120
void
121
0
isc__buffer_add(isc_buffer_t *b, unsigned int n) {
122
  /*
123
   * Increase the 'used' region of 'b' by 'n' bytes.
124
   */
125
126
0
  REQUIRE(ISC_BUFFER_VALID(b));
127
0
  REQUIRE(b->used + n <= b->length);
128
129
0
  ISC__BUFFER_ADD(b, n);
130
0
}
131
132
void
133
0
isc__buffer_subtract(isc_buffer_t *b, unsigned int n) {
134
  /*
135
   * Decrease the 'used' region of 'b' by 'n' bytes.
136
   */
137
138
0
  REQUIRE(ISC_BUFFER_VALID(b));
139
0
  REQUIRE(b->used >= n);
140
141
0
  ISC__BUFFER_SUBTRACT(b, n);
142
0
}
143
144
void
145
0
isc__buffer_clear(isc_buffer_t *b) {
146
  /*
147
   * Make the used region empty.
148
   */
149
150
0
  REQUIRE(ISC_BUFFER_VALID(b));
151
152
0
  ISC__BUFFER_CLEAR(b);
153
0
}
154
155
void
156
0
isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r) {
157
  /*
158
   * Make 'r' refer to the consumed region of 'b'.
159
   */
160
161
0
  REQUIRE(ISC_BUFFER_VALID(b));
162
0
  REQUIRE(r != NULL);
163
164
0
  ISC__BUFFER_CONSUMEDREGION(b, r);
165
0
}
166
167
void
168
0
isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) {
169
  /*
170
   * Make 'r' refer to the remaining region of 'b'.
171
   */
172
173
0
  REQUIRE(ISC_BUFFER_VALID(b));
174
0
  REQUIRE(r != NULL);
175
176
0
  ISC__BUFFER_REMAININGREGION(b, r);
177
0
}
178
179
void
180
0
isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r) {
181
  /*
182
   * Make 'r' refer to the active region of 'b'.
183
   */
184
185
0
  REQUIRE(ISC_BUFFER_VALID(b));
186
0
  REQUIRE(r != NULL);
187
188
0
  ISC__BUFFER_ACTIVEREGION(b, r);
189
0
}
190
191
void
192
0
isc__buffer_setactive(isc_buffer_t *b, unsigned int n) {
193
  /*
194
   * Sets the end of the active region 'n' bytes after current.
195
   */
196
197
0
  REQUIRE(ISC_BUFFER_VALID(b));
198
0
  REQUIRE(b->current + n <= b->used);
199
200
0
  ISC__BUFFER_SETACTIVE(b, n);
201
0
}
202
203
void
204
0
isc__buffer_first(isc_buffer_t *b) {
205
  /*
206
   * Make the consumed region empty.
207
   */
208
209
0
  REQUIRE(ISC_BUFFER_VALID(b));
210
211
0
  ISC__BUFFER_FIRST(b);
212
0
}
213
214
void
215
0
isc__buffer_forward(isc_buffer_t *b, unsigned int n) {
216
  /*
217
   * Increase the 'consumed' region of 'b' by 'n' bytes.
218
   */
219
220
0
  REQUIRE(ISC_BUFFER_VALID(b));
221
0
  REQUIRE(b->current + n <= b->used);
222
223
0
  ISC__BUFFER_FORWARD(b, n);
224
0
}
225
226
void
227
0
isc__buffer_back(isc_buffer_t *b, unsigned int n) {
228
  /*
229
   * Decrease the 'consumed' region of 'b' by 'n' bytes.
230
   */
231
232
0
  REQUIRE(ISC_BUFFER_VALID(b));
233
0
  REQUIRE(n <= b->current);
234
235
0
  ISC__BUFFER_BACK(b, n);
236
0
}
237
238
void
239
0
isc_buffer_compact(isc_buffer_t *b) {
240
0
  unsigned int length;
241
0
  void *src;
242
243
  /*
244
   * Compact the used region by moving the remaining region so it occurs
245
   * at the start of the buffer.  The used region is shrunk by the size
246
   * of the consumed region, and the consumed region is then made empty.
247
   */
248
249
0
  REQUIRE(ISC_BUFFER_VALID(b));
250
251
0
  src = isc_buffer_current(b);
252
0
  length = isc_buffer_remaininglength(b);
253
0
  (void)memmove(b->base, src, (size_t)length);
254
255
0
  if (b->active > b->current)
256
0
    b->active -= b->current;
257
0
  else
258
0
    b->active = 0;
259
0
  b->current = 0;
260
0
  b->used = length;
261
0
}
262
263
isc_uint8_t
264
0
isc_buffer_getuint8(isc_buffer_t *b) {
265
0
  unsigned char *cp;
266
0
  isc_uint8_t result;
267
268
  /*
269
   * Read an unsigned 8-bit integer from 'b' and return it.
270
   */
271
272
0
  REQUIRE(ISC_BUFFER_VALID(b));
273
0
  REQUIRE(b->used - b->current >= 1);
274
275
0
  cp = isc_buffer_current(b);
276
0
  b->current += 1;
277
0
  result = ((isc_uint8_t)(cp[0]));
278
279
0
  return (result);
280
0
}
281
282
void
283
0
isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val) {
284
0
  REQUIRE(ISC_BUFFER_VALID(b));
285
0
  REQUIRE(b->used + 1 <= b->length);
286
287
0
  ISC__BUFFER_PUTUINT8(b, val);
288
0
}
289
290
isc_uint16_t
291
0
isc_buffer_getuint16(isc_buffer_t *b) {
292
0
  unsigned char *cp;
293
0
  isc_uint16_t result;
294
295
  /*
296
   * Read an unsigned 16-bit integer in network byte order from 'b',
297
   * convert it to host byte order, and return it.
298
   */
299
300
0
  REQUIRE(ISC_BUFFER_VALID(b));
301
0
  REQUIRE(b->used - b->current >= 2);
302
303
0
  cp = isc_buffer_current(b);
304
0
  b->current += 2;
305
0
  result = ((unsigned int)(cp[0])) << 8;
306
0
  result |= ((unsigned int)(cp[1]));
307
308
0
  return (result);
309
0
}
310
311
void
312
0
isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val) {
313
0
  REQUIRE(ISC_BUFFER_VALID(b));
314
0
  REQUIRE(b->used + 2 <= b->length);
315
316
0
  ISC__BUFFER_PUTUINT16(b, val);
317
0
}
318
319
void
320
0
isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val) {
321
0
  REQUIRE(ISC_BUFFER_VALID(b));
322
0
  REQUIRE(b->used + 3 <= b->length);
323
324
0
  ISC__BUFFER_PUTUINT24(b, val);
325
0
}
326
327
isc_uint32_t
328
0
isc_buffer_getuint32(isc_buffer_t *b) {
329
0
  unsigned char *cp;
330
0
  isc_uint32_t result;
331
332
  /*
333
   * Read an unsigned 32-bit integer in network byte order from 'b',
334
   * convert it to host byte order, and return it.
335
   */
336
337
0
  REQUIRE(ISC_BUFFER_VALID(b));
338
0
  REQUIRE(b->used - b->current >= 4);
339
340
0
  cp = isc_buffer_current(b);
341
0
  b->current += 4;
342
0
  result = ((unsigned int)(cp[0])) << 24;
343
0
  result |= ((unsigned int)(cp[1])) << 16;
344
0
  result |= ((unsigned int)(cp[2])) << 8;
345
0
  result |= ((unsigned int)(cp[3]));
346
347
0
  return (result);
348
0
}
349
350
void
351
0
isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) {
352
0
  REQUIRE(ISC_BUFFER_VALID(b));
353
0
  REQUIRE(b->used + 4 <= b->length);
354
355
0
  ISC__BUFFER_PUTUINT32(b, val);
356
0
}
357
358
isc_uint64_t
359
0
isc_buffer_getuint48(isc_buffer_t *b) {
360
0
  unsigned char *cp;
361
0
  isc_uint64_t result;
362
363
  /*
364
   * Read an unsigned 48-bit integer in network byte order from 'b',
365
   * convert it to host byte order, and return it.
366
   */
367
368
0
  REQUIRE(ISC_BUFFER_VALID(b));
369
0
  REQUIRE(b->used - b->current >= 6);
370
371
0
  cp = isc_buffer_current(b);
372
0
  b->current += 6;
373
0
  result = ((isc_int64_t)(cp[0])) << 40;
374
0
  result |= ((isc_int64_t)(cp[1])) << 32;
375
0
  result |= ((isc_int64_t)(cp[2])) << 24;
376
0
  result |= ((isc_int64_t)(cp[3])) << 16;
377
0
  result |= ((isc_int64_t)(cp[4])) << 8;
378
0
  result |= ((isc_int64_t)(cp[5]));
379
380
0
  return (result);
381
0
}
382
383
void
384
0
isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) {
385
0
  isc_uint16_t valhi;
386
0
  isc_uint32_t vallo;
387
388
0
  REQUIRE(ISC_BUFFER_VALID(b));
389
0
  REQUIRE(b->used + 6 <= b->length);
390
391
0
  valhi = (isc_uint16_t)(val >> 32);
392
0
  vallo = (isc_uint32_t)(val & 0xFFFFFFFF);
393
0
  ISC__BUFFER_PUTUINT16(b, valhi);
394
0
  ISC__BUFFER_PUTUINT32(b, vallo);
395
0
}
396
397
void
398
isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
399
       unsigned int length)
400
0
{
401
0
  REQUIRE(ISC_BUFFER_VALID(b));
402
0
  REQUIRE(b->used + length <= b->length);
403
404
0
  ISC__BUFFER_PUTMEM(b, base, length);
405
0
}
406
407
void
408
0
isc__buffer_putstr(isc_buffer_t *b, const char *source) {
409
0
  size_t l;
410
0
  unsigned char *cp;
411
412
0
  REQUIRE(ISC_BUFFER_VALID(b));
413
0
  REQUIRE(source != NULL);
414
415
  /*
416
   * Do not use ISC__BUFFER_PUTSTR(), so strlen is only done once.
417
   */
418
0
  l = strlen(source);
419
420
0
  REQUIRE(l <= isc_buffer_availablelength(b));
421
422
0
  cp = isc_buffer_used(b);
423
0
  memcpy(cp, source, l);
424
0
  b->used += (u_int)l; /* checked above - no overflow here */
425
0
}
426
427
isc_result_t
428
0
isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) {
429
0
  unsigned char *base;
430
0
  unsigned int available;
431
432
0
  REQUIRE(ISC_BUFFER_VALID(b));
433
0
  REQUIRE(r != NULL);
434
435
  /*
436
   * XXXDCL
437
   */
438
0
  base = isc_buffer_used(b);
439
0
  available = isc_buffer_availablelength(b);
440
0
  if (r->length > available)
441
0
    return (ISC_R_NOSPACE);
442
0
  memcpy(base, r->base, r->length);
443
0
  b->used += r->length;
444
445
0
  return (ISC_R_SUCCESS);
446
0
}
447
448
isc_result_t
449
isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
450
        unsigned int length)
451
0
{
452
0
  isc_buffer_t *dbuf;
453
454
0
  REQUIRE(dynbuffer != NULL);
455
0
  REQUIRE(*dynbuffer == NULL);
456
457
0
  dbuf = isc_mem_get(mctx, length + sizeof(isc_buffer_t));
458
0
  if (dbuf == NULL)
459
0
    return (ISC_R_NOMEMORY);
460
461
0
  isc_buffer_init(dbuf, ((unsigned char *)dbuf) + sizeof(isc_buffer_t),
462
0
      length);
463
0
  dbuf->mctx = mctx;
464
465
0
  *dynbuffer = dbuf;
466
467
0
  return (ISC_R_SUCCESS);
468
0
}
469
470
void
471
0
isc_buffer_free(isc_buffer_t **dynbuffer) {
472
0
  unsigned int real_length;
473
0
  isc_buffer_t *dbuf;
474
0
  isc_mem_t *mctx;
475
476
0
  REQUIRE(dynbuffer != NULL);
477
0
  REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
478
0
  REQUIRE((*dynbuffer)->mctx != NULL);
479
480
0
  dbuf = *dynbuffer;
481
0
  *dynbuffer = NULL;  /* destroy external reference */
482
483
0
  real_length = dbuf->length + sizeof(isc_buffer_t);
484
0
  mctx = dbuf->mctx;
485
0
  dbuf->mctx = NULL;
486
0
  isc_buffer_invalidate(dbuf);
487
488
0
  isc_mem_put(mctx, dbuf, real_length);
489
0
}