26 #elif defined(_MSC_VER) 45 const size_t limit = 0xFFFFFFFF;
46 unsigned long long res = (
unsigned long long)m1 * (
unsigned long long)m2 + (
unsigned long long)extra;
49 msg(
M_FATAL,
"attempted allocation of excessively large array");
57 msg(
M_FATAL,
"fatal buffer size error, size=%lu", (
unsigned long)size);
62 alloc_buf_debug(size_t size, const char *file,
int line)
77 buf.
data = openvpn_dmalloc(file, line, size);
79 buf.
data = calloc(1, size);
88 alloc_buf_gc_debug(size_t size, struct gc_arena *gc,
const char *file,
int line)
102 buf.
data = (
uint8_t *) gc_malloc_debug(size,
false, gc, file, line);
115 clone_buf_debug(const struct buffer *buf,
const char *file,
int line)
134 #ifdef BUF_INIT_TRACKING 137 buf_init_debug(
struct buffer *buf,
int offset,
const char *file,
int line)
139 buf->debug_file = file;
140 buf->debug_line = line;
147 return buf->debug_line;
153 return buf->debug_file;
158 #define buf_debug_line(buf) 0 159 #define buf_debug_file(buf) "[UNDEF]" 223 buf_sub(struct buffer *buf,
int size,
bool prepend)
254 va_start(arglist, format);
255 stat =
vsnprintf((
char *)ptr, cap, format, arglist);
258 buf->
len += (int) strlen((
char *)ptr);
259 if (stat >= 0 && stat < cap)
278 buf->
len += (int) strlen((
char *)ptr);
302 va_start(arglist, format);
303 len =
vsnprintf(str, size, format, arglist);
307 return (len >= 0 && len < size);
324 va_start(arglist, format);
325 len = vswprintf(str, size, format, arglist);
327 str[size - 1] = L
'\0';
329 return (len >= 0 && len < size);
342 int len = (int) strlen(str) + 1;
372 int fd =
platform_open(filename, O_CREAT | O_TRUNC | O_WRONLY,
376 msg(
M_ERRNO,
"Cannot open file '%s' for write", filename);
381 if (size !=
BLEN(buf))
383 msg(
M_ERRNO,
"Write error on file '%s'", filename);
391 msg(
M_ERRNO,
"Close error on file %s", filename);
403 gc_malloc_debug(
size_t size,
bool clear,
struct gc_arena *a,
const char *file,
int line)
413 e = (
struct gc_entry *) openvpn_dmalloc(file, line, size +
sizeof(
struct gc_entry));
418 ret = (
char *) e +
sizeof(
struct gc_entry);
425 ret = openvpn_dmalloc(file, line, size);
431 #ifndef ZERO_BUFFER_ON_ALLOC 434 memset(ret, 0, size);
503 while (e->
next != NULL)
520 unsigned int space_break_flags,
const char *separator,
524 const size_t separator_len = separator ? strlen(separator) : 0;
525 static_assert(INT_MAX <= SIZE_MAX,
"Code assumes INT_MAX <= SIZE_MAX");
526 const size_t out_len = maxoutput > 0 ? maxoutput :
527 ((size * 2) + ((size / bytes_per_hexblock) * separator_len) + 2);
530 for (
int i = 0; i < size; ++i)
532 if (separator && i && !(i % bytes_per_hexblock))
546 return (
char *)out.
data;
557 if (cp && *cp ==
remove)
571 char *last = (
char *)
BLAST(buf);
572 if (last && *last ==
'\0')
594 char *last = (
char *)
BLAST(buf);
620 if (!(c ==
' ' || c ==
'\t'))
635 ASSERT(len >= 0 && len <= capacity && capacity > 0);
640 else if (len == capacity)
642 *(str + len - 1) =
'\0';
664 const int len = strlen(str);
668 char *cp = str + (len - 1);
669 if (strchr(what_to_delete, *cp) != NULL)
683 string_alloc_debug(
const char *str,
struct gc_arena *gc,
const char *file,
int line)
690 const int n = strlen(str) + 1;
696 ret = (
char *) gc_malloc_debug(n,
false, gc, file, line);
708 ret = openvpn_dmalloc(file, line, n);
760 const char *cp = *p++;
787 string_alloc_buf_debug(const char *str,
struct gc_arena *gc,
const char *file,
int line)
817 const int size = strlen(match);
818 if (size < 0 || size > src->
len)
822 return memcmp(
BPTR(src), match, size) == 0;
843 struct buffer tmp = *buf;
862 buf_parse(
struct buffer *buf,
const int delim,
char *line,
const int size)
877 if (c <= 0 || c == delim)
890 return !(eol && !strlen(line));
925 if ((flags &
CC_NULL) && c ==
'\0')
930 if ((flags &
CC_ALNUM) && isalnum(c))
934 if ((flags &
CC_ALPHA) && isalpha(c))
938 if ((flags &
CC_ASCII) && isascii(c))
942 if ((flags &
CC_CNTRL) && iscntrl(c))
946 if ((flags &
CC_DIGIT) && isdigit(c))
950 if ((flags &
CC_PRINT) && (c >= 32 && c != 127))
954 if ((flags &
CC_PUNCT) && ispunct(c))
958 if ((flags &
CC_SPACE) && isspace(c))
967 if ((flags &
CC_BLANK) && (c ==
' ' || c ==
'\t'))
975 if ((flags &
CC_CR) && c ==
'\r')
988 if ((flags &
CC_DASH) && c ==
'-')
992 if ((flags &
CC_DOT) && c ==
'.')
1000 if ((flags &
CC_COLON) && c ==
':')
1004 if ((flags &
CC_SLASH) && c ==
'/')
1020 if ((flags &
CC_AT) && c ==
'@')
1024 if ((flags &
CC_EQUAL) && c ==
'=')
1036 if ((flags &
CC_PIPE) && c ==
'|')
1053 char_inc_exc(
const char c,
const unsigned int inclusive,
const unsigned int exclusive)
1059 string_class(
const char *str,
const unsigned int inclusive,
const unsigned int exclusive)
1063 while ((c = *str++))
1078 string_mod(
char *str,
const unsigned int inclusive,
const unsigned int exclusive,
const char replace)
1080 const char *in = str;
1111 const unsigned int inclusive,
1112 const unsigned int exclusive,
1114 struct gc_arena *gc)
1119 string_mod(buf, inclusive, exclusive, replace);
1146 #ifdef CHARACTER_CLASS_DEBUG 1148 #define CC_INCLUDE (CC_PRINT) 1149 #define CC_EXCLUDE (0) 1150 #define CC_REPLACE ('.') 1153 character_class_debug(
void)
1157 while (fgets(buf,
sizeof(buf), stdin) != NULL)
1159 string_mod(buf, CC_INCLUDE, CC_EXCLUDE, CC_REPLACE);
1166 #ifdef VERIFY_ALIGNMENT 1168 valign4(
const struct buffer *buf,
const char *file,
const int line)
1170 if (buf && buf->
len)
1173 const unsigned int u = (
unsigned int)
BPTR(buf);
1180 msg(msglevel,
"%sAlignment at %s/%d ptr=" ptr_format " OLC=%d/%d/%d I=%s/%d",
1220 return ol && ol->
head != NULL;
1243 const size_t len = strlen((
const char *)str);
1272 memcpy(e->
buf.
data, data, size);
1296 const int sep_len = strlen(sep);
1300 for (count = 0; more; ++count)
1302 size_t extra_len =
BLEN(&more->
buf) + sep_len;
1303 if (size + extra_len > max_len)
1319 for (
size_t i = 0; e && i < count; ++i)
1329 bl->
size -= count - 1;
1366 struct buffer *buf = &ol->
head->
buf;
1383 char *line = (
char *)
malloc(max_line_len);
1387 while (fgets(line, max_line_len, fp) != NULL)
1401 struct buffer ret = { 0 };
1415 const size_t size = file_stat.st_size;
1417 ssize_t read_size = fread(
BPTR(&ret), 1, size, fp);
bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive)
static bool buf_write_u8(struct buffer *dest, int data)
static void strncpynt(char *dest, const char *src, size_t maxlen)
bool buffer_list_defined(const struct buffer_list *ol)
Checks if the list is valid and non-empty.
void free_buf(struct buffer *buf)
char * string_alloc(const char *str, struct gc_arena *gc)
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
void string_clear(char *str)
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
static bool buf_advance(struct buffer *buf, int size)
#define FHE_SPACE_BREAK_MASK
struct buffer_entry * head
bool char_class(const unsigned char c, const unsigned int flags)
struct buffer string_alloc_buf(const char *str, struct gc_arena *gc)
#define buf_debug_file(buf)
bool buf_assign(struct buffer *dest, const struct buffer *src)
static bool buf_safe(const struct buffer *buf, int len)
struct buffer_list * buffer_list_new(const int max_size)
Allocate an empty buffer list of capacity max_size.
void gc_transfer(struct gc_arena *dest, struct gc_arena *src)
struct gc_entry_special * next
#define static_assert(expr, diagnostic)
static uint8_t * buf_write_alloc(struct buffer *buf, int size)
struct gc_entry * next
Pointer to the next item in the linked list.
struct buffer alloc_buf(size_t size)
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
static bool match(const WIN32_FIND_DATA *find, LPCTSTR ext)
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 ...
bool buf_printf(struct buffer *buf, const char *format,...)
static int buf_read_u8(struct buffer *buf)
char * print_argv(const char **p, struct gc_arena *gc, const unsigned int flags)
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
struct buffer_entry * tail
static bool char_inc_exc(const char c, const unsigned int inclusive, const unsigned int exclusive)
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
const char * np(const char *str)
const char * skip_leading_whitespace(const char *str)
int offset
Offset in bytes of the actual content within the allocated memory.
Garbage collection entry for a specially allocated structure that needs a custom free function to be ...
int capacity
Size in bytes of memory allocated by malloc().
int len
Length in bytes of the actual content within the allocated memory.
void string_null_terminate(char *str, int len, int capacity)
static bool buf_write(struct buffer *dest, const void *src, int size)
Garbage collection entry for one dynamically allocated block of memory.
bool openvpn_snprintf(char *str, size_t size, const char *format,...)
static bool buf_size_valid(const size_t size)
static uint8_t * buf_prepend(struct buffer *buf, int size)
static bool buf_init_dowork(struct buffer *buf, int offset)
void gc_addspecial(void *addr, void(*free_function)(void *), struct gc_arena *a)
bool buf_puts(struct buffer *buf, const char *str)
void x_gc_free(struct gc_arena *a)
void rm_trailing_chars(char *str, const char *what_to_delete)
void buf_null_terminate(struct buffer *buf)
#define ALLOC_OBJ_CLEAR(dptr, type)
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
void buffer_list_advance(struct buffer_list *ol, int n)
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
size_t array_mult_safe(const size_t m1, const size_t m2, const size_t extra)
struct gc_entry * list
First element of the linked list of gc_entry structures.
static int buf_forward_capacity(const struct buffer *buf)
void buf_clear(struct buffer *buf)
void buffer_list_reset(struct buffer_list *ol)
Empty the list ol and frees all the contained buffers.
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)
int buf_substring_len(const struct buffer *buf, int delim)
#define buf_debug_line(buf)
uint8_t * data
Pointer to the allocated memory.
void buf_chomp(struct buffer *buf)
void buf_size_error(const size_t size)
void buf_catrunc(struct buffer *buf, 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)
void x_gc_freespecial(struct gc_arena *a)
struct buffer_entry * next
static bool buf_defined(const struct buffer *buf)
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
void buffer_list_push(struct buffer_list *ol, const char *str)
Allocates and appends a new buffer containing str as data to ol.
int string_array_len(const char **array)
struct gc_entry_special * list_special
static bool buf_inc_len(struct buffer *buf, int inc)
static void check_malloc_return(const void *p)
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
void string_replace_leading(char *str, const char match, const char replace)
Wrapper structure for dynamically allocated memory.
#define buf_init(buf, offset)
void buf_rmtail(struct buffer *buf, uint8_t remove)
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
void convert_to_one_line(struct buffer *buf)
static int buf_forward_capacity_total(const struct buffer *buf)
bool openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const format,...)
static void free_buf_gc(struct buffer *buf, struct gc_arena *gc)
struct buffer clone_buf(const struct buffer *buf)
void buffer_list_pop(struct buffer_list *ol)
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_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.
static void buf_set_read(struct buffer *buf, const uint8_t *data, int size)
bool buf_string_match_head_str(const struct buffer *src, const char *match)
bool buf_string_compare_advance(struct buffer *src, const char *match)