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
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;
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 BEND(buf) (buf_bend(buf))
143#define BLAST(buf) (buf_blast(buf))
145#define BLEN(buf) (buf_len(buf))
147#define BLENZ(buf) ((size_t)buf_len(buf))
149#define BDEF(buf) (buf_defined(buf))
151#define BSTR(buf) (buf_str(buf))
153#define BCAP(buf) (buf_forward_capacity(buf))
154
163void buf_clear(struct buffer *buf);
164
172void free_buf(struct buffer *buf);
173
185bool buf_assign(struct buffer *dest, const struct buffer *src);
186
194void string_clear(char *str);
195
203int string_array_len(const char **array);
204
218size_t array_mult_safe(const size_t m1, const size_t m2, const size_t extra);
219
221#define PA_BRACKET (1 << 0)
231char *print_argv(const char **p, struct gc_arena *gc, const unsigned int flags);
232
241void buf_size_error(const size_t size);
242
253struct buffer alloc_buf(size_t size);
254
268
279struct buffer clone_buf(const struct buffer *buf);
280
294void *gc_malloc(size_t size, bool clear, struct gc_arena *a);
295
306char *string_alloc(const char *str, struct gc_arena *gc);
307
322
335void gc_addspecial(void *addr, void (*free_function)(void *), struct gc_arena *a);
336
348void *gc_realloc(void *ptr, size_t size, struct gc_arena *a);
349
350#ifdef BUF_INIT_TRACKING
351#define buf_init(buf, offset) buf_init_debug(buf, offset, __FILE__, __LINE__)
353bool buf_init_debug(struct buffer *buf, int offset, const char *file, int line);
354
355#else
356#define buf_init(buf, offset) buf_init_dowork(buf, offset)
357#endif
358
359
360/* inline functions */
361
368static inline void
370{
371 freeaddrinfo((struct addrinfo *)addr);
372}
373
375static inline struct buffer
377{
378 return (struct buffer){ 0 };
379}
380
389static inline bool
390buf_defined(const struct buffer *buf)
391{
392 return buf->data != NULL;
393}
394
403static inline bool
404buf_valid(const struct buffer *buf)
405{
406 return likely(buf->data != NULL) && likely(buf->len >= 0);
407}
408
417static inline uint8_t *
418buf_bptr(const struct buffer *buf)
419{
420 if (buf_valid(buf))
421 {
422 return buf->data + buf->offset;
423 }
424 else
425 {
426 return NULL;
427 }
428}
429
437static int
438buf_len(const struct buffer *buf)
439{
440 if (buf_valid(buf))
441 {
442 return buf->len;
443 }
444 else
445 {
446 return 0;
447 }
448}
449
457static inline uint8_t *
458buf_bend(const struct buffer *buf)
459{
460 return buf_bptr(buf) + buf_len(buf);
461}
462
471static inline uint8_t *
472buf_blast(const struct buffer *buf)
473{
474 if (buf_len(buf) > 0)
475 {
476 return buf_bptr(buf) + buf_len(buf) - 1;
477 }
478 else
479 {
480 return NULL;
481 }
482}
483
491static inline bool
492buf_size_valid(const size_t size)
493{
494 return likely(size < BUF_SIZE_MAX);
495}
496
507static inline bool
509{
510 return likely(size >= -BUF_SIZE_MAX) && likely(size < BUF_SIZE_MAX);
511}
512
520static inline char *
521buf_str(const struct buffer *buf)
522{
523 return (char *)buf_bptr(buf);
524}
525
534static inline void
535buf_reset(struct buffer *buf)
536{
537 buf->capacity = 0;
538 buf->offset = 0;
539 buf->len = 0;
540 buf->data = NULL;
541}
542
551static inline void
553{
554 buf->len = 0;
555 buf->offset = 0;
556}
557
570static inline bool
571buf_init_dowork(struct buffer *buf, int offset)
572{
573 if (offset < 0 || offset > buf->capacity || buf->data == NULL)
574 {
575 return false;
576 }
577 buf->len = 0;
578 buf->offset = offset;
579 return true;
580}
581
593static inline void
594buf_set_write(struct buffer *buf, uint8_t *data, int size)
595{
596 if (!buf_size_valid(size))
597 {
598 buf_size_error(size);
599 }
600 buf->len = 0;
601 buf->offset = 0;
602 buf->capacity = size;
603 buf->data = data;
604 if (size > 0 && data)
605 {
606 *data = 0;
607 }
608}
609
622static inline void
623buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
624{
625 if (!buf_size_valid(size))
626 {
627 buf_size_error(size);
628 }
629 buf->len = buf->capacity = (int)size;
630 buf->offset = 0;
631 buf->data = (uint8_t *)data;
632}
633
645static inline void
646strncpynt(char *dest, const char *src, size_t maxlen)
647{
648 if (maxlen > 0)
649 {
650 strncpy(dest, src, maxlen - 1);
651 dest[maxlen - 1] = 0;
652 }
653}
654
662static inline bool
663has_digit(const char *src)
664{
665 char c;
666 while ((c = *src++))
667 {
668 if (isdigit(c))
669 {
670 return true;
671 }
672 }
673 return false;
674}
675
704static inline void
705secure_memzero(void *data, size_t len)
706{
707#if defined(_WIN32)
708 SecureZeroMemory(data, len);
709#elif defined(__GNUC__) || defined(__clang__)
710 memset(data, 0, len);
711 __asm__ __volatile__("" : : "r"(data) : "memory");
712#else
713 volatile char *p = (volatile char *)data;
714 while (len--)
715 {
716 *p++ = 0;
717 }
718#endif
719}
720
736bool buf_printf(struct buffer *buf, const char *format, ...)
737#ifdef __GNUC__
738#if __USE_MINGW_ANSI_STDIO
739 __attribute__((format(gnu_printf, 2, 3)))
740#else
741 __attribute__((format(__printf__, 2, 3)))
742#endif
743#endif
744 ;
745
754bool buf_puts(struct buffer *buf, const char *str);
755
756
757/*
758 * remove/add trailing characters
759 */
760
771void buf_null_terminate(struct buffer *buf);
772
778void buf_chomp(struct buffer *buf);
779
786void buf_rmtail(struct buffer *buf, uint8_t remove);
787
798void chomp(char *str);
799
806void rm_trailing_chars(char *str, const char *what_to_delete);
807
816const char *skip_leading_whitespace(const char *str);
817
828#ifdef _WIN32
829void string_null_terminate(char *str, int len, int capacity);
830#endif
832/* End of string utility functions */
833
842bool buffer_write_file(const char *filename, const struct buffer *buf);
843
856void buf_catrunc(struct buffer *buf, const char *str);
857
875bool buf_parse(struct buffer *buf, const int delim, char *line, const int size);
876
884#define FHE_SPACE_BREAK_MASK 0xFF
886#define FHE_CAPS 0x100
903char *format_hex_ex(const uint8_t *data, size_t size, size_t maxoutput, unsigned int space_break_flags,
904 const char *separator, struct gc_arena *gc);
905
918static inline char *
919format_hex(const uint8_t *data, size_t size, size_t maxoutput, struct gc_arena *gc)
920{
921 return format_hex_ex(data, size, maxoutput, 4, " ", gc);
922}
924/* End of Hex Dump */
925
941struct buffer buf_sub(struct buffer *buf, int size, bool prepend);
942
952static inline bool
953buf_safe(const struct buffer *buf, size_t len)
954{
955 return buf_valid(buf) && buf_size_valid(len)
956 && buf->offset + buf->len + (int)len <= buf->capacity;
957}
958
971static inline bool
972buf_safe_bidir(const struct buffer *buf, int len)
973{
975 {
976 int newlen = buf->len + len;
977 return newlen >= 0 && buf->offset + newlen <= buf->capacity;
978 }
979 else
980 {
981 return false;
982 }
983}
984
996static inline int
997buf_forward_capacity(const struct buffer *buf)
998{
999 if (buf_valid(buf))
1000 {
1001 int ret = buf->capacity - (buf->offset + buf->len);
1002 if (ret < 0)
1003 {
1004 ret = 0;
1005 }
1006 return ret;
1007 }
1008 else
1009 {
1010 return 0;
1011 }
1012}
1013
1025static inline int
1027{
1028 if (buf_valid(buf))
1029 {
1030 int ret = buf->capacity - buf->offset;
1031 if (ret < 0)
1032 {
1033 ret = 0;
1034 }
1035 return ret;
1036 }
1037 else
1038 {
1039 return 0;
1040 }
1041}
1042
1053static inline int
1055{
1056 if (buf_valid(buf))
1057 {
1058 return buf->offset;
1059 }
1060 else
1061 {
1062 return 0;
1063 }
1064}
1065
1077static inline bool
1078buf_inc_len(struct buffer *buf, int inc)
1079{
1080 if (!buf_safe_bidir(buf, inc))
1081 {
1082 return false;
1083 }
1084 buf->len += inc;
1085 return true;
1086}
1087
1100static inline uint8_t *
1101buf_prepend(struct buffer *buf, ssize_t size)
1102{
1103 if (!buf_valid(buf) || size < 0 || size > buf->offset)
1104 {
1105 return NULL;
1106 }
1107 buf->offset -= (int)size;
1108 buf->len += (int)size;
1109 return BPTR(buf);
1110}
1111
1123static inline bool
1124buf_advance(struct buffer *buf, ssize_t size)
1125{
1126 if (!buf_valid(buf) || size < 0 || buf->len < size)
1127 {
1128 return false;
1129 }
1130 buf->offset += (int)size;
1131 buf->len -= (int)size;
1132 return true;
1133}
1134
1147static inline uint8_t *
1148buf_write_alloc(struct buffer *buf, size_t size)
1149{
1150 uint8_t *ret;
1151 if (!buf_safe(buf, size))
1152 {
1153 return NULL;
1154 }
1155 ret = BPTR(buf) + buf->len;
1156 buf->len += (int)size;
1157 return ret;
1158}
1159
1172static inline uint8_t *
1173buf_read_alloc(struct buffer *buf, int size)
1174{
1175 uint8_t *ret;
1176 if (size < 0 || buf->len < size)
1177 {
1178 return NULL;
1179 }
1180 ret = BPTR(buf);
1181 buf->offset += size;
1182 buf->len -= size;
1183 return ret;
1184}
1185
1197static inline bool
1198buf_write(struct buffer *dest, const void *src, size_t size)
1199{
1200 uint8_t *cp = buf_write_alloc(dest, size);
1201 if (!cp)
1202 {
1203 return false;
1204 }
1205 memcpy(cp, src, size);
1206 return true;
1207}
1208
1221static inline bool
1222buf_write_prepend(struct buffer *dest, const void *src, int size)
1223{
1224 uint8_t *cp = buf_prepend(dest, size);
1225 if (!cp)
1226 {
1227 return false;
1228 }
1229 memcpy(cp, src, size);
1230 return true;
1231}
1232
1241static inline bool
1243{
1244 return buf_write(dest, &data, sizeof(uint8_t));
1245}
1246
1255static inline bool
1257{
1259 return buf_write(dest, &u16, sizeof(uint16_t));
1260}
1261
1270static inline bool
1272{
1274 return buf_write(dest, &u32, sizeof(uint32_t));
1275}
1276
1285static inline bool
1287{
1289 return buf_write(dest, &u64, sizeof(uint64_t));
1290}
1291
1300static inline bool
1301buf_copy(struct buffer *dest, const struct buffer *src)
1302{
1303 return buf_write(dest, BPTR(src), BLENZ(src));
1304}
1305
1318static inline bool
1319buf_copy_n(struct buffer *dest, struct buffer *src, int n)
1320{
1321 const uint8_t *cp = buf_read_alloc(src, n);
1322 if (!cp)
1323 {
1324 return false;
1325 }
1326 return buf_write(dest, cp, n);
1327}
1328
1345static inline bool
1346buf_copy_range(struct buffer *dest, int dest_index, const struct buffer *src, int src_index,
1347 int src_len)
1348{
1350 || dest->offset + dest_index + src_len > dest->capacity)
1351 {
1352 return false;
1353 }
1354 memcpy(dest->data + dest->offset + dest_index, src->data + src->offset + src_index, src_len);
1355 if (dest_index + src_len > dest->len)
1356 {
1357 dest->len = dest_index + src_len;
1358 }
1359 return true;
1360}
1361
1375static inline bool
1376buf_copy_excess(struct buffer *dest, struct buffer *src, int len)
1377{
1378 if (len < 0)
1379 {
1380 return false;
1381 }
1382 if (src->len > len)
1383 {
1384 struct buffer b = *src;
1385 src->len = len;
1386 if (!buf_advance(&b, len))
1387 {
1388 return false;
1389 }
1390 return buf_copy(dest, &b);
1391 }
1392 else
1393 {
1394 return true;
1395 }
1396}
1397
1409static inline bool
1410buf_read(struct buffer *src, void *dest, int size)
1411{
1412 const uint8_t *cp = buf_read_alloc(src, size);
1413 if (!cp)
1414 {
1415 return false;
1416 }
1417 memcpy(dest, cp, size);
1418 return true;
1419}
1420
1429static inline int
1431{
1432 int ret;
1433 if (BLEN(buf) < 1)
1434 {
1435 return -1;
1436 }
1437 ret = *BPTR(buf);
1438 return ret;
1439}
1440
1448static inline int
1450{
1451 int ret = buf_peek_u8(buf);
1452 if (ret >= 0)
1453 {
1454 buf_advance(buf, 1);
1455 }
1456 return ret;
1457}
1458
1469static inline int
1471{
1472 uint16_t ret;
1473 if (!buf_read(buf, &ret, sizeof(uint16_t)))
1474 {
1475 return -1;
1476 }
1477 return ntohs(ret);
1478}
1479
1491static inline uint32_t
1492buf_read_u32(struct buffer *buf, bool *good)
1493{
1494 uint32_t ret;
1495 if (!buf_read(buf, &ret, sizeof(uint32_t)))
1496 {
1497 if (good)
1498 {
1499 *good = false;
1500 }
1501 return 0;
1502 }
1503 else
1504 {
1505 if (good)
1506 {
1507 *good = true;
1508 }
1509 return ntohl(ret);
1510 }
1511}
1512
1524static inline uint64_t
1525buf_read_u64(struct buffer *buf, bool *good)
1526{
1527 uint64_t ret;
1528 if (!buf_read(buf, &ret, sizeof(uint64_t)))
1529 {
1530 if (good)
1531 {
1532 *good = false;
1533 }
1534 return 0;
1535 }
1536 else
1537 {
1538 if (good)
1539 {
1540 *good = true;
1541 }
1542 return ntohll(ret);
1543 }
1544}
1545
1547static inline bool
1548buf_equal(const struct buffer *a, const struct buffer *b)
1549{
1550 return BLEN(a) == BLEN(b) && 0 == memcmp(BPTR(a), BPTR(b), BLENZ(a));
1551}
1552
1557static inline bool
1558buf_string_match(const struct buffer *src, const void *match, int size)
1559{
1560 if (size != src->len)
1561 {
1562 return false;
1563 }
1564 return memcmp(BPTR(src), match, size) == 0;
1565}
1566
1571static inline bool
1572buf_string_match_head(const struct buffer *src, const void *match, int size)
1573{
1574 if (size < 0 || size > src->len)
1575 {
1576 return false;
1577 }
1578 return memcmp(BPTR(src), match, size) == 0;
1579}
1580
1592bool buf_string_match_head_str(const struct buffer *src, const char *match);
1593
1605bool buf_string_compare_advance(struct buffer *src, const char *match);
1606
1620int buf_substring_len(const struct buffer *buf, int delim);
1621
1629const char *np(const char *str);
1630
1636#define CC_ANY (1 << 0)
1637#define CC_NULL (1 << 1)
1639#define CC_ALNUM (1 << 2)
1640#define CC_ALPHA (1 << 3)
1641#define CC_ASCII (1 << 4)
1642#define CC_CNTRL (1 << 5)
1643#define CC_DIGIT (1 << 6)
1644#define CC_PRINT (1 << 7)
1645#define CC_PUNCT (1 << 8)
1646#define CC_SPACE (1 << 9)
1647#define CC_XDIGIT (1 << 10)
1649#define CC_BLANK (1 << 11)
1650#define CC_NEWLINE (1 << 12)
1651#define CC_CR (1 << 13)
1653#define CC_BACKSLASH (1 << 14)
1654#define CC_UNDERBAR (1 << 15)
1655#define CC_DASH (1 << 16)
1656#define CC_DOT (1 << 17)
1657#define CC_COMMA (1 << 18)
1658#define CC_COLON (1 << 19)
1659#define CC_SLASH (1 << 20)
1660#define CC_SINGLE_QUOTE (1 << 21)
1661#define CC_DOUBLE_QUOTE (1 << 22)
1662#define CC_REVERSE_QUOTE (1 << 23)
1663#define CC_AT (1 << 24)
1664#define CC_EQUAL (1 << 25)
1665#define CC_LESS_THAN (1 << 26)
1666#define CC_GREATER_THAN (1 << 27)
1667#define CC_PIPE (1 << 28)
1668#define CC_QUESTION_MARK (1 << 29)
1669#define CC_ASTERISK (1 << 30)
1671/* macro classes */
1672#define CC_NAME (CC_ALNUM | CC_UNDERBAR)
1673#define CC_CRLF (CC_CR | CC_NEWLINE)
1683bool char_class(const unsigned char c, const unsigned int flags);
1684
1696bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive);
1697
1711bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive,
1712 const char replace);
1713
1714
1723bool string_check_buf(struct buffer *buf, const unsigned int inclusive,
1724 const unsigned int exclusive);
1725
1740const char *string_mod_const(const char *str, const unsigned int inclusive,
1741 const unsigned int exclusive, const char replace, struct gc_arena *gc);
1755void string_replace_leading(char *str, const char match, const char replace);
1756
1763static inline bool
1764strprefix(const char *str, const char *prefix)
1765{
1766 return 0 == strncmp(str, prefix, strlen(prefix));
1767}
1768
1769bool string_defined_equal(const char *s1, const char *s2);
1770char *string_substitute(const char *src, char from, char to, struct gc_arena *gc);
1771
1786bool checked_snprintf(char *str, size_t size, const char *format, ...)
1787#ifdef __GNUC__
1788#if __USE_MINGW_ANSI_STDIO
1790#else
1792#endif
1793#endif
1794 ;
1795
1796/*
1797 * Verify that a pointer is correctly aligned
1798 */
1799#ifdef VERIFY_ALIGNMENT
1810void valign4(const struct buffer *buf, const char *file, const int line);
1811
1812#define verify_align_4(ptr) valign4(buf, __FILE__, __LINE__)
1813#else
1814#define verify_align_4(ptr)
1815#endif
1816
1832void gc_transfer(struct gc_arena *dest, struct gc_arena *src);
1833
1841void x_gc_free(struct gc_arena *a);
1842
1851void x_gc_freespecial(struct gc_arena *a);
1852
1858static inline bool
1860{
1861 return a->list != NULL;
1862}
1863
1869static inline void
1871{
1872 a->list = NULL;
1873 a->list_special = NULL;
1874}
1875
1884static inline void
1886{
1887 gc_init(a);
1888}
1889
1895static inline struct gc_arena
1897{
1898 struct gc_arena ret;
1899 gc_init(&ret);
1900 return ret;
1901}
1902
1911static inline void
1913{
1914 if (a->list)
1915 {
1916 x_gc_free(a);
1917 }
1918 if (a->list_special)
1919 {
1921 }
1922}
1923
1931static inline void
1933{
1934 gc_free(a);
1935}
1936
1937/*
1938 * Allocate memory to hold a structure
1939 */
1940
1941/* When allocating arrays make sure we do not use a excessive amount
1942 * of memory.
1943 */
1944#if UINTPTR_MAX <= UINT32_MAX
1945/* 1 GB on 32bit systems, they usually can only allocate 2 GB for the
1946 * whole process.
1947 */
1949#define ALLOC_SIZE_MAX (1u << 30)
1950#else
1952#define ALLOC_SIZE_MAX ((size_t)1 << 32) /* 4 GB */
1953#endif
1954
1963#define ALLOC_OBJ(dptr, type) \
1964 { \
1965 check_malloc_return((dptr) = (type *)malloc(sizeof(type))); \
1966 }
1967
1974#define ALLOC_OBJ_CLEAR(dptr, type) \
1975 { \
1976 ALLOC_OBJ(dptr, type); \
1977 memset((dptr), 0, sizeof(type)); \
1978 }
1979
1990#define ALLOC_ARRAY(dptr, type, n) \
1991 { \
1992 check_malloc_return((dptr) = (type *)malloc(array_mult_safe(sizeof(type), (n), 0))); \
1993 }
1994
2003#define ALLOC_ARRAY_GC(dptr, type, n, gc) \
2004 { \
2005 (dptr) = (type *)gc_malloc(array_mult_safe(sizeof(type), (n), 0), false, (gc)); \
2006 }
2007
2015#define ALLOC_ARRAY_CLEAR(dptr, type, n) \
2016 { \
2017 ALLOC_ARRAY(dptr, type, n); \
2018 memset((dptr), 0, (array_mult_safe(sizeof(type), (n), 0))); \
2019 }
2020
2029#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc) \
2030 { \
2031 (dptr) = (type *)gc_malloc(array_mult_safe(sizeof(type), (n), 0), true, (gc)); \
2032 }
2033
2046#define ALLOC_VAR_ARRAY_CLEAR_GC(dptr, type, atype, n, gc) \
2047 { \
2048 (dptr) = (type *)gc_malloc(array_mult_safe(sizeof(atype), (n), sizeof(type)), true, (gc)); \
2049 }
2050
2058#define ALLOC_OBJ_GC(dptr, type, gc) \
2059 { \
2060 (dptr) = (type *)gc_malloc(sizeof(type), false, (gc)); \
2061 }
2062
2070#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc) \
2071 { \
2072 (dptr) = (type *)gc_malloc(sizeof(type), true, (gc)); \
2073 }
2074
2081static inline void
2083{
2084 if (!p)
2085 {
2086 out_of_memory();
2087 }
2088}
2090/* End of GC */
2091
2099{
2100 struct buffer buf;
2102};
2103
2106{
2109 size_t size;
2110 size_t max_size;
2111};
2112
2118struct buffer_list *buffer_list_new(void);
2119
2125void buffer_list_free(struct buffer_list *ol);
2126
2134bool buffer_list_defined(const struct buffer_list *ol);
2135
2141void buffer_list_reset(struct buffer_list *ol);
2142
2149void buffer_list_push(struct buffer_list *ol, const char *str);
2150
2160struct buffer_entry *buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size);
2161
2169struct buffer *buffer_list_peek(struct buffer_list *ol);
2170
2180void buffer_list_advance(struct buffer_list *ol, ssize_t n);
2181
2189void buffer_list_pop(struct buffer_list *ol);
2190
2200void buffer_list_aggregate(struct buffer_list *bl, const size_t max);
2201
2214void buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len, const char *sep);
2215
2230struct buffer_list *buffer_list_file(const char *fn, int max_line_len);
2231
2242struct buffer buffer_read_from_file(const char *filename, struct gc_arena *gc);
2244/* End of Buffer Lists */
2245
2253char *
2254buf_extract_field(struct buffer *buf, char sep, struct gc_arena *gc);
2255
2256#endif /* BUFFER_H */
bool buffer_list_defined(const struct buffer_list *ol)
Checks if the list is valid and non-empty.
Definition buffer.c:1175
static uint8_t * buf_bend(const struct buffer *buf)
Return a pointer one past the end of the buffer content.
Definition buffer.h:458
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:1256
static bool has_digit(const char *src)
Return true if the string contains at least one decimal digit.
Definition buffer.h:663
static uint8_t * buf_bptr(const struct buffer *buf)
Return a pointer to the start of the buffer content.
Definition buffer.h:418
static void gc_detach(struct gc_arena *a)
Detach all allocations from an arena without freeing them.
Definition buffer.h:1885
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
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:492
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
struct buffer clone_buf(const struct buffer *buf)
Duplicate a buffer, including its content.
Definition buffer.c:99
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
static uint8_t * buf_blast(const struct buffer *buf)
Return a pointer to the last byte of the buffer content.
Definition buffer.h:472
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:571
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:376
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:1301
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:1271
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:1376
static bool buf_write_prepend(struct buffer *dest, const void *src, int size)
Prepend data to a buffer.
Definition buffer.h:1222
void string_clear(char *str)
Securely clear a null-terminated string.
Definition buffer.c:649
static int buf_peek_u8(struct buffer *buf)
Return the first byte of the buffer without consuming it.
Definition buffer.h:1430
static bool buf_string_match(const struct buffer *src, const void *match, int size)
Compare src buffer contents with match.
Definition buffer.h:1558
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:508
static int buf_read_u16(struct buffer *buf)
Read and consume a uint16_t from the front of a buffer.
Definition buffer.h:1470
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:972
static bool buf_inc_len(struct buffer *buf, int inc)
Increase or decrease the length of a buffer.
Definition buffer.h:1078
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:1319
static bool buf_equal(const struct buffer *a, const struct buffer *b)
Return true if buffer contents are equal.
Definition buffer.h:1548
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:1572
static bool buf_valid(const struct buffer *buf)
Return true iff buf is valid.
Definition buffer.h:404
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
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
Return a sub-buffer of another buffer.
Definition buffer.c:207
static void gc_init(struct gc_arena *a)
Initialise a garbage collection arena to an empty state.
Definition buffer.h:1870
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:1173
static void buf_reset(struct buffer *buf)
Reset a buffer to an undefined (unallocated) state.
Definition buffer.h:535
static bool buf_safe(const struct buffer *buf, size_t len)
Check whether len bytes can be appended to a buffer.
Definition buffer.h:953
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:594
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:1410
const char * np(const char *str)
Return a printable representation of a string that might be NULL.
Definition buffer.c:814
bool string_check_buf(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 string_defined_equal(const char *s1, const char *s2)
Definition buffer.c:1089
#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 uint8_t * buf_prepend(struct buffer *buf, ssize_t size)
Make space at the front of a buffer for prepending data.
Definition buffer.h:1101
static int buf_len(const struct buffer *buf)
Return the length of the buffer content.
Definition buffer.h:438
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:623
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:1525
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:997
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:705
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:1148
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:1124
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:1198
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
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Append a uint8_t to a buffer.
Definition buffer.h:1242
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
struct buffer alloc_buf(size_t size)
Allocate a buffer of the given size.
Definition buffer.c:60
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:1859
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:1449
#define BLEN(buf)
Return the length of the buffer content in bytes.
Definition buffer.h:145
static void buf_reset_len(struct buffer *buf)
Reset the length and offset of a buffer to zero.
Definition buffer.h:552
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:919
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
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:147
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:646
static void gc_reset(struct gc_arena *a)
Free all allocations in a garbage collection arena and reinitialise it.
Definition buffer.h:1932
static void check_malloc_return(void *p)
Abort if a memory allocation returned NULL.
Definition buffer.h:2082
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1912
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:1346
static char * buf_str(const struct buffer *buf)
Return the buffer content pointer cast to char *.
Definition buffer.h:521
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
static bool buf_defined(const struct buffer *buf)
Return true iff buf has a non-NULL data pointer.
Definition buffer.h:390
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:1054
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:1764
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:1492
static void gc_freeaddrinfo_callback(void *addr)
Callback to free a struct addrinfo, suitable for use with gc_addspecial().
Definition buffer.h:369
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1896
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:1286
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:1026
#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:2099
struct buffer_entry * next
Pointer to the next node, or NULL.
Definition buffer.h:2101
struct buffer buf
The buffer stored in this list node.
Definition buffer.h:2100
A singly-linked list of buffers, with head/tail pointers for O(1) push.
Definition buffer.h:2106
size_t size
Current number of entries.
Definition buffer.h:2109
struct buffer_entry * tail
Last item pushed.
Definition buffer.h:2108
size_t max_size
Maximum number of entries allowed.
Definition buffer.h:2110
struct buffer_entry * head
Next item to pop/peek.
Definition buffer.h:2107
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