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
23#ifndef BUFFER_H
24#define BUFFER_H
25
26#include "basic.h"
27#include "error.h"
28#include "integer.h"
29
30#define BUF_SIZE_MAX 1000000
31
32/*
33 * Define verify_align function, otherwise
34 * it will be a noop.
35 */
36/* #define VERIFY_ALIGNMENT */
37
38/*
39 * Keep track of source file/line of buf_init calls
40 */
41#ifdef VERIFY_ALIGNMENT
42#define BUF_INIT_TRACKING
43#endif
44
45/**************************************************************************/
60struct buffer
61{
64 int offset;
66 int len;
70#ifdef BUF_INIT_TRACKING
71 const char *debug_file;
72 int debug_line;
73#endif
74};
75
76
77/**************************************************************************/
88{
89 struct gc_entry *next;
91};
92
99{
101 void (*free_fnc)(void *);
102 void *addr;
103};
104
105
117{
118 struct gc_entry *list;
121};
122
123
124#define BPTR(buf) (buf_bptr(buf))
125#define BEND(buf) (buf_bend(buf))
126#define BLAST(buf) (buf_blast(buf))
127#define BLEN(buf) (buf_len(buf))
128#define BLENZ(buf) ((size_t)buf_len(buf))
129#define BDEF(buf) (buf_defined(buf))
130#define BSTR(buf) (buf_str(buf))
131#define BCAP(buf) (buf_forward_capacity(buf))
132
133void buf_clear(struct buffer *buf);
134
135void free_buf(struct buffer *buf);
136
137bool buf_assign(struct buffer *dest, const struct buffer *src);
138
139void string_clear(char *str);
140
141int string_array_len(const char **array);
142
143size_t array_mult_safe(const size_t m1, const size_t m2, const size_t extra);
144
145#define PA_BRACKET (1 << 0)
146char *print_argv(const char **p, struct gc_arena *gc, const unsigned int flags);
147
148void buf_size_error(const size_t size);
149
150/* for dmalloc debugging */
151
152#ifdef DMALLOC
153
154#define alloc_buf(size) alloc_buf_debug(size, __FILE__, __LINE__)
155#define alloc_buf_gc(size, gc) alloc_buf_gc_debug(size, gc, __FILE__, __LINE__);
156#define clone_buf(buf) clone_buf_debug(buf, __FILE__, __LINE__);
157#define gc_malloc(size, clear, arena) gc_malloc_debug(size, clear, arena, __FILE__, __LINE__)
158#define string_alloc(str, gc) string_alloc_debug(str, gc, __FILE__, __LINE__)
159#define string_alloc_buf(str, gc) string_alloc_buf_debug(str, gc, __FILE__, __LINE__)
160
161struct buffer alloc_buf_debug(size_t size, const char *file, int line);
162
163struct buffer alloc_buf_gc_debug(size_t size, struct gc_arena *gc, const char *file, int line);
164
165struct buffer clone_buf_debug(const struct buffer *buf, const char *file, int line);
166
167void *gc_malloc_debug(size_t size, bool clear, struct gc_arena *a, const char *file, int line);
168
169char *string_alloc_debug(const char *str, struct gc_arena *gc, const char *file, int line);
170
171struct buffer string_alloc_buf_debug(const char *str, struct gc_arena *gc, const char *file,
172 int line);
173
174#else /* ifdef DMALLOC */
175
176struct buffer alloc_buf(size_t size);
177
178struct buffer alloc_buf_gc(size_t size,
179 struct gc_arena *gc); /* allocate buffer with garbage collection */
180
181struct buffer clone_buf(const struct buffer *buf);
182
183void *gc_malloc(size_t size, bool clear, struct gc_arena *a);
184
185char *string_alloc(const char *str, struct gc_arena *gc);
186
188
189#endif /* ifdef DMALLOC */
190
191void gc_addspecial(void *addr, void (*free_function)(void *), struct gc_arena *a);
192
204void *gc_realloc(void *ptr, size_t size, struct gc_arena *a);
205
206#ifdef BUF_INIT_TRACKING
207#define buf_init(buf, offset) buf_init_debug(buf, offset, __FILE__, __LINE__)
208bool buf_init_debug(struct buffer *buf, int offset, const char *file, int line);
209
210#else
211#define buf_init(buf, offset) buf_init_dowork(buf, offset)
212#endif
213
214
215/* inline functions */
216static inline void
218{
219 freeaddrinfo((struct addrinfo *)addr);
220}
221
223static inline struct buffer
225{
226 return (struct buffer){ 0 };
227}
228
229static inline bool
230buf_defined(const struct buffer *buf)
231{
232 return buf->data != NULL;
233}
234
235static inline bool
236buf_valid(const struct buffer *buf)
237{
238 return likely(buf->data != NULL) && likely(buf->len >= 0);
239}
240
241static inline uint8_t *
242buf_bptr(const struct buffer *buf)
243{
244 if (buf_valid(buf))
245 {
246 return buf->data + buf->offset;
247 }
248 else
249 {
250 return NULL;
251 }
252}
253
254static int
255buf_len(const struct buffer *buf)
256{
257 if (buf_valid(buf))
258 {
259 return buf->len;
260 }
261 else
262 {
263 return 0;
264 }
265}
266
267static inline uint8_t *
268buf_bend(const struct buffer *buf)
269{
270 return buf_bptr(buf) + buf_len(buf);
271}
272
273static inline uint8_t *
274buf_blast(const struct buffer *buf)
275{
276 if (buf_len(buf) > 0)
277 {
278 return buf_bptr(buf) + buf_len(buf) - 1;
279 }
280 else
281 {
282 return NULL;
283 }
284}
285
286static inline bool
287buf_size_valid(const size_t size)
288{
289 return likely(size < BUF_SIZE_MAX);
290}
291
292static inline bool
294{
295 return likely(size >= -BUF_SIZE_MAX) && likely(size < BUF_SIZE_MAX);
296}
297
298static inline char *
299buf_str(const struct buffer *buf)
300{
301 return (char *)buf_bptr(buf);
302}
303
304static inline void
305buf_reset(struct buffer *buf)
306{
307 buf->capacity = 0;
308 buf->offset = 0;
309 buf->len = 0;
310 buf->data = NULL;
311}
312
313static inline void
315{
316 buf->len = 0;
317 buf->offset = 0;
318}
319
320static inline bool
321buf_init_dowork(struct buffer *buf, int offset)
322{
323 if (offset < 0 || offset > buf->capacity || buf->data == NULL)
324 {
325 return false;
326 }
327 buf->len = 0;
328 buf->offset = offset;
329 return true;
330}
331
332static inline void
333buf_set_write(struct buffer *buf, uint8_t *data, int size)
334{
335 if (!buf_size_valid(size))
336 {
337 buf_size_error(size);
338 }
339 buf->len = 0;
340 buf->offset = 0;
341 buf->capacity = size;
342 buf->data = data;
343 if (size > 0 && data)
344 {
345 *data = 0;
346 }
347}
348
349static inline void
350buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
351{
352 if (!buf_size_valid(size))
353 {
354 buf_size_error(size);
355 }
356 buf->len = buf->capacity = (int)size;
357 buf->offset = 0;
358 buf->data = (uint8_t *)data;
359}
360
361/* Like strncpy but makes sure dest is always null terminated */
362static inline void
363strncpynt(char *dest, const char *src, size_t maxlen)
364{
365 if (maxlen > 0)
366 {
367 strncpy(dest, src, maxlen - 1);
368 dest[maxlen - 1] = 0;
369 }
370}
371
372/* return true if string contains at least one numerical digit */
373static inline bool
374has_digit(const char *src)
375{
376 char c;
377 while ((c = *src++))
378 {
379 if (isdigit(c))
380 {
381 return true;
382 }
383 }
384 return false;
385}
386
415static inline void
416secure_memzero(void *data, size_t len)
417{
418#if defined(_WIN32)
419 SecureZeroMemory(data, len);
420#elif defined(__GNUC__) || defined(__clang__)
421 memset(data, 0, len);
422 __asm__ __volatile__("" : : "r"(data) : "memory");
423#else
424 volatile char *p = (volatile char *)data;
425 while (len--)
426 {
427 *p++ = 0;
428 }
429#endif
430}
431
432/*
433 * printf append to a buffer with overflow check,
434 * due to usage of vsnprintf, it will leave space for
435 * a final null character and thus use only
436 * capacity - 1
437 */
438bool buf_printf(struct buffer *buf, const char *format, ...)
439#ifdef __GNUC__
440#if __USE_MINGW_ANSI_STDIO
441 __attribute__((format(gnu_printf, 2, 3)))
442#else
443 __attribute__((format(__printf__, 2, 3)))
444#endif
445#endif
446 ;
447
448/*
449 * puts append to a buffer with overflow check
450 */
451bool buf_puts(struct buffer *buf, const char *str);
452
453
454/*
455 * remove/add trailing characters
456 */
457
458void buf_null_terminate(struct buffer *buf);
459
460void buf_chomp(struct buffer *buf);
461
462void buf_rmtail(struct buffer *buf, uint8_t remove);
463
464/*
465 * non-buffer string functions
466 */
467void chomp(char *str);
468
469void rm_trailing_chars(char *str, const char *what_to_delete);
470
471const char *skip_leading_whitespace(const char *str);
472
473void string_null_terminate(char *str, int len, int capacity);
474
483bool buffer_write_file(const char *filename, const struct buffer *buf);
484
485/*
486 * write a string to the end of a buffer that was
487 * truncated by buf_printf
488 */
489void buf_catrunc(struct buffer *buf, const char *str);
490
491/*
492 * Parse a string based on a given delimiter char
493 */
494bool buf_parse(struct buffer *buf, const int delim, char *line, const int size);
495
496/*
497 * Hex dump -- Output a binary buffer to a hex string and return it.
498 */
499#define FHE_SPACE_BREAK_MASK 0xFF /* space_break parameter in lower 8 bits */
500#define FHE_CAPS 0x100 /* output hex in caps */
501char *format_hex_ex(const uint8_t *data, size_t size, size_t maxoutput, unsigned int space_break_flags,
502 const char *separator, struct gc_arena *gc);
503
504static inline char *
505format_hex(const uint8_t *data, size_t size, size_t maxoutput, struct gc_arena *gc)
506{
507 return format_hex_ex(data, size, maxoutput, 4, " ", gc);
508}
509
510/*
511 * Return a buffer that is a subset of another buffer.
512 */
513struct buffer buf_sub(struct buffer *buf, int size, bool prepend);
514
515/*
516 * Check if sufficient space to append to buffer.
517 */
518
519static inline bool
520buf_safe(const struct buffer *buf, size_t len)
521{
522 return buf_valid(buf) && buf_size_valid(len)
523 && buf->offset + buf->len + (int)len <= buf->capacity;
524}
525
526static inline bool
527buf_safe_bidir(const struct buffer *buf, int len)
528{
530 {
531 int newlen = buf->len + len;
532 return newlen >= 0 && buf->offset + newlen <= buf->capacity;
533 }
534 else
535 {
536 return false;
537 }
538}
539
540static inline int
541buf_forward_capacity(const struct buffer *buf)
542{
543 if (buf_valid(buf))
544 {
545 int ret = buf->capacity - (buf->offset + buf->len);
546 if (ret < 0)
547 {
548 ret = 0;
549 }
550 return ret;
551 }
552 else
553 {
554 return 0;
555 }
556}
557
558static inline int
560{
561 if (buf_valid(buf))
562 {
563 int ret = buf->capacity - buf->offset;
564 if (ret < 0)
565 {
566 ret = 0;
567 }
568 return ret;
569 }
570 else
571 {
572 return 0;
573 }
574}
575
576static inline int
577buf_reverse_capacity(const struct buffer *buf)
578{
579 if (buf_valid(buf))
580 {
581 return buf->offset;
582 }
583 else
584 {
585 return 0;
586 }
587}
588
589static inline bool
590buf_inc_len(struct buffer *buf, int inc)
591{
592 if (!buf_safe_bidir(buf, inc))
593 {
594 return false;
595 }
596 buf->len += inc;
597 return true;
598}
599
600/*
601 * Make space to prepend to a buffer.
602 * Return NULL if no space.
603 */
604
605static inline uint8_t *
606buf_prepend(struct buffer *buf, ssize_t size)
607{
608 if (!buf_valid(buf) || size < 0 || size > buf->offset)
609 {
610 return NULL;
611 }
612 buf->offset -= (int)size;
613 buf->len += (int)size;
614 return BPTR(buf);
615}
616
617static inline bool
618buf_advance(struct buffer *buf, ssize_t size)
619{
620 if (!buf_valid(buf) || size < 0 || buf->len < size)
621 {
622 return false;
623 }
624 buf->offset += (int)size;
625 buf->len -= (int)size;
626 return true;
627}
628
629/*
630 * Return a pointer to allocated space inside a buffer.
631 * Return NULL if no space.
632 */
633
634static inline uint8_t *
635buf_write_alloc(struct buffer *buf, size_t size)
636{
637 uint8_t *ret;
638 if (!buf_safe(buf, size))
639 {
640 return NULL;
641 }
642 ret = BPTR(buf) + buf->len;
643 buf->len += (int)size;
644 return ret;
645}
646
647static inline uint8_t *
648buf_read_alloc(struct buffer *buf, int size)
649{
650 uint8_t *ret;
651 if (size < 0 || buf->len < size)
652 {
653 return NULL;
654 }
655 ret = BPTR(buf);
656 buf->offset += size;
657 buf->len -= size;
658 return ret;
659}
660
661static inline bool
662buf_write(struct buffer *dest, const void *src, size_t size)
663{
664 uint8_t *cp = buf_write_alloc(dest, size);
665 if (!cp)
666 {
667 return false;
668 }
669 memcpy(cp, src, size);
670 return true;
671}
672
673static inline bool
674buf_write_prepend(struct buffer *dest, const void *src, int size)
675{
676 uint8_t *cp = buf_prepend(dest, size);
677 if (!cp)
678 {
679 return false;
680 }
681 memcpy(cp, src, size);
682 return true;
683}
684
685static inline bool
687{
688 return buf_write(dest, &data, sizeof(uint8_t));
689}
690
691static inline bool
693{
695 return buf_write(dest, &u16, sizeof(uint16_t));
696}
697
698static inline bool
700{
702 return buf_write(dest, &u32, sizeof(uint32_t));
703}
704
705static inline bool
707{
709 return buf_write(dest, &u64, sizeof(uint64_t));
710}
711
712static inline bool
713buf_copy(struct buffer *dest, const struct buffer *src)
714{
715 return buf_write(dest, BPTR(src), BLENZ(src));
716}
717
718static inline bool
719buf_copy_n(struct buffer *dest, struct buffer *src, int n)
720{
722 if (!cp)
723 {
724 return false;
725 }
726 return buf_write(dest, cp, n);
727}
728
729static inline bool
730buf_copy_range(struct buffer *dest, int dest_index, const struct buffer *src, int src_index,
731 int src_len)
732{
734 || dest->offset + dest_index + src_len > dest->capacity)
735 {
736 return false;
737 }
738 memcpy(dest->data + dest->offset + dest_index, src->data + src->offset + src_index, src_len);
739 if (dest_index + src_len > dest->len)
740 {
741 dest->len = dest_index + src_len;
742 }
743 return true;
744}
745
746/* truncate src to len, copy excess data beyond len to dest */
747static inline bool
748buf_copy_excess(struct buffer *dest, struct buffer *src, int len)
749{
750 if (len < 0)
751 {
752 return false;
753 }
754 if (src->len > len)
755 {
756 struct buffer b = *src;
757 src->len = len;
758 if (!buf_advance(&b, len))
759 {
760 return false;
761 }
762 return buf_copy(dest, &b);
763 }
764 else
765 {
766 return true;
767 }
768}
769
770static inline bool
771buf_read(struct buffer *src, void *dest, int size)
772{
773 uint8_t *cp = buf_read_alloc(src, size);
774 if (!cp)
775 {
776 return false;
777 }
778 memcpy(dest, cp, size);
779 return true;
780}
781
782static inline int
783buf_peek_u8(struct buffer *buf)
784{
785 int ret;
786 if (BLEN(buf) < 1)
787 {
788 return -1;
789 }
790 ret = *BPTR(buf);
791 return ret;
792}
793
794static inline int
795buf_read_u8(struct buffer *buf)
796{
797 int ret = buf_peek_u8(buf);
798 if (ret >= 0)
799 {
800 buf_advance(buf, 1);
801 }
802 return ret;
803}
804
805static inline int
807{
809 if (!buf_read(buf, &ret, sizeof(uint16_t)))
810 {
811 return -1;
812 }
813 return ntohs(ret);
814}
815
816static inline uint32_t
817buf_read_u32(struct buffer *buf, bool *good)
818{
820 if (!buf_read(buf, &ret, sizeof(uint32_t)))
821 {
822 if (good)
823 {
824 *good = false;
825 }
826 return 0;
827 }
828 else
829 {
830 if (good)
831 {
832 *good = true;
833 }
834 return ntohl(ret);
835 }
836}
837
838/* Read a 64-bit big-endian value (see buf_write_u64()). Sets *good to indicate
839 * success, like buf_read_u32(). */
840static inline uint64_t
841buf_read_u64(struct buffer *buf, bool *good)
842{
844 if (!buf_read(buf, &ret, sizeof(uint64_t)))
845 {
846 if (good)
847 {
848 *good = false;
849 }
850 return 0;
851 }
852 else
853 {
854 if (good)
855 {
856 *good = true;
857 }
858 return ntohll(ret);
859 }
860}
861
863static inline bool
864buf_equal(const struct buffer *a, const struct buffer *b)
865{
866 return BLEN(a) == BLEN(b) && 0 == memcmp(BPTR(a), BPTR(b), BLENZ(a));
867}
868
873static inline bool
874buf_string_match(const struct buffer *src, const void *match, int size)
875{
876 if (size != src->len)
877 {
878 return false;
879 }
880 return memcmp(BPTR(src), match, size) == 0;
881}
882
887static inline bool
888buf_string_match_head(const struct buffer *src, const void *match, int size)
889{
890 if (size < 0 || size > src->len)
891 {
892 return false;
893 }
894 return memcmp(BPTR(src), match, size) == 0;
895}
896
897bool buf_string_match_head_str(const struct buffer *src, const char *match);
898
899bool buf_string_compare_advance(struct buffer *src, const char *match);
900
901int buf_substring_len(const struct buffer *buf, int delim);
902
903/*
904 * Print a string which might be NULL
905 */
906const char *np(const char *str);
907
908/* character classes */
909
910#define CC_ANY (1 << 0)
911#define CC_NULL (1 << 1)
913#define CC_ALNUM (1 << 2)
914#define CC_ALPHA (1 << 3)
915#define CC_ASCII (1 << 4)
916#define CC_CNTRL (1 << 5)
917#define CC_DIGIT (1 << 6)
918#define CC_PRINT (1 << 7)
919#define CC_PUNCT (1 << 8)
920#define CC_SPACE (1 << 9)
921#define CC_XDIGIT (1 << 10)
923#define CC_BLANK (1 << 11)
924#define CC_NEWLINE (1 << 12)
925#define CC_CR (1 << 13)
927#define CC_BACKSLASH (1 << 14)
928#define CC_UNDERBAR (1 << 15)
929#define CC_DASH (1 << 16)
930#define CC_DOT (1 << 17)
931#define CC_COMMA (1 << 18)
932#define CC_COLON (1 << 19)
933#define CC_SLASH (1 << 20)
934#define CC_SINGLE_QUOTE (1 << 21)
935#define CC_DOUBLE_QUOTE (1 << 22)
936#define CC_REVERSE_QUOTE (1 << 23)
937#define CC_AT (1 << 24)
938#define CC_EQUAL (1 << 25)
939#define CC_LESS_THAN (1 << 26)
940#define CC_GREATER_THAN (1 << 27)
941#define CC_PIPE (1 << 28)
942#define CC_QUESTION_MARK (1 << 29)
943#define CC_ASTERISK (1 << 30)
945/* macro classes */
946#define CC_NAME (CC_ALNUM | CC_UNDERBAR)
947#define CC_CRLF (CC_CR | CC_NEWLINE)
949bool char_class(const unsigned char c, const unsigned int flags);
950
951bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive);
952
966bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive,
967 const char replace);
968
969
978bool string_check_buf(struct buffer *buf, const unsigned int inclusive,
979 const unsigned int exclusive);
980
995const char *string_mod_const(const char *str, const unsigned int inclusive,
996 const unsigned int exclusive, const char replace, struct gc_arena *gc);
997
998void string_replace_leading(char *str, const char match, const char replace);
999
1001static inline bool
1002strprefix(const char *str, const char *prefix)
1003{
1004 return 0 == strncmp(str, prefix, strlen(prefix));
1005}
1006
1021bool checked_snprintf(char *str, size_t size, const char *format, ...)
1022#ifdef __GNUC__
1023#if __USE_MINGW_ANSI_STDIO
1025#else
1027#endif
1028#endif
1029 ;
1030
1031/*
1032 * Verify that a pointer is correctly aligned
1033 */
1034#ifdef VERIFY_ALIGNMENT
1035void valign4(const struct buffer *buf, const char *file, const int line);
1036
1037#define verify_align_4(ptr) valign4(buf, __FILE__, __LINE__)
1038#else
1039#define verify_align_4(ptr)
1040#endif
1041
1042/*
1043 * Very basic garbage collection, mostly for routines that return
1044 * char ptrs to malloced strings.
1045 */
1046
1047void gc_transfer(struct gc_arena *dest, struct gc_arena *src);
1048
1049void x_gc_free(struct gc_arena *a);
1050
1051void x_gc_freespecial(struct gc_arena *a);
1052
1053static inline bool
1055{
1056 return a->list != NULL;
1057}
1058
1059static inline void
1061{
1062 a->list = NULL;
1063 a->list_special = NULL;
1064}
1065
1066static inline void
1068{
1069 gc_init(a);
1070}
1071
1072static inline struct gc_arena
1074{
1075 struct gc_arena ret;
1076 gc_init(&ret);
1077 return ret;
1078}
1079
1080static inline void
1082{
1083 if (a->list)
1084 {
1085 x_gc_free(a);
1086 }
1087 if (a->list_special)
1088 {
1090 }
1091}
1092
1093static inline void
1095{
1096 gc_free(a);
1097}
1098
1099/*
1100 * Allocate memory to hold a structure
1101 */
1102
1103/* When allocating arrays make sure we do not use a excessive amount
1104 * of memory.
1105 */
1106#if UINTPTR_MAX <= UINT32_MAX
1107/* 1 GB on 32bit systems, they usually can only allocate 2 GB for the
1108 * whole process.
1109 */
1110#define ALLOC_SIZE_MAX (1u << 30)
1111#else
1112#define ALLOC_SIZE_MAX ((size_t)1 << 32) /* 4 GB */
1113#endif
1114
1115#define ALLOC_OBJ(dptr, type) \
1116 { \
1117 check_malloc_return((dptr) = (type *)malloc(sizeof(type))); \
1118 }
1119
1120#define ALLOC_OBJ_CLEAR(dptr, type) \
1121 { \
1122 ALLOC_OBJ(dptr, type); \
1123 memset((dptr), 0, sizeof(type)); \
1124 }
1125
1126#define ALLOC_ARRAY(dptr, type, n) \
1127 { \
1128 check_malloc_return((dptr) = (type *)malloc(array_mult_safe(sizeof(type), (n), 0))); \
1129 }
1130
1131#define ALLOC_ARRAY_GC(dptr, type, n, gc) \
1132 { \
1133 (dptr) = (type *)gc_malloc(array_mult_safe(sizeof(type), (n), 0), false, (gc)); \
1134 }
1135
1136#define ALLOC_ARRAY_CLEAR(dptr, type, n) \
1137 { \
1138 ALLOC_ARRAY(dptr, type, n); \
1139 memset((dptr), 0, (array_mult_safe(sizeof(type), (n), 0))); \
1140 }
1141
1142#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc) \
1143 { \
1144 (dptr) = (type *)gc_malloc(array_mult_safe(sizeof(type), (n), 0), true, (gc)); \
1145 }
1146
1147#define ALLOC_VAR_ARRAY_CLEAR_GC(dptr, type, atype, n, gc) \
1148 { \
1149 (dptr) = (type *)gc_malloc(array_mult_safe(sizeof(atype), (n), sizeof(type)), true, (gc)); \
1150 }
1151
1152#define ALLOC_OBJ_GC(dptr, type, gc) \
1153 { \
1154 (dptr) = (type *)gc_malloc(sizeof(type), false, (gc)); \
1155 }
1156
1157#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc) \
1158 { \
1159 (dptr) = (type *)gc_malloc(sizeof(type), true, (gc)); \
1160 }
1161
1162static inline void
1164{
1165 if (!p)
1166 {
1167 out_of_memory();
1168 }
1169}
1170
1171/*
1172 * Manage lists of buffers
1173 */
1175{
1176 struct buffer buf;
1178};
1179
1181{
1182 struct buffer_entry *head; /* next item to pop/peek */
1183 struct buffer_entry *tail; /* last item pushed */
1184 size_t size; /* current number of entries */
1185 size_t max_size; /* maximum size list should grow to */
1186};
1187
1193struct buffer_list *buffer_list_new(void);
1194
1200void buffer_list_free(struct buffer_list *ol);
1201
1209bool buffer_list_defined(const struct buffer_list *ol);
1210
1216void buffer_list_reset(struct buffer_list *ol);
1217
1224void buffer_list_push(struct buffer_list *ol, const char *str);
1225
1235struct buffer_entry *buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size);
1236
1244struct buffer *buffer_list_peek(struct buffer_list *ol);
1245
1246void buffer_list_advance(struct buffer_list *ol, ssize_t n);
1247
1248void buffer_list_pop(struct buffer_list *ol);
1249
1259void buffer_list_aggregate(struct buffer_list *bl, const size_t max);
1260
1273void buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len, const char *sep);
1274
1275struct buffer_list *buffer_list_file(const char *fn, int max_line_len);
1276
1287struct buffer buffer_read_from_file(const char *filename, struct gc_arena *gc);
1288
1289#endif /* BUFFER_H */
bool buffer_list_defined(const struct buffer_list *ol)
Checks if the list is valid and non-empty.
Definition buffer.c:1197
static uint8_t * buf_bend(const struct buffer *buf)
Definition buffer.h:268
bool buf_string_compare_advance(struct buffer *src, const char *match)
Definition buffer.c:793
static bool buf_write_u16(struct buffer *dest, uint16_t data)
Definition buffer.h:692
static bool has_digit(const char *src)
Definition buffer.h:374
static uint8_t * buf_bptr(const struct buffer *buf)
Definition buffer.h:242
static void gc_detach(struct gc_arena *a)
Definition buffer.h:1067
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:1232
void rm_trailing_chars(char *str, const char *what_to_delete)
Definition buffer.c:627
void string_null_terminate(char *str, int len, int capacity)
Definition buffer.c:601
void free_buf(struct buffer *buf)
Definition buffer.c:189
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:1273
static bool buf_size_valid(const size_t size)
Definition buffer.h:287
void buf_clear(struct buffer *buf)
Definition buffer.c:168
void buffer_list_reset(struct buffer_list *ol)
Empty the list ol and frees all the contained buffers.
Definition buffer.c:1203
const char * skip_leading_whitespace(const char *str)
Definition buffer.c:583
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:1318
struct buffer clone_buf(const struct buffer *buf)
Definition buffer.c:115
void x_gc_freespecial(struct gc_arena *a)
Definition buffer.c:427
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
Definition buffer.c:306
static uint8_t * buf_blast(const struct buffer *buf)
Definition buffer.h:274
void buf_catrunc(struct buffer *buf, const char *str)
Definition buffer.c:293
static bool buf_init_dowork(struct buffer *buf, int offset)
Definition buffer.h:321
void buffer_list_pop(struct buffer_list *ol)
Definition buffer.c:1324
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:246
void string_replace_leading(char *str, const char match, const char replace)
Definition buffer.c:1125
static struct buffer clear_buf(void)
Return an empty struct buffer.
Definition buffer.h:224
bool buf_puts(struct buffer *buf, const char *str)
Definition buffer.c:273
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Definition buffer.h:713
#define BPTR(buf)
Definition buffer.h:124
static bool buf_write_u32(struct buffer *dest, uint32_t data)
Definition buffer.h:699
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
Definition buffer.c:1355
static bool buf_copy_excess(struct buffer *dest, struct buffer *src, int len)
Definition buffer.h:748
static bool buf_write_prepend(struct buffer *dest, const void *src, int size)
Definition buffer.h:674
void string_clear(char *str)
Definition buffer.c:695
static int buf_peek_u8(struct buffer *buf)
Definition buffer.h:783
static bool buf_string_match(const struct buffer *src, const void *match, int size)
Compare src buffer contents with match.
Definition buffer.h:874
static bool buf_size_valid_signed(const int size)
Definition buffer.h:293
static int buf_read_u16(struct buffer *buf)
Definition buffer.h:806
static bool buf_safe_bidir(const struct buffer *buf, int len)
Definition buffer.h:527
static bool buf_inc_len(struct buffer *buf, int inc)
Definition buffer.h:590
static bool buf_copy_n(struct buffer *dest, struct buffer *src, int n)
Definition buffer.h:719
static bool buf_equal(const struct buffer *a, const struct buffer *b)
Return true if buffer contents are equal.
Definition buffer.h:864
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:888
static bool buf_valid(const struct buffer *buf)
Definition buffer.h:236
void gc_transfer(struct gc_arena *dest, struct gc_arena *src)
Definition buffer.c:465
bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive)
Definition buffer.c:1040
char * print_argv(const char **p, struct gc_arena *gc, const unsigned int flags)
Definition buffer.c:721
void buf_null_terminate(struct buffer *buf)
Definition buffer.c:537
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
Definition buffer.c:227
static void gc_init(struct gc_arena *a)
Definition buffer.h:1060
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:375
static uint8_t * buf_read_alloc(struct buffer *buf, int size)
Definition buffer.h:648
static void buf_reset(struct buffer *buf)
Definition buffer.h:305
static bool buf_safe(const struct buffer *buf, size_t len)
Definition buffer.h:520
struct buffer_list * buffer_list_new(void)
Allocate an empty buffer list of capacity max_size.
Definition buffer.c:1178
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Definition buffer.h:333
void chomp(char *str)
Definition buffer.c:618
struct buffer * buffer_list_peek(struct buffer_list *ol)
Retrieve the head buffer.
Definition buffer.c:1260
static bool buf_read(struct buffer *src, void *dest, int size)
Definition buffer.h:771
const char * np(const char *str)
Definition buffer.c:868
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:1092
#define BUF_SIZE_MAX
Definition buffer.h:30
size_t array_mult_safe(const size_t m1, const size_t m2, const size_t extra)
Definition buffer.c:40
static uint8_t * buf_prepend(struct buffer *buf, ssize_t size)
Definition buffer.h:606
static int buf_len(const struct buffer *buf)
Definition buffer.h:255
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Definition buffer.h:350
static uint64_t buf_read_u64(struct buffer *buf, bool *good)
Definition buffer.h:841
static int buf_forward_capacity(const struct buffer *buf)
Definition buffer.h:541
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
Definition buffer.c:1187
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:341
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition buffer.h:416
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
Definition buffer.h:635
static bool buf_advance(struct buffer *buf, ssize_t size)
Definition buffer.h:618
bool buf_assign(struct buffer *dest, const struct buffer *src)
Definition buffer.c:179
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:662
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Definition buffer.h:686
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)
Definition buffer.c:488
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:1059
struct buffer alloc_buf(size_t size)
Definition buffer.c:63
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:1109
static bool gc_defined(struct gc_arena *a)
Definition buffer.h:1054
void gc_addspecial(void *addr, void(*free_function)(void *), struct gc_arena *a)
Definition buffer.c:443
void buffer_list_advance(struct buffer_list *ol, ssize_t n)
Definition buffer.c:1341
int string_array_len(const char **array)
Definition buffer.c:707
static int buf_read_u8(struct buffer *buf)
Definition buffer.h:795
#define BLEN(buf)
Definition buffer.h:127
static void buf_reset_len(struct buffer *buf)
Definition buffer.h:314
static char * format_hex(const uint8_t *data, size_t size, size_t maxoutput, struct gc_arena *gc)
Definition buffer.h:505
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:1378
void buf_rmtail(struct buffer *buf, uint8_t remove)
Definition buffer.c:522
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Definition buffer.c:829
#define BLENZ(buf)
Definition buffer.h:128
bool checked_snprintf(char *str, size_t size, const char *format,...)
Like snprintf() but returns an boolean.
Definition buffer.c:1143
void buf_size_error(const size_t size)
Definition buffer.c:54
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:653
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition buffer.h:363
static void gc_reset(struct gc_arena *a)
Definition buffer.h:1094
static void check_malloc_return(void *p)
Definition buffer.h:1163
static void gc_free(struct gc_arena *a)
Definition buffer.h:1081
static bool buf_copy_range(struct buffer *dest, int dest_index, const struct buffer *src, int src_index, int src_len)
Definition buffer.h:730
static char * buf_str(const struct buffer *buf)
Definition buffer.h:299
struct buffer string_alloc_buf(const char *str, struct gc_arena *gc)
Definition buffer.c:756
static bool buf_defined(const struct buffer *buf)
Definition buffer.h:230
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:1218
void x_gc_free(struct gc_arena *a)
Definition buffer.c:408
void buf_chomp(struct buffer *buf)
Definition buffer.c:558
static int buf_reverse_capacity(const struct buffer *buf)
Definition buffer.h:577
bool char_class(const unsigned char c, const unsigned int flags)
Definition buffer.c:893
static bool strprefix(const char *str, const char *prefix)
Return true iff str starts with prefix.
Definition buffer.h:1002
bool buf_string_match_head_str(const struct buffer *src, const char *match)
Definition buffer.c:782
static uint32_t buf_read_u32(struct buffer *buf, bool *good)
Definition buffer.h:817
static void gc_freeaddrinfo_callback(void *addr)
Definition buffer.h:217
static struct gc_arena gc_new(void)
Definition buffer.h:1073
int buf_substring_len(const struct buffer *buf, int delim)
Definition buffer.c:807
static bool buf_write_u64(struct buffer *dest, uint64_t data)
Definition buffer.h:706
static int buf_forward_capacity_total(const struct buffer *buf)
Definition buffer.h:559
#define ntohll(x)
Definition integer.h:36
#define htonll(x)
Definition integer.h:29
void out_of_memory(void)
Definition error.c:435
Definition buffer.h:1175
struct buffer_entry * next
Definition buffer.h:1177
struct buffer buf
Definition buffer.h:1176
size_t size
Definition buffer.h:1184
struct buffer_entry * tail
Definition buffer.h:1183
size_t max_size
Definition buffer.h:1185
struct buffer_entry * head
Definition buffer.h:1182
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
int capacity
Size in bytes of memory allocated by malloc().
Definition buffer.h:62
uint8_t * data
Pointer to the allocated memory.
Definition buffer.h:68
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
int offset
Offset in bytes of the actual content within the allocated memory.
Definition buffer.h:64
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
struct gc_entry_special * list_special
Definition buffer.h:120
struct gc_entry * list
First element of the linked list of gc_entry structures.
Definition buffer.h:118
Garbage collection entry for a specially allocated structure that needs a custom free function to be ...
Definition buffer.h:99
void(* free_fnc)(void *)
Definition buffer.h:101
void * addr
Definition buffer.h:102
struct gc_entry_special * next
Definition buffer.h:100
Garbage collection entry for one dynamically allocated block of memory.
Definition buffer.h:88
struct gc_entry * next
Pointer to the next item in the linked list.
Definition buffer.h:89
#define likely(x)
Definition syshead.h:34
__attribute__((unused))
Definition test.c:42
struct gc_arena gc
Definition test_ssl.c:133