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-2024 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, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24#ifndef BUFFER_H
25#define BUFFER_H
26
27#include "basic.h"
28#include "error.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 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, int line);
171
172#else /* ifdef DMALLOC */
173
174struct buffer alloc_buf(size_t size);
175
176struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc); /* allocate buffer with garbage collection */
177
178struct buffer clone_buf(const struct buffer *buf);
179
180void *gc_malloc(size_t size, bool clear, struct gc_arena *a);
181
182char *string_alloc(const char *str, struct gc_arena *gc);
183
185
186#endif /* ifdef DMALLOC */
187
188void gc_addspecial(void *addr, void (*free_function)(void *), struct gc_arena *a);
189
201void *
202gc_realloc(void *ptr, size_t size, struct gc_arena *a);
203
204#ifdef BUF_INIT_TRACKING
205#define buf_init(buf, offset) buf_init_debug(buf, offset, __FILE__, __LINE__)
206bool buf_init_debug(struct buffer *buf, int offset, const char *file, int line);
207
208#else
209#define buf_init(buf, offset) buf_init_dowork(buf, offset)
210#endif
211
212
213/* inline functions */
214static inline void
216{
217 freeaddrinfo((struct addrinfo *) addr);
218}
219
221static inline struct buffer
223{
224 return (struct buffer) { 0 };
225}
226
227static inline bool
228buf_defined(const struct buffer *buf)
229{
230 return buf->data != NULL;
231}
232
233static inline bool
234buf_valid(const struct buffer *buf)
235{
236 return likely(buf->data != NULL) && likely(buf->len >= 0);
237}
238
239static inline uint8_t *
240buf_bptr(const struct buffer *buf)
241{
242 if (buf_valid(buf))
243 {
244 return buf->data + buf->offset;
245 }
246 else
247 {
248 return NULL;
249 }
250}
251
252static int
253buf_len(const struct buffer *buf)
254{
255 if (buf_valid(buf))
256 {
257 return buf->len;
258 }
259 else
260 {
261 return 0;
262 }
263}
264
265static inline uint8_t *
266buf_bend(const struct buffer *buf)
267{
268 return buf_bptr(buf) + buf_len(buf);
269}
270
271static inline uint8_t *
272buf_blast(const struct buffer *buf)
273{
274 if (buf_len(buf) > 0)
275 {
276 return buf_bptr(buf) + buf_len(buf) - 1;
277 }
278 else
279 {
280 return NULL;
281 }
282}
283
284static inline bool
285buf_size_valid(const size_t size)
286{
287 return likely(size < BUF_SIZE_MAX);
288}
289
290static inline bool
292{
293 return likely(size >= -BUF_SIZE_MAX) && likely(size < BUF_SIZE_MAX);
294}
295
296static inline char *
297buf_str(const struct buffer *buf)
298{
299 return (char *)buf_bptr(buf);
300}
301
302static inline void
303buf_reset(struct buffer *buf)
304{
305 buf->capacity = 0;
306 buf->offset = 0;
307 buf->len = 0;
308 buf->data = NULL;
309}
310
311static inline void
313{
314 buf->len = 0;
315 buf->offset = 0;
316}
317
318static inline bool
319buf_init_dowork(struct buffer *buf, int offset)
320{
321 if (offset < 0 || offset > buf->capacity || buf->data == NULL)
322 {
323 return false;
324 }
325 buf->len = 0;
326 buf->offset = offset;
327 return true;
328}
329
330static inline void
331buf_set_write(struct buffer *buf, uint8_t *data, int size)
332{
333 if (!buf_size_valid(size))
334 {
335 buf_size_error(size);
336 }
337 buf->len = 0;
338 buf->offset = 0;
339 buf->capacity = size;
340 buf->data = data;
341 if (size > 0 && data)
342 {
343 *data = 0;
344 }
345}
346
347static inline void
348buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
349{
350 if (!buf_size_valid(size))
351 {
352 buf_size_error(size);
353 }
354 buf->len = buf->capacity = (int)size;
355 buf->offset = 0;
356 buf->data = (uint8_t *)data;
357}
358
359/* Like strncpy but makes sure dest is always null terminated */
360static inline void
361strncpynt(char *dest, const char *src, size_t maxlen)
362{
363 if (maxlen > 0)
364 {
365 strncpy(dest, src, maxlen-1);
366 dest[maxlen - 1] = 0;
367 }
368}
369
370/* return true if string contains at least one numerical digit */
371static inline bool
372has_digit(const char *src)
373{
374 char c;
375 while ((c = *src++))
376 {
377 if (isdigit(c))
378 {
379 return true;
380 }
381 }
382 return false;
383}
384
413static inline void
414secure_memzero(void *data, size_t len)
415{
416#if defined(_WIN32)
417 SecureZeroMemory(data, len);
418#elif defined(__GNUC__) || defined(__clang__)
419 memset(data, 0, len);
420 __asm__ __volatile__ ("" : : "r" (data) : "memory");
421#else
422 volatile char *p = (volatile char *) data;
423 while (len--)
424 {
425 *p++ = 0;
426 }
427#endif
428}
429
430/*
431 * printf append to a buffer with overflow check,
432 * due to usage of vsnprintf, it will leave space for
433 * a final null character and thus use only
434 * capacity - 1
435 */
436bool buf_printf(struct buffer *buf, const char *format, ...)
437#ifdef __GNUC__
438#if __USE_MINGW_ANSI_STDIO
439__attribute__ ((format(gnu_printf, 2, 3)))
440#else
441__attribute__ ((format(__printf__, 2, 3)))
442#endif
443#endif
444;
445
446/*
447 * puts append to a buffer with overflow check
448 */
449bool buf_puts(struct buffer *buf, const char *str);
450
451
452/*
453 * remove/add trailing characters
454 */
455
456void buf_null_terminate(struct buffer *buf);
457
458void buf_chomp(struct buffer *buf);
459
460void buf_rmtail(struct buffer *buf, uint8_t remove);
461
462/*
463 * non-buffer string functions
464 */
465void chomp(char *str);
466
467void rm_trailing_chars(char *str, const char *what_to_delete);
468
469const char *skip_leading_whitespace(const char *str);
470
471void string_null_terminate(char *str, int len, int capacity);
472
481bool buffer_write_file(const char *filename, const struct buffer *buf);
482
483/*
484 * write a string to the end of a buffer that was
485 * truncated by buf_printf
486 */
487void buf_catrunc(struct buffer *buf, const char *str);
488
489/*
490 * Parse a string based on a given delimiter char
491 */
492bool buf_parse(struct buffer *buf, const int delim, char *line, const int size);
493
494/*
495 * Hex dump -- Output a binary buffer to a hex string and return it.
496 */
497#define FHE_SPACE_BREAK_MASK 0xFF /* space_break parameter in lower 8 bits */
498#define FHE_CAPS 0x100 /* output hex in caps */
499char *
500format_hex_ex(const uint8_t *data, int size, int maxoutput,
501 unsigned int space_break_flags, const char *separator,
502 struct gc_arena *gc);
503
504static inline char *
505format_hex(const uint8_t *data, int size, int 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, int size)
607{
608 if (!buf_valid(buf) || size < 0 || size > buf->offset)
609 {
610 return NULL;
611 }
612 buf->offset -= size;
613 buf->len += size;
614 return BPTR(buf);
615}
616
617static inline bool
618buf_advance(struct buffer *buf, int size)
619{
620 if (!buf_valid(buf) || size < 0 || buf->len < size)
621 {
622 return false;
623 }
624 buf->offset += size;
625 buf->len -= 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_write_alloc_prepend(struct buffer *buf, int size, bool prepend)
649{
650 return prepend ? buf_prepend(buf, size) : buf_write_alloc(buf, size);
651}
652
653static inline uint8_t *
654buf_read_alloc(struct buffer *buf, int size)
655{
656 uint8_t *ret;
657 if (size < 0 || buf->len < size)
658 {
659 return NULL;
660 }
661 ret = BPTR(buf);
662 buf->offset += size;
663 buf->len -= size;
664 return ret;
665}
666
667static inline bool
668buf_write(struct buffer *dest, const void *src, size_t size)
669{
670 uint8_t *cp = buf_write_alloc(dest, size);
671 if (!cp)
672 {
673 return false;
674 }
675 memcpy(cp, src, size);
676 return true;
677}
678
679static inline bool
680buf_write_prepend(struct buffer *dest, const void *src, int size)
681{
682 uint8_t *cp = buf_prepend(dest, size);
683 if (!cp)
684 {
685 return false;
686 }
687 memcpy(cp, src, size);
688 return true;
689}
690
691static inline bool
693{
694 return buf_write(dest, &data, sizeof(uint8_t));
695}
696
697static inline bool
699{
701 return buf_write(dest, &u16, sizeof(uint16_t));
702}
703
704static inline bool
706{
708 return buf_write(dest, &u32, sizeof(uint32_t));
709}
710
711static inline bool
712buf_copy(struct buffer *dest, const struct buffer *src)
713{
714 return buf_write(dest, BPTR(src), BLEN(src));
715}
716
717static inline bool
718buf_copy_n(struct buffer *dest, struct buffer *src, int n)
719{
721 if (!cp)
722 {
723 return false;
724 }
725 return buf_write(dest, cp, n);
726}
727
728static inline bool
730 int dest_index,
731 const struct buffer *src,
732 int src_index,
733 int src_len)
734{
735 if (src_index < 0
736 || src_len < 0
737 || src_index + src_len > src->len
738 || dest_index < 0
739 || dest->offset + dest_index + src_len > dest->capacity)
740 {
741 return false;
742 }
743 memcpy(dest->data + dest->offset + dest_index, src->data + src->offset + src_index, src_len);
744 if (dest_index + src_len > dest->len)
745 {
746 dest->len = dest_index + src_len;
747 }
748 return true;
749}
750
751/* truncate src to len, copy excess data beyond len to dest */
752static inline bool
754 struct buffer *src,
755 int len)
756{
757 if (len < 0)
758 {
759 return false;
760 }
761 if (src->len > len)
762 {
763 struct buffer b = *src;
764 src->len = len;
765 if (!buf_advance(&b, len))
766 {
767 return false;
768 }
769 return buf_copy(dest, &b);
770 }
771 else
772 {
773 return true;
774 }
775}
776
777static inline bool
778buf_read(struct buffer *src, void *dest, int size)
779{
780 uint8_t *cp = buf_read_alloc(src, size);
781 if (!cp)
782 {
783 return false;
784 }
785 memcpy(dest, cp, size);
786 return true;
787}
788
789static inline int
790buf_read_u8(struct buffer *buf)
791{
792 int ret;
793 if (BLEN(buf) < 1)
794 {
795 return -1;
796 }
797 ret = *BPTR(buf);
798 buf_advance(buf, 1);
799 return ret;
800}
801
802static inline int
804{
805 uint16_t ret;
806 if (!buf_read(buf, &ret, sizeof(uint16_t)))
807 {
808 return -1;
809 }
810 return ntohs(ret);
811}
812
813static inline uint32_t
814buf_read_u32(struct buffer *buf, bool *good)
815{
816 uint32_t ret;
817 if (!buf_read(buf, &ret, sizeof(uint32_t)))
818 {
819 if (good)
820 {
821 *good = false;
822 }
823 return 0;
824 }
825 else
826 {
827 if (good)
828 {
829 *good = true;
830 }
831 return ntohl(ret);
832 }
833}
834
836static inline bool
837buf_equal(const struct buffer *a, const struct buffer *b)
838{
839 return BLEN(a) == BLEN(b) && 0 == memcmp(BPTR(a), BPTR(b), BLEN(a));
840}
841
846static inline bool
847buf_string_match(const struct buffer *src, const void *match, int size)
848{
849 if (size != src->len)
850 {
851 return false;
852 }
853 return memcmp(BPTR(src), match, size) == 0;
854}
855
860static inline bool
861buf_string_match_head(const struct buffer *src, const void *match, int size)
862{
863 if (size < 0 || size > src->len)
864 {
865 return false;
866 }
867 return memcmp(BPTR(src), match, size) == 0;
868}
869
870bool buf_string_match_head_str(const struct buffer *src, const char *match);
871
872bool buf_string_compare_advance(struct buffer *src, const char *match);
873
874int buf_substring_len(const struct buffer *buf, int delim);
875
876/*
877 * Print a string which might be NULL
878 */
879const char *np(const char *str);
880
881/* character classes */
882
883#define CC_ANY (1<<0)
884#define CC_NULL (1<<1)
886#define CC_ALNUM (1<<2)
887#define CC_ALPHA (1<<3)
888#define CC_ASCII (1<<4)
889#define CC_CNTRL (1<<5)
890#define CC_DIGIT (1<<6)
891#define CC_PRINT (1<<7)
892#define CC_PUNCT (1<<8)
893#define CC_SPACE (1<<9)
894#define CC_XDIGIT (1<<10)
896#define CC_BLANK (1<<11)
897#define CC_NEWLINE (1<<12)
898#define CC_CR (1<<13)
900#define CC_BACKSLASH (1<<14)
901#define CC_UNDERBAR (1<<15)
902#define CC_DASH (1<<16)
903#define CC_DOT (1<<17)
904#define CC_COMMA (1<<18)
905#define CC_COLON (1<<19)
906#define CC_SLASH (1<<20)
907#define CC_SINGLE_QUOTE (1<<21)
908#define CC_DOUBLE_QUOTE (1<<22)
909#define CC_REVERSE_QUOTE (1<<23)
910#define CC_AT (1<<24)
911#define CC_EQUAL (1<<25)
912#define CC_LESS_THAN (1<<26)
913#define CC_GREATER_THAN (1<<27)
914#define CC_PIPE (1<<28)
915#define CC_QUESTION_MARK (1<<29)
916#define CC_ASTERISK (1<<30)
918/* macro classes */
919#define CC_NAME (CC_ALNUM|CC_UNDERBAR)
920#define CC_CRLF (CC_CR|CC_NEWLINE)
922bool char_class(const unsigned char c, const unsigned int flags);
923
924bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive);
925
939bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace);
940
941
950bool
951string_check_buf(struct buffer *buf, const unsigned int inclusive, const unsigned int exclusive);
952
967const char *string_mod_const(const char *str,
968 const unsigned int inclusive,
969 const unsigned int exclusive,
970 const char replace,
971 struct gc_arena *gc);
972
973void string_replace_leading(char *str, const char match, const char replace);
974
976static inline bool
977strprefix(const char *str, const char *prefix)
978{
979 return 0 == strncmp(str, prefix, strlen(prefix));
980}
981
982
983/*
984 * Verify that a pointer is correctly aligned
985 */
986#ifdef VERIFY_ALIGNMENT
987void valign4(const struct buffer *buf, const char *file, const int line);
988
989#define verify_align_4(ptr) valign4(buf, __FILE__, __LINE__)
990#else
991#define verify_align_4(ptr)
992#endif
993
994/*
995 * Very basic garbage collection, mostly for routines that return
996 * char ptrs to malloced strings.
997 */
998
999void gc_transfer(struct gc_arena *dest, struct gc_arena *src);
1000
1001void x_gc_free(struct gc_arena *a);
1002
1003void x_gc_freespecial(struct gc_arena *a);
1004
1005static inline bool
1007{
1008 return a->list != NULL;
1009}
1010
1011static inline void
1013{
1014 a->list = NULL;
1015 a->list_special = NULL;
1016}
1017
1018static inline void
1020{
1021 gc_init(a);
1022}
1023
1024static inline struct gc_arena
1026{
1027 struct gc_arena ret;
1028 gc_init(&ret);
1029 return ret;
1030}
1031
1032static inline void
1034{
1035 if (a->list)
1036 {
1037 x_gc_free(a);
1038 }
1039 if (a->list_special)
1040 {
1042 }
1043}
1044
1045static inline void
1047{
1048 gc_free(a);
1049}
1050
1051/*
1052 * Allocate memory to hold a structure
1053 */
1054
1055#define ALLOC_OBJ(dptr, type) \
1056 { \
1057 check_malloc_return((dptr) = (type *) malloc(sizeof(type))); \
1058 }
1059
1060#define ALLOC_OBJ_CLEAR(dptr, type) \
1061 { \
1062 ALLOC_OBJ(dptr, type); \
1063 memset((dptr), 0, sizeof(type)); \
1064 }
1065
1066#define ALLOC_ARRAY(dptr, type, n) \
1067 { \
1068 check_malloc_return((dptr) = (type *) malloc(array_mult_safe(sizeof(type), (n), 0))); \
1069 }
1070
1071#define ALLOC_ARRAY_GC(dptr, type, n, gc) \
1072 { \
1073 (dptr) = (type *) gc_malloc(array_mult_safe(sizeof(type), (n), 0), false, (gc)); \
1074 }
1075
1076#define ALLOC_ARRAY_CLEAR(dptr, type, n) \
1077 { \
1078 ALLOC_ARRAY(dptr, type, n); \
1079 memset((dptr), 0, (array_mult_safe(sizeof(type), (n), 0))); \
1080 }
1081
1082#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc) \
1083 { \
1084 (dptr) = (type *) gc_malloc(array_mult_safe(sizeof(type), (n), 0), true, (gc)); \
1085 }
1086
1087#define ALLOC_VAR_ARRAY_CLEAR_GC(dptr, type, atype, n, gc) \
1088 { \
1089 (dptr) = (type *) gc_malloc(array_mult_safe(sizeof(atype), (n), sizeof(type)), true, (gc)); \
1090 }
1091
1092#define ALLOC_OBJ_GC(dptr, type, gc) \
1093 { \
1094 (dptr) = (type *) gc_malloc(sizeof(type), false, (gc)); \
1095 }
1096
1097#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc) \
1098 { \
1099 (dptr) = (type *) gc_malloc(sizeof(type), true, (gc)); \
1100 }
1101
1102static inline void
1104{
1105 if (!p)
1106 {
1107 out_of_memory();
1108 }
1109}
1110
1111/*
1112 * Manage lists of buffers
1113 */
1115{
1116 struct buffer buf;
1118};
1119
1121{
1122 struct buffer_entry *head; /* next item to pop/peek */
1123 struct buffer_entry *tail; /* last item pushed */
1124 int size; /* current number of entries */
1125 int max_size; /* maximum size list should grow to */
1126};
1127
1133struct buffer_list *buffer_list_new(void);
1134
1140void buffer_list_free(struct buffer_list *ol);
1141
1149bool buffer_list_defined(const struct buffer_list *ol);
1150
1156void buffer_list_reset(struct buffer_list *ol);
1157
1164void buffer_list_push(struct buffer_list *ol, const char *str);
1165
1175struct buffer_entry *buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size);
1176
1184struct buffer *buffer_list_peek(struct buffer_list *ol);
1185
1186void buffer_list_advance(struct buffer_list *ol, int n);
1187
1188void buffer_list_pop(struct buffer_list *ol);
1189
1199void buffer_list_aggregate(struct buffer_list *bl, const size_t max);
1200
1214 const size_t max_len, const char *sep);
1215
1216struct buffer_list *buffer_list_file(const char *fn, int max_line_len);
1217
1228struct buffer buffer_read_from_file(const char *filename, struct gc_arena *gc);
1229
1230#endif /* BUFFER_H */
bool buffer_list_defined(const struct buffer_list *ol)
Checks if the list is valid and non-empty.
Definition buffer.c:1177
static uint8_t * buf_bend(const struct buffer *buf)
Definition buffer.h:266
bool buf_string_compare_advance(struct buffer *src, const char *match)
Definition buffer.c:789
static bool buf_write_u16(struct buffer *dest, uint16_t data)
Definition buffer.h:698
static bool has_digit(const char *src)
Definition buffer.h:372
static uint8_t * buf_bptr(const struct buffer *buf)
Definition buffer.h:240
static void gc_detach(struct gc_arena *a)
Definition buffer.h:1019
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:1212
void rm_trailing_chars(char *str, const char *what_to_delete)
Definition buffer.c:623
void string_null_terminate(char *str, int len, int capacity)
Definition buffer.c:597
void buffer_list_advance(struct buffer_list *ol, int n)
Definition buffer.c:1321
void free_buf(struct buffer *buf)
Definition buffer.c:183
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:1252
static bool buf_size_valid(const size_t size)
Definition buffer.h:285
void buf_clear(struct buffer *buf)
Definition buffer.c:162
void buffer_list_reset(struct buffer_list *ol)
Empty the list ol and frees all the contained buffers.
Definition buffer.c:1183
const char * skip_leading_whitespace(const char *str)
Definition buffer.c:579
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:1298
struct buffer clone_buf(const struct buffer *buf)
Definition buffer.c:115
void x_gc_freespecial(struct gc_arena *a)
Definition buffer.c:422
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
Definition buffer.c:300
static uint8_t * buf_blast(const struct buffer *buf)
Definition buffer.h:272
void buf_catrunc(struct buffer *buf, const char *str)
Definition buffer.c:287
static bool buf_init_dowork(struct buffer *buf, int offset)
Definition buffer.h:319
static char * format_hex(const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
Definition buffer.h:505
void buffer_list_pop(struct buffer_list *ol)
Definition buffer.c:1304
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
void string_replace_leading(char *str, const char match, const char replace)
Definition buffer.c:1109
static struct buffer clear_buf(void)
Return an empty struct buffer.
Definition buffer.h:222
bool buf_puts(struct buffer *buf, const char *str)
Definition buffer.c:267
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Definition buffer.h:712
#define BPTR(buf)
Definition buffer.h:124
static bool buf_write_u32(struct buffer *dest, uint32_t data)
Definition buffer.h:705
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
Definition buffer.c:1335
static bool buf_copy_excess(struct buffer *dest, struct buffer *src, int len)
Definition buffer.h:753
static bool buf_write_prepend(struct buffer *dest, const void *src, int size)
Definition buffer.h:680
void string_clear(char *str)
Definition buffer.c:691
static bool buf_string_match(const struct buffer *src, const void *match, int size)
Compare src buffer contents with match.
Definition buffer.h:847
static bool buf_size_valid_signed(const int size)
Definition buffer.h:291
static int buf_read_u16(struct buffer *buf)
Definition buffer.h:803
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:718
static bool buf_equal(const struct buffer *a, const struct buffer *b)
Return true if buffer contents are equal.
Definition buffer.h:837
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:861
static bool buf_valid(const struct buffer *buf)
Definition buffer.h:234
void gc_transfer(struct gc_arena *dest, struct gc_arena *src)
Definition buffer.c:460
bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive)
Definition buffer.c:1022
char * print_argv(const char **p, struct gc_arena *gc, const unsigned int flags)
Definition buffer.c:717
void buf_null_terminate(struct buffer *buf)
Definition buffer.c:533
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
Definition buffer.c:221
static void gc_init(struct gc_arena *a)
Definition buffer.h:1012
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:370
static uint8_t * buf_read_alloc(struct buffer *buf, int size)
Definition buffer.h:654
static void buf_reset(struct buffer *buf)
Definition buffer.h:303
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition buffer.c:483
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:1158
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Definition buffer.h:331
void chomp(char *str)
Definition buffer.c:614
struct buffer * buffer_list_peek(struct buffer_list *ol)
Retrieve the head buffer.
Definition buffer.c:1239
static bool buf_read(struct buffer *src, void *dest, int size)
Definition buffer.h:778
const char * np(const char *str)
Definition buffer.c:860
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:1073
#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:41
static bool buf_advance(struct buffer *buf, int size)
Definition buffer.h:618
static int buf_len(const struct buffer *buf)
Definition buffer.h:253
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Definition buffer.h:348
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:1167
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:336
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition buffer.h:414
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
Definition buffer.h:635
bool buf_assign(struct buffer *dest, const struct buffer *src)
Definition buffer.c:173
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:668
static uint8_t * buf_prepend(struct buffer *buf, int size)
Definition buffer.h:606
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:692
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:1041
struct buffer alloc_buf(size_t size)
Definition buffer.c:62
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:1090
static bool gc_defined(struct gc_arena *a)
Definition buffer.h:1006
void gc_addspecial(void *addr, void(*free_function)(void *), struct gc_arena *a)
Definition buffer.c:438
int string_array_len(const char **array)
Definition buffer.c:703
static int buf_read_u8(struct buffer *buf)
Definition buffer.h:790
#define BLEN(buf)
Definition buffer.h:127
static void buf_reset_len(struct buffer *buf)
Definition buffer.h:312
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:1358
void buf_rmtail(struct buffer *buf, uint8_t remove)
Definition buffer.c:518
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Definition buffer.c:825
void buf_size_error(const size_t size)
Definition buffer.c:53
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:649
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition buffer.h:361
static void gc_reset(struct gc_arena *a)
Definition buffer.h:1046
static void check_malloc_return(void *p)
Definition buffer.h:1103
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
static bool buf_copy_range(struct buffer *dest, int dest_index, const struct buffer *src, int src_index, int src_len)
Definition buffer.h:729
static char * buf_str(const struct buffer *buf)
Definition buffer.h:297
struct buffer string_alloc_buf(const char *str, struct gc_arena *gc)
Definition buffer.c:752
static bool buf_defined(const struct buffer *buf)
Definition buffer.h:228
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:1198
void x_gc_free(struct gc_arena *a)
Definition buffer.c:403
void buf_chomp(struct buffer *buf)
Definition buffer.c:554
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:877
static bool strprefix(const char *str, const char *prefix)
Return true iff str starts with prefix.
Definition buffer.h:977
bool buf_string_match_head_str(const struct buffer *src, const char *match)
Definition buffer.c:778
static uint32_t buf_read_u32(struct buffer *buf, bool *good)
Definition buffer.h:814
static void gc_freeaddrinfo_callback(void *addr)
Definition buffer.h:215
static struct gc_arena gc_new(void)
Definition buffer.h:1025
static uint8_t * buf_write_alloc_prepend(struct buffer *buf, int size, bool prepend)
Definition buffer.h:648
int buf_substring_len(const struct buffer *buf, int delim)
Definition buffer.c:803
static int buf_forward_capacity_total(const struct buffer *buf)
Definition buffer.h:559
void out_of_memory(void)
Definition error.c:460
Definition buffer.h:1115
struct buffer_entry * next
Definition buffer.h:1117
struct buffer buf
Definition buffer.h:1116
struct buffer_entry * tail
Definition buffer.h:1123
int max_size
Definition buffer.h:1125
struct buffer_entry * head
Definition buffer.h:1122
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:35
__attribute__((unused))
Definition test.c:42
struct gc_arena gc
Definition test_ssl.c:155