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