43 unsigned long long res =
44 (
unsigned long long)m1 * (
unsigned long long)m2 + (
unsigned long long)extra;
48 msg(
M_FATAL,
"attempted allocation of excessively large array");
56 msg(
M_FATAL,
"fatal buffer size error, size=%zu", size);
106#ifdef BUF_INIT_TRACKING
107 ret.debug_file = buf->debug_file;
108 ret.debug_line = buf->debug_line;
116#ifdef BUF_INIT_TRACKING
121 buf->debug_file = file;
122 buf->debug_line =
line;
126#ifdef VERIFY_ALIGNMENT
130 return buf->debug_line;
136 return buf->debug_file;
142#define buf_debug_line(buf) 0
143#define buf_debug_file(buf) "[UNDEF]"
185 if ((uint8_t *)(*e + 1) == buf->
data)
292 msg(
M_ERRNO,
"Cannot open file '%s' for write", filename);
297 if (size !=
BLEN(buf))
299 msg(
M_ERRNO,
"Write error on file '%s'", filename);
307 msg(
M_ERRNO,
"Close error on file %s", filename);
326 ret = (
char *)e +
sizeof(
struct gc_entry);
335#ifndef ZERO_BUFFER_ON_ALLOC
338 memset(ret, 0, size);
345 void *ret = realloc(ptr, size);
349 if (ptr && ptr != ret)
436 while (e->
next != NULL)
452format_hex_ex(
const uint8_t *data,
size_t size,
size_t maxoutput,
unsigned int space_break_flags,
456 const size_t separator_len = separator ? strlen(separator) : 0;
457 const size_t out_len = maxoutput > 0
459 : ((size * 2) + ((size / bytes_per_hexblock) * separator_len) + 2);
462 for (
size_t i = 0;
i < size; ++
i)
478 return (
char *)out.
data;
504 if (last && *last ==
'\0')
552 if (!(
c ==
' ' ||
c ==
'\t'))
681 const char *
cp = *
p++;
806 line[size - 1] =
'\0';
876 if ((flags &
CC_PRINT) && (
c >= 32 &&
c != 127))
893 if ((flags &
CC_BLANK) && (
c ==
' ' ||
c ==
'\t'))
901 if ((flags &
CC_CR) &&
c ==
'\r')
918 if ((flags &
CC_DOT) &&
c ==
'.')
1008 const char *in =
str;
1042 for (
int i = 0;
i <
BLEN(buf);
i++)
1131#ifdef VERIFY_ALIGNMENT
1135 if (buf && buf->
len)
1145 msg(msglevel,
"%sAlignment at %s/%d ptr=" ptr_format " OLC=%d/%d/%d I=%s/%d",
1177 return ol && ol->
head != NULL && ol->
size > 0;
1200 const size_t len = strlen((
const char *)str);
1229 memcpy(e->
buf.
data, data, size);
1242 return &
ol->head->buf;
1257 for (; more; ++count)
1259 size_t extra_len =
BLENZ(&more->
buf) + sep_len;
1260 if (size + extra_len > max_len)
1276 for (
size_t i = 0; e && i < count; ++i)
1286 bl->
size -= count - 1;
1323 struct buffer *buf = &
ol->head->buf;
1340 char *line = (
char *)malloc(max_line_len);
1344 while (fgets(line, max_line_len, fp) != NULL)
bool buffer_list_defined(const struct buffer_list *ol)
Checks if the list is valid and non-empty.
bool buf_string_compare_advance(struct buffer *src, const char *match)
Compare the head of src with match and advance past it if equal.
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 rm_trailing_chars(char *str, const char *what_to_delete)
Remove all trailing characters that appear in a given set.
void string_null_terminate(char *str, int len, int capacity)
Null-terminate a fixed-length string buffer.
void free_buf(struct buffer *buf)
Free the memory allocated for a 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 .
static bool char_inc_exc(const char c, const unsigned int inclusive, const unsigned int exclusive)
void buf_clear(struct buffer *buf)
Zeroise and reset a buffer.
void buffer_list_reset(struct buffer_list *ol)
Empty the list ol and frees all the contained buffers.
static void free_buf_gc(struct buffer *buf, struct gc_arena *gc)
const char * skip_leading_whitespace(const char *str)
Return a pointer past any leading whitespace in a string.
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 .
struct buffer clone_buf(const struct buffer *buf)
Duplicate a buffer, including its content.
void x_gc_freespecial(struct gc_arena *a)
Free all specially-allocated entries in a garbage collection arena.
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
void buf_catrunc(struct buffer *buf, const char *str)
Append a string to the physical end of a buffer that was truncated by buf_printf().
#define buf_debug_file(buf)
void buffer_list_pop(struct buffer_list *ol)
Remove and free the head buffer of the list.
bool buf_printf(struct buffer *buf, const char *format,...)
printf-style append to a buffer with overflow check.
void string_replace_leading(char *str, const char match, const char replace)
Replace all leading occurrences of a character in a string.
bool buf_puts(struct buffer *buf, const char *str)
Append a string to a buffer with overflow check.
char * buf_extract_field(struct buffer *buf, char sep, struct gc_arena *gc)
Extract a field from buf that ends with the sep character.
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
Read a file into a buffer list, one buffer per line.
void string_clear(char *str)
Securely clear a null-terminated string.
#define buf_debug_line(buf)
void gc_transfer(struct gc_arena *dest, struct gc_arena *src)
Move all allocations from one garbage collection arena to another.
bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive)
Test whether all characters in a string satisfy a character class filter.
char * print_argv(const char **p, struct gc_arena *gc, const unsigned int flags)
Format a NULL-terminated argument vector as a single string.
void buf_null_terminate(struct buffer *buf)
Force a null terminator at the end of the buffer content.
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
Return a sub-buffer of another buffer.
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
struct buffer_list * buffer_list_new(void)
Allocate an empty buffer list of capacity max_size.
void chomp(char *str)
Remove trailing newline and carriage-return characters from a string.
struct buffer * buffer_list_peek(struct buffer_list *ol)
Retrieve the head buffer.
const char * np(const char *str)
Return a printable representation of a string that might be NULL.
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.
bool string_defined_equal(const char *s1, const char *s2)
size_t array_mult_safe(const size_t m1, const size_t m2, const size_t extra)
Safely compute the product of two sizes plus an extra amount.
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Allocate memory and, optionally, zero it.
bool buf_assign(struct buffer *dest, const struct buffer *src)
Assign the content of one buffer to another.
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
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)
Format a binary buffer as a hex string.
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 alloc_buf(size_t size)
Allocate a buffer of the given size.
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_addspecial(void *addr, void(*free_function)(void *), struct gc_arena *a)
Register an address with a custom free function in a garbage collection arena.
void buffer_list_advance(struct buffer_list *ol, ssize_t n)
Advance past n bytes in the head buffer, popping it if it becomes empty.
int string_array_len(const char **array)
Return the number of elements in a NULL-terminated array of strings.
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
void buf_rmtail(struct buffer *buf, uint8_t remove)
Remove all occurrences of a specific byte from the end of a buffer.
char * string_substitute(const char *src, char from, char to, struct gc_arena *gc)
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Extract the next token from a buffer, delimited by a given character.
bool checked_snprintf(char *str, size_t size, const char *format,...)
Like snprintf() but returns an boolean.
void buf_size_error(const size_t size)
Report a buffer size error and abort.
char * string_alloc(const char *str, struct gc_arena *gc)
Duplicate a string, allocating memory under garbage collection.
struct buffer string_alloc_buf(const char *str, struct gc_arena *gc)
Allocate a buffer containing a copy of the given string.
void buffer_list_push(struct buffer_list *ol, const char *str)
Allocates and appends a new buffer containing str as data to ol.
void x_gc_free(struct gc_arena *a)
Free all plain allocations in a garbage collection arena.
void buf_chomp(struct buffer *buf)
Remove trailing newline and carriage-return characters from a buffer.
bool char_class(const unsigned char c, const unsigned int flags)
Test whether a character belongs to one or more character classes.
bool buf_string_match_head_str(const struct buffer *src, const char *match)
Return true if the head of src matches the string match.
int buf_substring_len(const struct buffer *buf, int delim)
Return the number of bytes in a buffer up to and including a delimiter.
Buffer management functions and garbage collection.
#define CC_EXCLAMATION
exclamation mark
#define CC_PERCENT
percent sign
#define BEND(buf)
Return a pointer one past the end of the buffer content.
static bool buf_size_valid(const size_t size)
Return true iff size is within the allowed buffer size range.
#define CC_DOUBLE_QUOTE
double quote
#define BLAST(buf)
Return a pointer to the last byte of the buffer content, or NULL if empty.
#define CC_BLANK
space or tab
static bool buf_init_dowork(struct buffer *buf, int offset)
Initialise a buffer with a given initial offset.
#define BSTR(buf)
Return the buffer content pointer cast to char *.
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Copy the content of one buffer to the end of another.
#define CC_ANY
any character
#define BPTR(buf)
Return a pointer to the start of the buffer content.
static int buf_peek_u8(struct buffer *buf)
Return the first byte of the buffer without consuming it.
#define CC_XDIGIT
hex digit isxdigit()
#define CC_SINGLE_QUOTE
single quote
static bool buf_inc_len(struct buffer *buf, int inc)
Increase or decrease the length of a buffer.
#define CC_DIGIT
digit isdigit()
static bool buf_valid(const struct buffer *buf)
Return true iff buf is valid.
#define PA_BRACKET
Flag for print_argv(): wrap each argument in square brackets.
#define CC_CRLF
carriage return or newline
static bool buf_safe(const struct buffer *buf, size_t len)
Check whether len bytes can be appended to a buffer.
#define ALLOC_SIZE_MAX
Maximum size for a single array allocation (checked by array_mult_safe()).
#define CC_ASTERISK
asterisk
#define CC_ALPHA
alphabetic isalpha()
#define CC_NEWLINE
newline
static uint8_t * buf_prepend(struct buffer *buf, ssize_t size)
Make space at the front of a buffer for prepending data.
static int buf_len(const struct buffer *buf)
Return the length of the buffer content.
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Initialise a buffer with an externally provided read-only memory region.
static int buf_forward_capacity(const struct buffer *buf)
Return the number of bytes that can still be appended to the buffer.
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
Reserve space at the end of a buffer for writing.
static bool buf_advance(struct buffer *buf, ssize_t size)
Advance the content start of a buffer, consuming bytes from the front.
#define CC_REVERSE_QUOTE
reverse quote
#define CC_SPACE
whitespace isspace()
#define CC_ASCII
ASCII character.
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Append data to a buffer.
#define CC_BACKSLASH
backslash
#define CC_CNTRL
control character iscntrl()
#define CC_LESS_THAN
less than sign
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Append a uint8_t to a buffer.
static int buf_read_u8(struct buffer *buf)
Read and consume a uint8_t from the front of a buffer.
#define BLEN(buf)
Return the length of the buffer content in bytes.
#define CC_CR
carriage return
#define CC_UNDERBAR
underscore
#define CC_GREATER_THAN
greater than sign
#define BLENZ(buf)
Return the length of the buffer content as a size_t.
void buf_size_error(const size_t size)
Report a buffer size error and abort.
static void strncpynt(char *dest, const char *src, size_t maxlen)
Like strncpy() but always null-terminates the destination.
static void check_malloc_return(void *p)
Abort if a memory allocation returned NULL.
#define CC_NULL
null character \0
#define CC_PRINT
printable (>= 32, != 127)
#define CC_QUESTION_MARK
question mark
#define ALLOC_OBJ_CLEAR(dptr, type)
Allocate and zero-initialise memory for a single object of the given type.
static bool buf_defined(const struct buffer *buf)
Return true iff buf has a non-NULL data pointer.
#define CC_ALNUM
alphanumeric isalnum()
#define buf_init(buf, offset)
#define FHE_SPACE_BREAK_MASK
Mask for the space_break_flags field of format_hex_ex(): number of bytes between separators (lower 8 ...
#define CC_PUNCT
punctuation ispunct()
#define FHE_CAPS
Flag for format_hex_ex(): output hex digits in upper case.
static int buf_forward_capacity_total(const struct buffer *buf)
Return the total number of bytes available from the current offset to the end of the allocated memory...
One node in a buffer_list linked list.
struct buffer_entry * next
Pointer to the next node, or NULL.
struct buffer buf
The buffer stored in this list node.
A singly-linked list of buffers, with head/tail pointers for O(1) push.
size_t size
Current number of entries.
struct buffer_entry * tail
Last item pushed.
struct buffer_entry * head
Next item to pop/peek.
Wrapper structure for dynamically allocated memory.
int capacity
Size in bytes of memory allocated by malloc().
uint8_t * data
Pointer to the allocated memory.
int len
Length in bytes of the actual content within the allocated memory.
int offset
Offset in bytes of the actual content within the allocated memory.
Garbage collection arena used to keep track of dynamically allocated memory.
struct gc_entry_special * list_special
First element of the linked list of gc_entry_special structures for allocations requiring a custom fr...
struct gc_entry * list
First element of the linked list of gc_entry structures.
Garbage collection entry for a specially allocated structure that needs a custom free function to be ...
struct gc_entry_special * next
Garbage collection entry for one dynamically allocated block of memory.
struct gc_entry * next
Pointer to the next item in the linked list.
static int cleanup(void **state)