OpenVPN
buffer.h
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2026 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
31
32#ifndef BUFFER_H
33#define BUFFER_H
34
35#include "basic.h"
36#include "error.h"
37#include "integer.h"
38
40#define BUF_SIZE_MAX 1000000
41
42/*
43 * Define verify_align function, otherwise
44 * it will be a noop.
45 */
46/* #define VERIFY_ALIGNMENT */
47
48/*
49 * Keep track of source file/line of buf_init calls
50 */
51#ifdef VERIFY_ALIGNMENT
52#define BUF_INIT_TRACKING
53#endif
54
55/**************************************************************************/
70struct buffer
71{
74 int offset;
76 int len;
78 uint8_t *data;
79
80#ifdef BUF_INIT_TRACKING
81 const char *debug_file;
82 int debug_line;
83#endif
84};
85
86
87/**************************************************************************/
98{
99 struct gc_entry *next;
101};
102
109{
111 void (*free_fnc)(void *);
112 void *addr;
113};
114
115
127{
128 struct gc_entry *list;
135};
136
137
139#define BPTR(buf) (buf_bptr(buf))
141#define CBPTR(buf) (buf_cbptr(buf))
143#define BEND(buf) (buf_bend(buf))
145#define CBEND(buf) (buf_cbend(buf))
147#define BLAST(buf) (buf_blast(buf))
149#define CBLAST(buf) (buf_cblast(buf))
151#define BLEN(buf) (buf_len(buf))
153#define BLENZ(buf) ((size_t)buf_len(buf))
155#define BDEF(buf) (buf_defined(buf))
157#define BSTR(buf) (buf_str(buf))
159#define CBSTR(buf) (buf_cstr(buf))
161#define BCAP(buf) (buf_forward_capacity(buf))
162
171void buf_clear(struct buffer *buf);
172
180void free_buf(struct buffer *buf);
181
193bool buf_assign(struct buffer *dest, const struct buffer *src);
194
202void string_clear(char *str);
203
211int string_array_len(const char **array);
212
226size_t array_mult_safe(const size_t m1, const size_t m2, const size_t extra);
227
229#define PA_BRACKET (1 << 0)
239char *print_argv(const char **p, struct gc_arena *gc, const unsigned int flags);
240
249void buf_size_error(const size_t size);
250
261struct buffer alloc_buf(size_t size);
262
275struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc);
276
287struct buffer clone_buf(const struct buffer *buf);
288
302void *gc_malloc(size_t size, bool clear, struct gc_arena *a);
303
314char *string_alloc(const char *str, struct gc_arena *gc);
315
329struct buffer string_alloc_buf(const char *str, struct gc_arena *gc);
330
343void gc_addspecial(void *addr, void (*free_function)(void *), struct gc_arena *a);
344
356void *gc_realloc(void *ptr, size_t size, struct gc_arena *a);
357
358#ifdef BUF_INIT_TRACKING
359#define buf_init(buf, offset) buf_init_debug(buf, offset, __FILE__, __LINE__)
361bool buf_init_debug(struct buffer *buf, int offset, const char *file, int line);
362
363#else
364#define buf_init(buf, offset) buf_init_dowork(buf, offset)
365#endif
366
367
368/* inline functions */
369
376static inline void
378{
379 freeaddrinfo((struct addrinfo *)addr);
380}
381
383static inline struct buffer
385{
386 return (struct buffer){ 0 };
387}
388
398static inline bool
399buf_defined(const struct buffer *buf)
400{
401 return likely(buf != NULL) && buf->data != NULL;
402}
403
413static inline bool
414buf_valid(const struct buffer *buf)
415{
416 return likely(buf != NULL) && likely(buf->data != NULL) && likely(buf->len >= 0);
417}
418
427static inline const uint8_t *
428buf_cbptr(const struct buffer *buf)
429{
430 if (buf_valid(buf))
431 {
432 return buf->data + buf->offset;
433 }
434 else
435 {
436 return NULL;
437 }
438}
439
448static inline uint8_t *
449buf_bptr(struct buffer *buf)
450{
451 return (uint8_t *)buf_cbptr(buf);
452}
453
461static int
462buf_len(const struct buffer *buf)
463{
464 if (buf_valid(buf))
465 {
466 return buf->len;
467 }
468 else
469 {
470 return 0;
471 }
472}
473
481static inline uint8_t *
482buf_bend(struct buffer *buf)
483{
484 return buf_bptr(buf) + buf_len(buf);
485}
486
494static inline const uint8_t *
495buf_cbend(const struct buffer *buf)
496{
497 return buf_cbptr(buf) + buf_len(buf);
498}
499
508static inline const uint8_t *
509buf_cblast(const struct buffer *buf)
510{
511 if (buf_len(buf) > 0)
512 {
513 return buf_cbptr(buf) + buf_len(buf) - 1;
514 }
515 else
516 {
517 return NULL;
518 }
519}
520
529static inline uint8_t *
530buf_blast(struct buffer *buf)
531{
532 return (uint8_t *)buf_cblast(buf);
533}
534
542static inline bool
543buf_size_valid(const size_t size)
544{
545 return likely(size < BUF_SIZE_MAX);
546}
547
558static inline bool
560{
561 return likely(size >= -BUF_SIZE_MAX) && likely(size < BUF_SIZE_MAX);
562}
563
571static inline char *
572buf_str(struct buffer *buf)
573{
574 return (char *)buf_bptr(buf);
575}
576
584static inline const char *
585buf_cstr(const struct buffer *buf)
586{
587 return (const char *)buf_cbptr(buf);
588}
589
598static inline void
599buf_reset(struct buffer *buf)
600{
601 buf->capacity = 0;
602 buf->offset = 0;
603 buf->len = 0;
604 buf->data = NULL;
605}
606
615static inline void
617{
618 buf->len = 0;
619 buf->offset = 0;
620}
621
634static inline bool
635buf_init_dowork(struct buffer *buf, int offset)
636{
637 if (offset < 0 || offset > buf->capacity || buf->data == NULL)
638 {
639 return false;
640 }
641 buf->len = 0;
642 buf->offset = offset;
643 return true;
644}
645
657static inline void
658buf_set_write(struct buffer *buf, uint8_t *data, int size)
659{
660 if (!buf_size_valid(size))
661 {
662 buf_size_error(size);
663 }
664 buf->len = 0;
665 buf->offset = 0;
666 buf->capacity = size;
667 buf->data = data;
668 if (size > 0 && data)
669 {
670 *data = 0;
671 }
672}
673
686static inline void
687buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
688{
689 if (!buf_size_valid(size))
690 {
691 buf_size_error(size);
692 }
693 buf->len = buf->capacity = (int)size;
694 buf->offset = 0;
695 buf->data = (uint8_t *)data;
696}
697
709static inline void
710strncpynt(char *dest, const char *src, size_t maxlen)
711{
712 if (maxlen > 0)
713 {
714 strncpy(dest, src, maxlen - 1);
715 dest[maxlen - 1] = 0;
716 }
717}
718
726static inline bool
727has_digit(const char *src)
728{
729 char c;
730 while ((c = *src++))
731 {
732 if (isdigit(c))
733 {
734 return true;
735 }
736 }
737 return false;
738}
739
768static inline void
769secure_memzero(void *data, size_t len)
770{
771#if defined(_WIN32)
772 SecureZeroMemory(data, len);
773#elif defined(__GNUC__) || defined(__clang__)
774 memset(data, 0, len);
775 __asm__ __volatile__("" : : "r"(data) : "memory");
776#else
777 volatile char *p = (volatile char *)data;
778 while (len--)
779 {
780 *p++ = 0;
781 }
782#endif
783}
784
800bool buf_printf(struct buffer *buf, const char *format, ...)
801#ifdef __GNUC__
802#if __USE_MINGW_ANSI_STDIO
803 __attribute__((format(gnu_printf, 2, 3)))
804#else
805 __attribute__((format(__printf__, 2, 3)))
806#endif
807#endif
808 ;
809
818bool buf_puts(struct buffer *buf, const char *str);
819
820
821/*
822 * remove/add trailing characters
823 */
824
835void buf_null_terminate(struct buffer *buf);
836
842void buf_chomp(struct buffer *buf);
843
850void buf_rmtail(struct buffer *buf, uint8_t remove);
851
856
862void chomp(char *str);
863
870void rm_trailing_chars(char *str, const char *what_to_delete);
871
880const char *skip_leading_whitespace(const char *str);
881
892#ifdef _WIN32
893void string_null_terminate(char *str, int len, int capacity);
894#endif
896/* End of string utility functions */
897
906bool buffer_write_file(const char *filename, const struct buffer *buf);
907
920void buf_catrunc(struct buffer *buf, const char *str);
921
939bool buf_parse(struct buffer *buf, const int delim, char *line, const int size);
940
945
948#define FHE_SPACE_BREAK_MASK 0xFF
950#define FHE_CAPS 0x100
967char *format_hex_ex(const uint8_t *data, size_t size, size_t maxoutput, unsigned int space_break_flags,
968 const char *separator, struct gc_arena *gc);
969
982static inline char *
983format_hex(const uint8_t *data, size_t size, size_t maxoutput, struct gc_arena *gc)
984{
985 return format_hex_ex(data, size, maxoutput, 4, " ", gc);
986}
987
988/* End of Hex Dump */
989
1005struct buffer buf_sub(struct buffer *buf, int size, bool prepend);
1006
1016static inline bool
1017buf_safe(const struct buffer *buf, size_t len)
1018{
1019 return buf_valid(buf) && buf_size_valid(len)
1020 && buf->offset + buf->len + (int)len <= buf->capacity;
1021}
1022
1035static inline bool
1036buf_safe_bidir(const struct buffer *buf, int len)
1037{
1038 if (buf_valid(buf) && buf_size_valid_signed(len))
1039 {
1040 int newlen = buf->len + len;
1041 return newlen >= 0 && buf->offset + newlen <= buf->capacity;
1042 }
1043 else
1044 {
1045 return false;
1046 }
1047}
1048
1060static inline int
1062{
1063 if (buf_valid(buf))
1064 {
1065 int ret = buf->capacity - (buf->offset + buf->len);
1066 if (ret < 0)
1067 {
1068 ret = 0;
1069 }
1070 return ret;
1071 }
1072 else
1073 {
1074 return 0;
1075 }
1076}
1077
1089static inline int
1091{
1092 if (buf_valid(buf))
1093 {
1094 int ret = buf->capacity - buf->offset;
1095 if (ret < 0)
1096 {
1097 ret = 0;
1098 }
1099 return ret;
1100 }
1101 else
1102 {
1103 return 0;
1104 }
1105}
1106
1117static inline int
1119{
1120 if (buf_valid(buf))
1121 {
1122 return buf->offset;
1123 }
1124 else
1125 {
1126 return 0;
1127 }
1128}
1129
1141static inline bool
1142buf_inc_len(struct buffer *buf, int inc)
1143{
1144 if (!buf_safe_bidir(buf, inc))
1145 {
1146 return false;
1147 }
1148 buf->len += inc;
1149 return true;
1150}
1151
1164static inline uint8_t *
1165buf_prepend(struct buffer *buf, ssize_t size)
1166{
1167 if (!buf_valid(buf) || size < 0 || size > buf->offset)
1168 {
1169 return NULL;
1170 }
1171 buf->offset -= (int)size;
1172 buf->len += (int)size;
1173 return BPTR(buf);
1174}
1175
1187static inline bool
1188buf_advance(struct buffer *buf, ssize_t size)
1189{
1190 if (!buf_valid(buf) || size < 0 || buf->len < size)
1191 {
1192 return false;
1193 }
1194 buf->offset += (int)size;
1195 buf->len -= (int)size;
1196 return true;
1197}
1198
1211static inline uint8_t *
1212buf_write_alloc(struct buffer *buf, size_t size)
1213{
1214 uint8_t *ret;
1215 if (!buf_safe(buf, size))
1216 {
1217 return NULL;
1218 }
1219 ret = BPTR(buf) + buf->len;
1220 buf->len += (int)size;
1221 return ret;
1222}
1223
1236static inline uint8_t *
1237buf_read_alloc(struct buffer *buf, int size)
1238{
1239 uint8_t *ret;
1240 if (size < 0 || buf->len < size)
1241 {
1242 return NULL;
1243 }
1244 ret = BPTR(buf);
1245 buf->offset += size;
1246 buf->len -= size;
1247 return ret;
1248}
1249
1261static inline bool
1262buf_write(struct buffer *dest, const void *src, size_t size)
1263{
1264 uint8_t *cp = buf_write_alloc(dest, size);
1265 if (!cp)
1266 {
1267 return false;
1268 }
1269 memcpy(cp, src, size);
1270 return true;
1271}
1272
1285static inline bool
1286buf_write_prepend(struct buffer *dest, const void *src, int size)
1287{
1288 uint8_t *cp = buf_prepend(dest, size);
1289 if (!cp)
1290 {
1291 return false;
1292 }
1293 memcpy(cp, src, size);
1294 return true;
1295}
1296
1305static inline bool
1306buf_write_u8(struct buffer *dest, uint8_t data)
1307{
1308 return buf_write(dest, &data, sizeof(uint8_t));
1309}
1310
1319static inline bool
1320buf_write_u16(struct buffer *dest, uint16_t data)
1321{
1322 uint16_t u16 = htons(data);
1323 return buf_write(dest, &u16, sizeof(uint16_t));
1324}
1325
1334static inline bool
1335buf_write_u32(struct buffer *dest, uint32_t data)
1336{
1337 uint32_t u32 = htonl(data);
1338 return buf_write(dest, &u32, sizeof(uint32_t));
1339}
1340
1349static inline bool
1350buf_write_u64(struct buffer *dest, uint64_t data)
1351{
1352 uint64_t u64 = htonll(data);
1353 return buf_write(dest, &u64, sizeof(uint64_t));
1354}
1355
1364static inline bool
1365buf_copy(struct buffer *dest, const struct buffer *src)
1366{
1367 return buf_write(dest, CBPTR(src), BLENZ(src));
1368}
1369
1382static inline bool
1383buf_copy_n(struct buffer *dest, struct buffer *src, int n)
1384{
1385 const uint8_t *cp = buf_read_alloc(src, n);
1386 if (!cp)
1387 {
1388 return false;
1389 }
1390 return buf_write(dest, cp, n);
1391}
1392
1409static inline bool
1410buf_copy_range(struct buffer *dest, int dest_index, const struct buffer *src, int src_index,
1411 int src_len)
1412{
1413 if (src_index < 0 || src_len < 0 || src_index + src_len > src->len || dest_index < 0
1414 || dest->offset + dest_index + src_len > dest->capacity)
1415 {
1416 return false;
1417 }
1418 memcpy(dest->data + dest->offset + dest_index, src->data + src->offset + src_index, src_len);
1419 if (dest_index + src_len > dest->len)
1420 {
1421 dest->len = dest_index + src_len;
1422 }
1423 return true;
1424}
1425
1439static inline bool
1440buf_copy_excess(struct buffer *dest, struct buffer *src, int len)
1441{
1442 if (len < 0)
1443 {
1444 return false;
1445 }
1446 if (src->len > len)
1447 {
1448 struct buffer b = *src;
1449 src->len = len;
1450 if (!buf_advance(&b, len))
1451 {
1452 return false;
1453 }
1454 return buf_copy(dest, &b);
1455 }
1456 else
1457 {
1458 return true;
1459 }
1460}
1461
1473static inline bool
1474buf_read(struct buffer *src, void *dest, int size)
1475{
1476 const uint8_t *cp = buf_read_alloc(src, size);
1477 if (!cp)
1478 {
1479 return false;
1480 }
1481 memcpy(dest, cp, size);
1482 return true;
1483}
1484
1493static inline int
1494buf_peek_u8(const struct buffer *buf)
1495{
1496 int ret;
1497 if (BLEN(buf) < 1)
1498 {
1499 return -1;
1500 }
1501 ret = *CBPTR(buf);
1502 return ret;
1503}
1504
1512static inline int
1514{
1515 int ret = buf_peek_u8(buf);
1516 if (ret >= 0)
1517 {
1518 buf_advance(buf, 1);
1519 }
1520 return ret;
1521}
1522
1533static inline int
1535{
1536 uint16_t ret;
1537 if (!buf_read(buf, &ret, sizeof(uint16_t)))
1538 {
1539 return -1;
1540 }
1541 return ntohs(ret);
1542}
1543
1555static inline uint32_t
1556buf_read_u32(struct buffer *buf, bool *good)
1557{
1558 uint32_t ret;
1559 if (!buf_read(buf, &ret, sizeof(uint32_t)))
1560 {
1561 if (good)
1562 {
1563 *good = false;
1564 }
1565 return 0;
1566 }
1567 else
1568 {
1569 if (good)
1570 {
1571 *good = true;
1572 }
1573 return ntohl(ret);
1574 }
1575}
1576
1588static inline uint64_t
1589buf_read_u64(struct buffer *buf, bool *good)
1590{
1591 uint64_t ret;
1592 if (!buf_read(buf, &ret, sizeof(uint64_t)))
1593 {
1594 if (good)
1595 {
1596 *good = false;
1597 }
1598 return 0;
1599 }
1600 else
1601 {
1602 if (good)
1603 {
1604 *good = true;
1605 }
1606 return ntohll(ret);
1607 }
1608}
1609
1611static inline bool
1612buf_equal(const struct buffer *a, const struct buffer *b)
1613{
1614 return BLEN(a) == BLEN(b) && 0 == memcmp(CBPTR(a), CBPTR(b), BLENZ(a));
1615}
1616
1621static inline bool
1622buf_string_match(const struct buffer *src, const void *match, int size)
1623{
1624 if (size != src->len)
1625 {
1626 return false;
1627 }
1628 return memcmp(CBPTR(src), match, size) == 0;
1629}
1630
1635static inline bool
1636buf_string_match_head(const struct buffer *src, const void *match, int size)
1637{
1638 if (size < 0 || size > src->len)
1639 {
1640 return false;
1641 }
1642 return memcmp(CBPTR(src), match, size) == 0;
1643}
1644
1656bool buf_string_match_head_str(const struct buffer *src, const char *match);
1657
1669bool buf_string_compare_advance(struct buffer *src, const char *match);
1670
1684int buf_substring_len(const struct buffer *buf, int delim);
1685
1693const char *np(const char *str);
1694
1700#define CC_ANY (1 << 0)
1701#define CC_NULL (1 << 1)
1702
1703#define CC_ALNUM (1 << 2)
1704#define CC_ALPHA (1 << 3)
1705#define CC_ASCII (1 << 4)
1706#define CC_CNTRL (1 << 5)
1707#define CC_DIGIT (1 << 6)
1708#define CC_PRINT (1 << 7)
1709#define CC_PUNCT (1 << 8)
1710#define CC_SPACE (1 << 9)
1711#define CC_XDIGIT (1 << 10)
1712
1713#define CC_BLANK (1 << 11)
1714#define CC_NEWLINE (1 << 12)
1715#define CC_CR (1 << 13)
1716
1717#define CC_BACKSLASH (1 << 14)
1718#define CC_UNDERBAR (1 << 15)
1719#define CC_DASH (1 << 16)
1720#define CC_DOT (1 << 17)
1721#define CC_COMMA (1 << 18)
1722#define CC_COLON (1 << 19)
1723#define CC_SLASH (1 << 20)
1724#define CC_SINGLE_QUOTE (1 << 21)
1725#define CC_DOUBLE_QUOTE (1 << 22)
1726#define CC_REVERSE_QUOTE (1 << 23)
1727#define CC_PERCENT (1 << 24)
1728#define CC_EXCLAMATION (1 << 25)
1729#define CC_LESS_THAN (1 << 26)
1730#define CC_GREATER_THAN (1 << 27)
1731#define CC_PIPE (1 << 28)
1732#define CC_QUESTION_MARK (1 << 29)
1733#define CC_ASTERISK (1 << 30)
1734
1735/* macro classes */
1736#define CC_NAME (CC_ALNUM | CC_UNDERBAR)
1737#define CC_CRLF (CC_CR | CC_NEWLINE)
1738
1747bool char_class(const unsigned char c, const unsigned int flags);
1748
1760bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive);
1761
1775bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive,
1776 const char replace);
1777
1778
1787bool string_check_buf(const struct buffer *buf, const unsigned int inclusive,
1788 const unsigned int exclusive);
1789
1804const char *string_mod_const(const char *str, const unsigned int inclusive,
1805 const unsigned int exclusive, const char replace, struct gc_arena *gc);
1807
1819void string_replace_leading(char *str, const char match, const char replace);
1820
1827static inline bool
1828strprefix(const char *str, const char *prefix)
1829{
1830 return 0 == strncmp(str, prefix, strlen(prefix));
1831}
1832
1833bool string_defined_equal(const char *s1, const char *s2);
1834char *string_substitute(const char *src, char from, char to, struct gc_arena *gc);
1835
1850bool checked_snprintf(char *str, size_t size, const char *format, ...)
1851#ifdef __GNUC__
1852#if __USE_MINGW_ANSI_STDIO
1853 __attribute__((format(gnu_printf, 3, 4)))
1854#else
1855 __attribute__((format(__printf__, 3, 4)))
1856#endif
1857#endif
1858 ;
1859
1860/*
1861 * Verify that a pointer is correctly aligned
1862 */
1863#ifdef VERIFY_ALIGNMENT
1874void valign4(const struct buffer *buf, const char *file, const int line);
1875
1876#define verify_align_4(ptr) valign4(buf, __FILE__, __LINE__)
1877#else
1878#define verify_align_4(ptr)
1879#endif
1880
1886
1896void gc_transfer(struct gc_arena *dest, struct gc_arena *src);
1897
1905void x_gc_free(struct gc_arena *a);
1906
1915void x_gc_freespecial(struct gc_arena *a);
1916
1922static inline bool
1924{
1925 return a->list != NULL;
1926}
1927
1933static inline void
1935{
1936 a->list = NULL;
1937 a->list_special = NULL;
1938}
1939
1948static inline void
1950{
1951 gc_init(a);
1952}
1953
1959static inline struct gc_arena
1961{
1962 struct gc_arena ret;
1963 gc_init(&ret);
1964 return ret;
1965}
1966
1975static inline void
1977{
1978 if (a->list)
1979 {
1980 x_gc_free(a);
1981 }
1982 if (a->list_special)
1983 {
1985 }
1986}
1987
1995static inline void
1997{
1998 gc_free(a);
1999}
2000
2001/*
2002 * Allocate memory to hold a structure
2003 */
2004
2005/* When allocating arrays make sure we do not use a excessive amount
2006 * of memory.
2007 */
2008#if UINTPTR_MAX <= UINT32_MAX
2009/* 1 GB on 32bit systems, they usually can only allocate 2 GB for the
2010 * whole process.
2011 */
2013#define ALLOC_SIZE_MAX (1u << 30)
2014#else
2016#define ALLOC_SIZE_MAX ((size_t)1 << 32) /* 4 GB */
2017#endif
2018
2027#define ALLOC_OBJ(dptr, type) \
2028 { \
2029 check_malloc_return((dptr) = (type *)malloc(sizeof(type))); \
2030 }
2031
2038#define ALLOC_OBJ_CLEAR(dptr, type) \
2039 { \
2040 ALLOC_OBJ(dptr, type); \
2041 memset((dptr), 0, sizeof(type)); \
2042 }
2043
2054#define ALLOC_ARRAY(dptr, type, n) \
2055 { \
2056 check_malloc_return((dptr) = (type *)malloc(array_mult_safe(sizeof(type), (n), 0))); \
2057 }
2058
2067#define ALLOC_ARRAY_GC(dptr, type, n, gc) \
2068 { \
2069 (dptr) = (type *)gc_malloc(array_mult_safe(sizeof(type), (n), 0), false, (gc)); \
2070 }
2071
2079#define ALLOC_ARRAY_CLEAR(dptr, type, n) \
2080 { \
2081 ALLOC_ARRAY(dptr, type, n); \
2082 memset((dptr), 0, (array_mult_safe(sizeof(type), (n), 0))); \
2083 }
2084
2093#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc) \
2094 { \
2095 (dptr) = (type *)gc_malloc(array_mult_safe(sizeof(type), (n), 0), true, (gc)); \
2096 }
2097
2110#define ALLOC_VAR_ARRAY_CLEAR_GC(dptr, type, atype, n, gc) \
2111 { \
2112 (dptr) = (type *)gc_malloc(array_mult_safe(sizeof(atype), (n), sizeof(type)), true, (gc)); \
2113 }
2114
2122#define ALLOC_OBJ_GC(dptr, type, gc) \
2123 { \
2124 (dptr) = (type *)gc_malloc(sizeof(type), false, (gc)); \
2125 }
2126
2134#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc) \
2135 { \
2136 (dptr) = (type *)gc_malloc(sizeof(type), true, (gc)); \
2137 }
2138
2145static inline void
2147{
2148 if (!p)
2149 {
2150 out_of_memory();
2151 }
2152}
2153
2154/* End of GC */
2155
2160
2163{
2164 struct buffer buf;
2166};
2167
2170{
2173 size_t size;
2174 size_t max_size;
2175};
2176
2182struct buffer_list *buffer_list_new(void);
2183
2189void buffer_list_free(struct buffer_list *ol);
2190
2198bool buffer_list_defined(const struct buffer_list *ol);
2199
2205void buffer_list_reset(struct buffer_list *ol);
2206
2213void buffer_list_push(struct buffer_list *ol, const char *str);
2214
2224struct buffer_entry *buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size);
2225
2233struct buffer *buffer_list_peek(struct buffer_list *ol);
2234
2244void buffer_list_advance(struct buffer_list *ol, ssize_t n);
2245
2253void buffer_list_pop(struct buffer_list *ol);
2254
2264void buffer_list_aggregate(struct buffer_list *bl, const size_t max);
2265
2278void buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len, const char *sep);
2279
2294struct buffer_list *buffer_list_file(const char *fn, int max_line_len);
2295
2306struct buffer buffer_read_from_file(const char *filename, struct gc_arena *gc);
2308/* End of Buffer Lists */
2309
2317char *
2318buf_extract_field(struct buffer *buf, char sep, struct gc_arena *gc);
2319
2320#endif /* BUFFER_H */
struct buffer clone_buf(const struct buffer *buf)
Duplicate a buffer, including its content.
Definition buffer.c:99
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
Return a sub-buffer of another buffer.
Definition buffer.c:207
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
Definition buffer.c:77
struct buffer alloc_buf(size_t size)
Allocate a buffer of the given size.
Definition buffer.c:60
struct buffer buffer_read_from_file(const char *filename, struct gc_arena *gc)
buffer_read_from_file - copy the content of a file into a buffer
Definition buffer.c:1356
struct buffer string_alloc_buf(const char *str, struct gc_arena *gc)
Allocate a buffer containing a copy of the given string.
Definition buffer.c:707
bool buffer_list_defined(const struct buffer_list *ol)
Checks if the list is valid and non-empty.
Definition buffer.c:1175
bool buf_string_compare_advance(struct buffer *src, const char *match)
Compare the head of src with match and advance past it if equal.
Definition buffer.c:739
static bool buf_write_u16(struct buffer *dest, uint16_t data)
Append a uint16_t to a buffer in network byte order.
Definition buffer.h:1320
static bool has_digit(const char *src)
Return true if the string contains at least one decimal digit.
Definition buffer.h:727
static void gc_detach(struct gc_arena *a)
Detach all allocations from an arena without freeing them.
Definition buffer.h:1949
struct buffer_entry * buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size)
Allocates and appends a new buffer containing data of length size.
Definition buffer.c:1210
void rm_trailing_chars(char *str, const char *what_to_delete)
Remove all trailing characters that appear in a given set.
Definition buffer.c:593
void string_null_terminate(char *str, int len, int capacity)
Null-terminate a fixed-length string buffer.
Definition buffer.c:566
static const uint8_t * buf_cbend(const struct buffer *buf)
Return a const pointer one past the end of the buffer content.
Definition buffer.h:495
void free_buf(struct buffer *buf)
Free the memory allocated for a buffer.
Definition buffer.c:169
void buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len, const char *sep)
Aggregates as many buffers as possible from bl in a new buffer of maximum length max_len .
Definition buffer.c:1251
static bool buf_size_valid(const size_t size)
Return true iff size is within the allowed buffer size range.
Definition buffer.h:543
void buf_clear(struct buffer *buf)
Zeroise and reset a buffer.
Definition buffer.c:148
void buffer_list_reset(struct buffer_list *ol)
Empty the list ol and frees all the contained buffers.
Definition buffer.c:1181
const char * skip_leading_whitespace(const char *str)
Return a pointer past any leading whitespace in a string.
Definition buffer.c:547
void buffer_list_aggregate(struct buffer_list *bl, const size_t max)
Aggregates as many buffers as possible from bl in a new buffer of maximum length max_len .
Definition buffer.c:1296
void x_gc_freespecial(struct gc_arena *a)
Free all specially-allocated entries in a garbage collection arena.
Definition buffer.c:395
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
Definition buffer.c:286
void buf_catrunc(struct buffer *buf, const char *str)
Append a string to the physical end of a buffer that was truncated by buf_printf().
Definition buffer.c:273
static bool buf_init_dowork(struct buffer *buf, int offset)
Initialise a buffer with a given initial offset.
Definition buffer.h:635
static uint8_t * buf_bptr(struct buffer *buf)
Return a pointer to the start of the buffer content.
Definition buffer.h:449
void buffer_list_pop(struct buffer_list *ol)
Remove and free the head buffer of the list.
Definition buffer.c:1302
bool buf_printf(struct buffer *buf, const char *format,...)
printf-style append to a buffer with overflow check.
Definition buffer.c:226
void string_replace_leading(char *str, const char match, const char replace)
Replace all leading occurrences of a character in a string.
Definition buffer.c:1071
static struct buffer clear_buf(void)
Return an empty, undefined struct buffer (all fields zero).
Definition buffer.h:384
bool buf_puts(struct buffer *buf, const char *str)
Append a string to a buffer with overflow check.
Definition buffer.c:253
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Copy the content of one buffer to the end of another.
Definition buffer.h:1365
char * buf_extract_field(struct buffer *buf, char sep, struct gc_arena *gc)
Extract a field from buf that ends with the sep character.
Definition buffer.c:1389
#define BPTR(buf)
Return a pointer to the start of the buffer content.
Definition buffer.h:139
static bool buf_write_u32(struct buffer *dest, uint32_t data)
Append a uint32_t to a buffer in network byte order.
Definition buffer.h:1335
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
Read a file into a buffer list, one buffer per line.
Definition buffer.c:1333
static bool buf_copy_excess(struct buffer *dest, struct buffer *src, int len)
Truncate src to len bytes and copy any excess to dest.
Definition buffer.h:1440
static uint8_t * buf_blast(struct buffer *buf)
Return a pointer to the last byte of the buffer content.
Definition buffer.h:530
static bool buf_write_prepend(struct buffer *dest, const void *src, int size)
Prepend data to a buffer.
Definition buffer.h:1286
void string_clear(char *str)
Securely clear a null-terminated string.
Definition buffer.c:649
static bool buf_string_match(const struct buffer *src, const void *match, int size)
Compare src buffer contents with match.
Definition buffer.h:1622
static bool buf_size_valid_signed(const int size)
Return true iff a signed size is within the allowed buffer size range.
Definition buffer.h:559
static int buf_read_u16(struct buffer *buf)
Read and consume a uint16_t from the front of a buffer.
Definition buffer.h:1534
static bool buf_safe_bidir(const struct buffer *buf, int len)
Check whether len bytes can be added to or removed from a buffer.
Definition buffer.h:1036
static bool buf_inc_len(struct buffer *buf, int inc)
Increase or decrease the length of a buffer.
Definition buffer.h:1142
static bool buf_copy_n(struct buffer *dest, struct buffer *src, int n)
Read n bytes from src and append them to dest.
Definition buffer.h:1383
static bool buf_equal(const struct buffer *a, const struct buffer *b)
Return true if buffer contents are equal.
Definition buffer.h:1612
static bool buf_string_match_head(const struct buffer *src, const void *match, int size)
Compare first size bytes of src buffer contents with match.
Definition buffer.h:1636
static bool buf_valid(const struct buffer *buf)
Return true iff buf is valid.
Definition buffer.h:414
void gc_transfer(struct gc_arena *dest, struct gc_arena *src)
Move all allocations from one garbage collection arena to another.
Definition buffer.c:429
bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive)
Test whether all characters in a string satisfy a character class filter.
Definition buffer.c:986
char * print_argv(const char **p, struct gc_arena *gc, const unsigned int flags)
Format a NULL-terminated argument vector as a single string.
Definition buffer.c:675
void buf_null_terminate(struct buffer *buf)
Force a null terminator at the end of the buffer content.
Definition buffer.c:501
static void gc_init(struct gc_arena *a)
Initialise a garbage collection arena to an empty state.
Definition buffer.h:1934
void * gc_realloc(void *ptr, size_t size, struct gc_arena *a)
allows to realloc a pointer previously allocated by gc_malloc or gc_realloc
Definition buffer.c:343
static uint8_t * buf_read_alloc(struct buffer *buf, int size)
Consume bytes from the front of a buffer for reading.
Definition buffer.h:1237
static void buf_reset(struct buffer *buf)
Reset a buffer to an undefined (unallocated) state.
Definition buffer.h:599
static bool buf_safe(const struct buffer *buf, size_t len)
Check whether len bytes can be appended to a buffer.
Definition buffer.h:1017
struct buffer_list * buffer_list_new(void)
Allocate an empty buffer list of capacity max_size.
Definition buffer.c:1156
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Initialise a buffer with an externally provided writable memory region.
Definition buffer.h:658
void chomp(char *str)
Remove trailing newline and carriage-return characters from a string.
Definition buffer.c:584
struct buffer * buffer_list_peek(struct buffer_list *ol)
Retrieve the head buffer.
Definition buffer.c:1238
static bool buf_read(struct buffer *src, void *dest, int size)
Read bytes from the front of a buffer into a caller-supplied destination.
Definition buffer.h:1474
const char * np(const char *str)
Return a printable representation of a string that might be NULL.
Definition buffer.c:814
bool string_defined_equal(const char *s1, const char *s2)
Definition buffer.c:1089
static uint8_t * buf_bend(struct buffer *buf)
Return a pointer one past the end of the buffer content.
Definition buffer.h:482
#define BUF_SIZE_MAX
Maximum allowed size (in bytes) for a single buffer allocation.
Definition buffer.h:40
size_t array_mult_safe(const size_t m1, const size_t m2, const size_t extra)
Safely compute the product of two sizes plus an extra amount.
Definition buffer.c:40
static const char * buf_cstr(const struct buffer *buf)
Return the buffer content pointer cast to const char *.
Definition buffer.h:585
static uint8_t * buf_prepend(struct buffer *buf, ssize_t size)
Make space at the front of a buffer for prepending data.
Definition buffer.h:1165
static int buf_len(const struct buffer *buf)
Return the length of the buffer content.
Definition buffer.h:462
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Initialise a buffer with an externally provided read-only memory region.
Definition buffer.h:687
static uint64_t buf_read_u64(struct buffer *buf, bool *good)
Read and consume a uint64_t from the front of a buffer.
Definition buffer.h:1589
static int buf_forward_capacity(const struct buffer *buf)
Return the number of bytes that can still be appended to the buffer.
Definition buffer.h:1061
#define CBPTR(buf)
Return a const pointer to the start of the buffer content.
Definition buffer.h:141
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
Definition buffer.c:1165
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Allocate memory and, optionally, zero it.
Definition buffer.c:318
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition buffer.h:769
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
Reserve space at the end of a buffer for writing.
Definition buffer.h:1212
static bool buf_advance(struct buffer *buf, ssize_t size)
Advance the content start of a buffer, consuming bytes from the front.
Definition buffer.h:1188
static int buf_peek_u8(const struct buffer *buf)
Return the first byte of the buffer without consuming it.
Definition buffer.h:1494
bool buf_assign(struct buffer *dest, const struct buffer *src)
Assign the content of one buffer to another.
Definition buffer.c:159
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Append data to a buffer.
Definition buffer.h:1262
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Append a uint8_t to a buffer.
Definition buffer.h:1306
char * format_hex_ex(const uint8_t *data, size_t size, size_t maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Format a binary buffer as a hex string.
Definition buffer.c:452
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Modifies a string in place by replacing certain classes of characters of it with a specified characte...
Definition buffer.c:1005
const char * string_mod_const(const char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace, struct gc_arena *gc)
Returns a copy of a string with certain classes of characters of it replaced with a specified charact...
Definition buffer.c:1055
static bool gc_defined(struct gc_arena *a)
Return true iff the arena contains at least one allocation.
Definition buffer.h:1923
void gc_addspecial(void *addr, void(*free_function)(void *), struct gc_arena *a)
Register an address with a custom free function in a garbage collection arena.
Definition buffer.c:411
void buffer_list_advance(struct buffer_list *ol, ssize_t n)
Advance past n bytes in the head buffer, popping it if it becomes empty.
Definition buffer.c:1319
int string_array_len(const char **array)
Return the number of elements in a NULL-terminated array of strings.
Definition buffer.c:661
static int buf_read_u8(struct buffer *buf)
Read and consume a uint8_t from the front of a buffer.
Definition buffer.h:1513
#define BLEN(buf)
Return the length of the buffer content in bytes.
Definition buffer.h:151
static void buf_reset_len(struct buffer *buf)
Reset the length and offset of a buffer to zero.
Definition buffer.h:616
static char * format_hex(const uint8_t *data, size_t size, size_t maxoutput, struct gc_arena *gc)
Format a binary buffer as a hex string with spaces every 4 bytes.
Definition buffer.h:983
void buf_rmtail(struct buffer *buf, uint8_t remove)
Remove all occurrences of a specific byte from the end of a buffer.
Definition buffer.c:486
char * string_substitute(const char *src, char from, char to, struct gc_arena *gc)
Definition buffer.c:1102
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Extract the next token from a buffer, delimited by a given character.
Definition buffer.c:775
#define BLENZ(buf)
Return the length of the buffer content as a size_t.
Definition buffer.h:153
bool checked_snprintf(char *str, size_t size, const char *format,...)
Like snprintf() but returns an boolean.
Definition buffer.c:1121
void buf_size_error(const size_t size)
Report a buffer size error and abort.
Definition buffer.c:54
char * string_alloc(const char *str, struct gc_arena *gc)
Duplicate a string, allocating memory under garbage collection.
Definition buffer.c:616
static void strncpynt(char *dest, const char *src, size_t maxlen)
Like strncpy() but always null-terminates the destination.
Definition buffer.h:710
static void gc_reset(struct gc_arena *a)
Free all allocations in a garbage collection arena and reinitialise it.
Definition buffer.h:1996
static const uint8_t * buf_cbptr(const struct buffer *buf)
Return a const pointer to the start of the buffer content.
Definition buffer.h:428
static void check_malloc_return(void *p)
Abort if a memory allocation returned NULL.
Definition buffer.h:2146
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1976
static bool buf_copy_range(struct buffer *dest, int dest_index, const struct buffer *src, int src_index, int src_len)
Copy a range of bytes from one buffer into a specific position in another.
Definition buffer.h:1410
static bool buf_defined(const struct buffer *buf)
Return true iff buf has a non-NULL data pointer.
Definition buffer.h:399
void buffer_list_push(struct buffer_list *ol, const char *str)
Allocates and appends a new buffer containing str as data to ol.
Definition buffer.c:1196
void x_gc_free(struct gc_arena *a)
Free all plain allocations in a garbage collection arena.
Definition buffer.c:376
void buf_chomp(struct buffer *buf)
Remove trailing newline and carriage-return characters from a buffer.
Definition buffer.c:522
static int buf_reverse_capacity(const struct buffer *buf)
Return the number of bytes available for prepending to the buffer.
Definition buffer.h:1118
static const uint8_t * buf_cblast(const struct buffer *buf)
Return a const pointer to the last byte of the buffer content.
Definition buffer.h:509
bool string_check_buf(const struct buffer *buf, const unsigned int inclusive, const unsigned int exclusive)
Check a buffer if it only consists of allowed characters.
Definition buffer.c:1038
bool char_class(const unsigned char c, const unsigned int flags)
Test whether a character belongs to one or more character classes.
Definition buffer.c:839
static bool strprefix(const char *str, const char *prefix)
Return true iff str starts with prefix.
Definition buffer.h:1828
bool buf_string_match_head_str(const struct buffer *src, const char *match)
Return true if the head of src matches the string match.
Definition buffer.c:728
static uint32_t buf_read_u32(struct buffer *buf, bool *good)
Read and consume a uint32_t from the front of a buffer.
Definition buffer.h:1556
static void gc_freeaddrinfo_callback(void *addr)
Callback to free a struct addrinfo, suitable for use with gc_addspecial().
Definition buffer.h:377
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1960
int buf_substring_len(const struct buffer *buf, int delim)
Return the number of bytes in a buffer up to and including a delimiter.
Definition buffer.c:753
static bool buf_write_u64(struct buffer *dest, uint64_t data)
Append a uint64_t to a buffer in network byte order.
Definition buffer.h:1350
static char * buf_str(struct buffer *buf)
Return the buffer content pointer cast to char *.
Definition buffer.h:572
static int buf_forward_capacity_total(const struct buffer *buf)
Return the total number of bytes available from the current offset to the end of the allocated memory...
Definition buffer.h:1090
#define ntohll(x)
Definition integer.h:36
#define htonll(x)
Definition integer.h:29
void out_of_memory(void)
Definition error.c:437
One node in a buffer_list linked list.
Definition buffer.h:2163
struct buffer_entry * next
Pointer to the next node, or NULL.
Definition buffer.h:2165
struct buffer buf
The buffer stored in this list node.
Definition buffer.h:2164
A singly-linked list of buffers, with head/tail pointers for O(1) push.
Definition buffer.h:2170
size_t size
Current number of entries.
Definition buffer.h:2173
struct buffer_entry * tail
Last item pushed.
Definition buffer.h:2172
size_t max_size
Maximum number of entries allowed.
Definition buffer.h:2174
struct buffer_entry * head
Next item to pop/peek.
Definition buffer.h:2171
Wrapper structure for dynamically allocated memory.
Definition buffer.h:71
int capacity
Size in bytes of memory allocated by malloc().
Definition buffer.h:72
uint8_t * data
Pointer to the allocated memory.
Definition buffer.h:78
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:76
int offset
Offset in bytes of the actual content within the allocated memory.
Definition buffer.h:74
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
struct gc_entry_special * list_special
First element of the linked list of gc_entry_special structures for allocations requiring a custom fr...
Definition buffer.h:130
struct gc_entry * list
First element of the linked list of gc_entry structures.
Definition buffer.h:128
Garbage collection entry for a specially allocated structure that needs a custom free function to be ...
Definition buffer.h:109
void(* free_fnc)(void *)
Definition buffer.h:111
void * addr
Definition buffer.h:112
struct gc_entry_special * next
Definition buffer.h:110
Garbage collection entry for one dynamically allocated block of memory.
Definition buffer.h:98
struct gc_entry * next
Pointer to the next item in the linked list.
Definition buffer.h:99
#define likely(x)
Definition syshead.h:34
__attribute__((unused))
Definition test.c:42
struct gc_arena gc
Definition test_ssl.c:122