Go to the documentation of this file.
43 const size_t limit = 0xFFFFFFFF;
44 unsigned long long res = (
unsigned long long)m1 * (
unsigned long long)m2 + (
unsigned long long)extra;
47 msg(
M_FATAL,
"attempted allocation of excessively large array");
55 msg(
M_FATAL,
"fatal buffer size error, size=%lu", (
unsigned long)size);
60 alloc_buf_debug(size_t size, const char *file,
int line)
75 buf.
data = openvpn_dmalloc(file, line, size);
77 buf.
data = calloc(1, size);
86 alloc_buf_gc_debug(size_t size, struct
gc_arena *gc,
const char *file,
int line)
100 buf.
data = (uint8_t *) gc_malloc_debug(size,
false, gc, file, line);
113 clone_buf_debug(const struct
buffer *buf,
const char *file,
int line)
123 ret.
data = (uint8_t *) openvpn_dmalloc(file, line, buf->
capacity);
132 #ifdef BUF_INIT_TRACKING
135 buf_init_debug(
struct buffer *buf,
int offset,
const char *file,
int line)
137 buf->debug_file = file;
138 buf->debug_line = line;
145 return buf->debug_line;
151 return buf->debug_file;
156 #define buf_debug_line(buf) 0
157 #define buf_debug_file(buf) "[UNDEF]"
199 if ((uint8_t *)(*e + 1) == buf->
data)
246 uint8_t *ptr =
BEND(buf);
252 va_start(arglist, format);
253 stat = vsnprintf((
char *)ptr, cap, format, arglist);
256 buf->
len += (int) strlen((
char *)ptr);
257 if (stat >= 0 && stat < cap)
270 uint8_t *ptr =
BEND(buf);
276 buf->
len += (int) strlen((
char *)ptr);
291 size_t len = strlen(str) + 1;
305 uint8_t *cp =
BPTR(buf);
321 int fd =
platform_open(filename, O_CREAT | O_TRUNC | O_WRONLY,
325 msg(
M_ERRNO,
"Cannot open file '%s' for write", filename);
330 if (size !=
BLEN(buf))
332 msg(
M_ERRNO,
"Write error on file '%s'", filename);
340 msg(
M_ERRNO,
"Close error on file %s", filename);
352 gc_malloc_debug(
size_t size,
bool clear,
struct gc_arena *a,
const char *file,
int line)
362 e = (
struct gc_entry *) openvpn_dmalloc(file, line, size +
sizeof(
struct gc_entry));
367 ret = (
char *) e +
sizeof(
struct gc_entry);
374 ret = openvpn_dmalloc(file, line, size);
380 #ifndef ZERO_BUFFER_ON_ALLOC
383 memset(ret, 0, size);
390 void *ret = realloc(ptr, size);
394 if (ptr && ptr != ret)
485 while (e->
next != NULL)
502 unsigned int space_break_flags,
const char *separator,
506 const size_t separator_len = separator ? strlen(separator) : 0;
507 static_assert(INT_MAX <= SIZE_MAX,
"Code assumes INT_MAX <= SIZE_MAX");
508 const size_t out_len = maxoutput > 0 ? maxoutput :
509 ((size * 2) + ((size / bytes_per_hexblock) * separator_len) + 2);
512 for (
int i = 0; i < size; ++i)
514 if (separator && i && !(i % bytes_per_hexblock))
528 return (
char *)out.
data;
538 uint8_t *cp =
BLAST(buf);
539 if (cp && *cp == remove)
553 char *last = (
char *)
BLAST(buf);
554 if (last && *last ==
'\0')
576 char *last = (
char *)
BLAST(buf);
602 if (!(c ==
' ' || c ==
'\t'))
617 ASSERT(
len >= 0 && len <= capacity && capacity > 0);
624 *(str +
len - 1) =
'\0';
646 const size_t len = strlen(str);
650 char *cp = str + (
len - 1);
651 if (strchr(what_to_delete, *cp) != NULL)
665 string_alloc_debug(
const char *str,
struct gc_arena *gc,
const char *file,
int line)
672 const size_t n = strlen(str) + 1;
678 ret = (
char *) gc_malloc_debug(n,
false, gc, file, line);
690 ret = openvpn_dmalloc(file, line, n);
741 const char *cp = *p++;
768 string_alloc_buf_debug(const char *str,
struct gc_arena *gc,
const char *file,
int line)
778 buf_set_read(&buf, (uint8_t *) string_alloc_debug(str, gc, file, line), strlen(str) + 1);
798 const size_t size = strlen(match);
803 return memcmp(
BPTR(src), match, size) == 0;
858 if (c <= 0 || c == delim)
871 return !(eol && !strlen(line));
906 if ((flags &
CC_NULL) && c ==
'\0')
911 if ((flags &
CC_ALNUM) && isalnum(c))
915 if ((flags &
CC_ALPHA) && isalpha(c))
919 if ((flags &
CC_ASCII) && isascii(c))
923 if ((flags &
CC_CNTRL) && iscntrl(c))
927 if ((flags &
CC_DIGIT) && isdigit(c))
931 if ((flags &
CC_PRINT) && (c >= 32 && c != 127))
935 if ((flags &
CC_PUNCT) && ispunct(c))
939 if ((flags &
CC_SPACE) && isspace(c))
948 if ((flags &
CC_BLANK) && (c ==
' ' || c ==
'\t'))
956 if ((flags &
CC_CR) && c ==
'\r')
969 if ((flags &
CC_DASH) && c ==
'-')
973 if ((flags &
CC_DOT) && c ==
'.')
1001 if ((flags &
CC_AT) && c ==
'@')
1005 if ((flags &
CC_EQUAL) && c ==
'=')
1017 if ((flags &
CC_PIPE) && c ==
'|')
1034 char_inc_exc(
const char c,
const unsigned int inclusive,
const unsigned int exclusive)
1040 string_class(
const char *str,
const unsigned int inclusive,
const unsigned int exclusive)
1044 while ((c = *str++))
1059 string_mod(
char *str,
const unsigned int inclusive,
const unsigned int exclusive,
const char replace)
1061 const char *in = str;
1095 for (
int i = 0; i <
BLEN(buf); i++)
1097 char c =
BSTR(buf)[i];
1109 const unsigned int inclusive,
1110 const unsigned int exclusive,
1117 string_mod(buf, inclusive, exclusive, replace);
1144 #ifdef VERIFY_ALIGNMENT
1146 valign4(
const struct buffer *buf,
const char *file,
const int line)
1148 if (buf && buf->
len)
1151 const unsigned int u = (
unsigned int)
BPTR(buf);
1158 msg(msglevel,
"%sAlignment at %s/%d ptr=" ptr_format " OLC=%d/%d/%d I=%s/%d",
1197 return ol && ol->
head != NULL;
1220 const size_t len = strlen((
const char *)str);
1249 memcpy(e->
buf.
data, data, size);
1273 const size_t sep_len = strlen(sep);
1277 for (count = 0; more; ++count)
1279 size_t extra_len =
BLEN(&more->
buf) + sep_len;
1280 if (size + extra_len > max_len)
1296 for (
size_t i = 0; e && i < count; ++i)
1306 bl->
size -= count - 1;
1360 char *line = (
char *) malloc(max_line_len);
1364 while (fgets(line, max_line_len, fp) != NULL)
1378 struct buffer ret = { 0 };
1392 const size_t size = file_stat.st_size;
1394 size_t read_size = fread(
BPTR(&ret), 1, size, fp);
struct gc_entry * list
First element of the linked list of gc_entry structures.
static bool buf_safe(const struct buffer *buf, size_t len)
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
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
#define CC_BACKSLASH
backslash
void buf_rmtail(struct buffer *buf, uint8_t remove)
void gc_addspecial(void *addr, void(*free_function)(void *), struct gc_arena *a)
int string_array_len(const char **array)
static int buf_forward_capacity_total(const struct buffer *buf)
int len
Length in bytes of the actual content within the allocated memory.
struct gc_entry * next
Pointer to the next item in the linked list.
#define buf_init(buf, offset)
#define CC_UNDERBAR
underscore
#define static_assert(expr, diagnostic)
static bool buf_size_valid(const size_t size)
#define CC_ASTERISK
asterisk
void rm_trailing_chars(char *str, const char *what_to_delete)
size_t array_mult_safe(const size_t m1, const size_t m2, const size_t extra)
int capacity
Size in bytes of memory allocated by malloc().
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
void buf_null_terminate(struct buffer *buf)
#define CC_CRLF
carriage return or newline
Garbage collection entry for one dynamically allocated block of memory.
struct buffer * buffer_list_peek(struct buffer_list *ol)
Retrieve the head buffer.
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 .
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
void buf_clear(struct buffer *buf)
static bool buf_copy(struct buffer *dest, const struct buffer *src)
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
struct buffer clone_buf(const struct buffer *buf)
struct gc_entry_special * list_special
#define CC_ALNUM
alphanumeric isalnum()
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.
void x_gc_freespecial(struct gc_arena *a)
#define CC_NEWLINE
newline
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
#define CC_DOUBLE_QUOTE
double quote
char * string_alloc(const char *str, struct gc_arena *gc)
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
void string_clear(char *str)
void string_replace_leading(char *str, const char match, const char replace)
void buf_chomp(struct buffer *buf)
static bool buf_advance(struct buffer *buf, int size)
void buf_size_error(const size_t size)
static bool buf_inc_len(struct buffer *buf, int inc)
#define CC_QUESTION_MARK
question mark
#define CC_SINGLE_QUOTE
single quote
#define buf_debug_file(buf)
static bool buf_write_u8(struct buffer *dest, uint8_t data)
bool buf_assign(struct buffer *dest, const struct buffer *src)
#define CC_PRINT
printable (>= 32, != 127)
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...
struct buffer_entry * next
void buffer_list_push(struct buffer_list *ol, const char *str)
Allocates and appends a new buffer containing str as data to ol.
#define CC_LESS_THAN
less than sign
#define CC_GREATER_THAN
greater than sign
#define CC_CR
carriage return
bool char_class(const unsigned char c, const unsigned int flags)
void convert_to_one_line(struct buffer *buf)
#define CC_EQUAL
equal sign
void gc_transfer(struct gc_arena *dest, struct gc_arena *src)
#define CC_REVERSE_QUOTE
reverse quote
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.
#define CC_DIGIT
digit isdigit()
#define CC_BLANK
space or tab
Wrapper structure for dynamically allocated memory.
struct buffer_list * buffer_list_new(void)
Allocate an empty buffer list of capacity max_size.
#define CC_SPACE
whitespace isspace()
#define CC_ASCII
ASCII character.
static bool buf_write(struct buffer *dest, const void *src, size_t size)
#define CC_ANY
any character
const char * np(const char *str)
#define CC_ALPHA
alphabetic isalpha()
Garbage collection arena used to keep track of dynamically allocated memory.
static void free_buf_gc(struct buffer *buf, struct gc_arena *gc)
bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive)
#define CC_PUNCT
punctuation ispunct()
int offset
Offset in bytes of the actual content within the allocated memory.
static void strncpynt(char *dest, const char *src, size_t maxlen)
static bool buf_init_dowork(struct buffer *buf, int offset)
static uint8_t * buf_prepend(struct buffer *buf, int size)
struct buffer_entry * tail
void buffer_list_pop(struct buffer_list *ol)
Garbage collection entry for a specially allocated structure that needs a custom free function to be ...
bool buf_puts(struct buffer *buf, const char *str)
void free_buf(struct buffer *buf)
void string_null_terminate(char *str, int len, int capacity)
bool buf_string_match_head_str(const struct buffer *src, const char *match)
#define FHE_SPACE_BREAK_MASK
bool buf_string_compare_advance(struct buffer *src, const char *match)
void buffer_list_advance(struct buffer_list *ol, int n)
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
void x_gc_free(struct gc_arena *a)
struct buffer string_alloc_buf(const char *str, struct gc_arena *gc)
bool buffer_list_defined(const struct buffer_list *ol)
Checks if the list is valid and non-empty.
#define ALLOC_OBJ_CLEAR(dptr, type)
struct gc_entry_special * next
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
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 .
#define CC_NULL
null character \0
#define CC_XDIGIT
hex digit isxdigit()
static void check_malloc_return(void *p)
#define buf_debug_line(buf)
int buf_substring_len(const struct buffer *buf, int delim)
static int buf_read_u8(struct buffer *buf)
static int buf_forward_capacity(const struct buffer *buf)
char * print_argv(const char **p, struct gc_arena *gc, const unsigned int flags)
#define CC_CNTRL
control character iscntrl()
static bool char_inc_exc(const char c, const unsigned int inclusive, const unsigned int exclusive)
struct buffer alloc_buf(size_t size)
void buffer_list_reset(struct buffer_list *ol)
Empty the list ol and frees all the contained buffers.
const char * skip_leading_whitespace(const char *str)
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...
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
static bool buf_defined(const struct buffer *buf)
bool buf_printf(struct buffer *buf, const char *format,...)
struct buffer_entry * head
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
uint8_t * data
Pointer to the allocated memory.
void buf_catrunc(struct buffer *buf, const char *str)
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
static int cleanup(void **state)