Regular binary buffers

Overview

Allocation of buffers, fill in by random numbers, etc. More…

// typedefs

typedef struct te_buf_pattern te_buf_pattern;

// structs

struct te_buf_pattern;

// global functions

te_errno te_compile_buf_pattern(const char* spec, uint8_t* storage, size_t max_size, te_buf_pattern* pattern);
void te_fill_pattern_buf(void* buf, size_t len, const te_buf_pattern* pattern);
void* te_make_pattern_buf(size_t min, size_t max, size_t* p_len, const te_buf_pattern* pattern);
te_errno te_fill_spec_buf(void* buf, size_t len, const char* spec);
void* te_make_spec_buf(size_t min, size_t max, size_t* p_len, const char* spec);
static void te_fill_buf(void* buf, size_t len);
static void* te_make_buf(size_t min, size_t max, size_t* p_len);
static void* te_make_buf_by_len(size_t len);
static void* te_make_buf_min(size_t min, size_t* p_len);
static void te_fill_printable_buf(void* buf, size_t len);
static char* te_make_printable_buf(size_t min, size_t max, size_t* p_len);
static char* te_make_printable_buf_by_len(size_t len);
static void* te_calloc_fill(size_t num, size_t size, int byte);
te_bool te_compare_bufs(const void* exp_buf, size_t exp_len, unsigned int n_copies, const void* actual_buf, size_t actual_len, unsigned int log_level);

// macros

#define TE_FILL_SPEC_ASCII
#define TE_FILL_SPEC_BINARY
#define TE_FILL_SPEC_C_ID
#define TE_FILL_SPEC_DECIMAL
#define TE_FILL_SPEC_FILENAME
#define TE_FILL_SPEC_HEX
#define TE_FILL_SPEC_HEX_LCASE
#define TE_FILL_SPEC_JSON_STR
#define TE_FILL_SPEC_PRINTABLE
#define TE_FILL_SPEC_TEXT
#define TE_FILL_SPEC_URI_CHUNK
#define TE_FILL_SPEC_WORD
#define TE_FILL_SPEC_XML_NAME
#define TE_FILL_SPEC_XML_TEXT

Detailed Documentation

Allocation of buffers, fill in by random numbers, etc.

Copyright (C) 2004-2022 OKTET Labs Ltd. All rights reserved.

Typedefs

typedef struct te_buf_pattern te_buf_pattern

Compiled buffer fill pattern.

The structure should be treated as opaque and only filled by te_compile_buf_pattern().

The compiled pattern is a sequence of “possible bytes”, where each “possible byte” is a number followed by that many byte values. If the number is zero, any byte is possible at that position.

Global Functions

te_errno te_compile_buf_pattern(const char* spec, uint8_t* storage, size_t max_size, te_buf_pattern* pattern)

Convert a textual pattern spec into a compiled pattern.

The pattern spec is a string consisting of three parts: prefix ```` (repeat ````) suffix, where both prefix and suffix are optional.

The resulting byte sequence is produced as follows:

  • first prefix is generated;

  • then repeat is repeated until there is only room for suffix

  • then suffix is generated.

If the buffer is shorter than the prefix and the suffix together, the suffix is laid over the prefix. This is slightly counter-intuitive, but it e.g. allows to ensure easily that a string would be zero-terminated.

Each part is a sequence of byte specs, which are either:

  • any verbatim bytes except an open bracket, a backtick and a binary zero;

  • a backtick followed by any byte including a binary zero;

  • a byte set.

A byte set is a sequence of elements enclosed in [ ... ], where each element is either:

  • any verbatim byte except a hyphen, a caret, a closing bracket, a backtick and a binary zero;

  • a backtick followed by any byte including a binary zero;

  • a range: a pair of bytes separated by -;

  • a literal unescaped hyphen if it’s the first or the last element of a byte set.

An empty byte set [] means any byte.

A byte set may also contain a right-associative exclusion operator ^ : A ^ B ^ C means “all bytes from A except (those in B except those in C); see below for examples.

The backtick was chosen as an escape character instead of a more common backslash in order to avoid double-escaping in C literals.

The compiled pattern is a sequence of “possible bytes”, where each “possible byte” is a number followed by that many byte values. If the number is zero, any byte is possible at that position.

The compiled pattern data are stored in storage which should be an array of at least max_size bytes. pattern holds pointers inside storage, so the latter should not have a shorter duration that the former.

  • "[0-9]" a sequence of decimal digits (not zero-terminated)

  • "[a-zA-Z_]([a-zA-Z0-9_])`\0" a valid C identifier (zero-terminated)

  • "[^`\0\x1-\x1F\x7F-\xFF^\n\t]" a sequence of printable ASCII characters + newline and tab

  • "[ -~\n\t]" a shorter version of the previous

  • "`[([0-9a-f])`]`\0" a zero-terminated sequence of hexadecimal digits enclosed in brackets

Parameters:

spec

pattern spec

storage

buffer to hold the compiled pattern

max_size

total size of storage

pattern

compiled pattern header (the structure is completely initialised by this function)

TE_ENOBUFS

There is not enough room in storage to hold the data.

TE_EILSEQ

An unmatched ```` [ or ```` ( is found.

TE_ENODATA

The spec contains no actual byte specs.

TE_EINVAL

The spec contains multiple repeat sections.

Returns:

status code

void te_fill_pattern_buf(void* buf, size_t len, const te_buf_pattern* pattern)

Fill buf of length len with random bytes according to a given pattern.

If pattern is NULL, the buffer is filled with unconstrained random bytes.

Parameters:

buf

buffer

len

length of buf

pattern

compiled pattern (see te_compile_buf_pattern())

void* te_make_pattern_buf(size_t min, size_t max, size_t* p_len, const te_buf_pattern* pattern)

Allocate a buffer of random size between min and max filled with random bytes according to pattern.

If pattern is NULL, the buffer is filled with unconstrained random bytes.

p_len may be NULL, if either min is equal to max, or spec contains a terminating NUL byte, since in this case the size may be determined by strlen().

Parameters:

min

minimum allowed size

max

maximum allowed size

p_len

actual size of the buffer (may be NULL)

pattern

compiled pattern (see te_compile_buf_pattern())

Returns:

an allocated and filled buffer (never NULL)

te_errno te_fill_spec_buf(void* buf, size_t len, const char* spec)

Fill buf of length len with random bytes according to a given spec.

The function only returns an error if spec is malformed. So callers that always pass known constant patterns to it, need not check for the return value.

Parameters:

buf

buffer

len

length of buf

spec

pattern spec (see te_compile_buf_pattern())

Returns:

status code

void* te_make_spec_buf(size_t min, size_t max, size_t* p_len, const char* spec)

Allocate a buffer of random size between min and max filled with random bytes according to spec.

p_len may be NULL, if either min is equal to max, or spec contains a terminating NUL byte, since in this case the size may be determined by strlen().

The function only returns NULL if spec is malformed. So callers that always pass known constant patterns to it, need not check for the return value being not NULL.

Parameters:

min

minimum allowed size

max

maximum allowed size

p_len

actual size of the buffer (may be NULL)

spec

pattern spec (see te_compile_buf_pattern())

Returns:

an allocated and filled buffer

static void te_fill_buf(void* buf, size_t len)

Fill buffer with random bytes.

Parameters:

buf

buffer pointer

len

buffer length

See also:

te_fill_pattern_buf()

static void* te_make_buf(size_t min, size_t max, size_t* p_len)

Allocate buffer of random size between min and max and fill it with random bytes.

Parameters:

min

minimum allowed size

max

maximum allowed size

p_len

actual size of the buffer (may be NULL if min is equal to max)

Returns:

an allocated and filled buffer

See also:

te_make_pattern_buf()

static void* te_make_buf_by_len(size_t len)

Allocate a buffer of given size len and fill it with random bytes.

Parameters:

len

buffer length

Returns:

an allocated and filled buffer

See also:

te_make_pattern_buf()

static void* te_make_buf_min(size_t min, size_t* p_len)

Allocate a buffer of at least min bytes and fill it with random bytes

Parameters:

min

minimum buffer length

p_len

actual buffer length

Returns:

an allocated and filled buffer

static void te_fill_printable_buf(void* buf, size_t len)

Fill a buffer with random printable characters.

The last byte will be zero, so the result may be used as a C string.

Parameters:

buf

buffer pointer

len

buffer length

See also:

te_fill_spec_buf()

static char* te_make_printable_buf(size_t min, size_t max, size_t* p_len)

Allocate buffer of random size between min and max and fill it with random printable characters. The buffer will be NUL-terminated, so it can be used as a C string.

Parameters:

min

minimum allowed size

max

maximum allowed size

p_len

actual size of the buffer (may be NULL)

Returns:

an allocated and filled buffer

See also:

te_make_spec_buf()

static char* te_make_printable_buf_by_len(size_t len)

Allocate a buffer of given size len and fill it with random printable characters. The buffer will be NUL-terminated.

Parameters:

len

buffer length

Returns:

an allocated and filled buffer

See also:

te_make_spec_buf()

static void* te_calloc_fill(size_t num, size_t size, int byte)

Allocate memory and fill it with the byte

Parameters:

num

Items number

size

Item instance size

byte

Byte to fill memory

Returns:

Pointer to the memory block

te_bool te_compare_bufs(const void* exp_buf, size_t exp_len, unsigned int n_copies, const void* actual_buf, size_t actual_len, unsigned int log_level)

Compare and probably log the difference of two buffers.

It can compare buffers of unequal size.

Unlike CHECK_BUFS_EQUAL(), it does not fail a test, so it can be used both in the Engine and agents.

Parameters:

exp_buf

Expected data.

exp_len

Length of expected data.

n_copies

Number of copies of the expected buffer that should be in the actual data.

actual_buf

Actual data.

actual_len

Length of actual data.

log_level

Log level for diff dumps. If zero, no logging is done.

Returns:

TRUE if the lengths and the content of buffers are the same.

Macros

#define TE_FILL_SPEC_ASCII

A random sequence of ASCII characters excluding NUL.

#define TE_FILL_SPEC_BINARY

A random sequence of bytes including NULs.

#define TE_FILL_SPEC_C_ID

A valid C identifier.

#define TE_FILL_SPEC_DECIMAL

Common fill patterns specs.

All sequences except TE_FILL_SPEC_BINARY are zero-terminated. A sequence of decimal digits.

#define TE_FILL_SPEC_FILENAME

A safe filename.

A name contains no directory separators, no wildcards, no spaces and no characters that may be interpreted by a shell, such as a dollar sign. A name also does not start with a dot.

#define TE_FILL_SPEC_HEX

A sequence of hex digits.

#define TE_FILL_SPEC_HEX_LCASE

A sequence of hex digits (lowercase variant).

#define TE_FILL_SPEC_JSON_STR

A valid content of a JSON string literal.

It contains any printable characters except quotes and backslashes.

#define TE_FILL_SPEC_PRINTABLE

A sequence of printable characters.

#define TE_FILL_SPEC_TEXT

A sequence of printable characters, tabs and newlines.

#define TE_FILL_SPEC_URI_CHUNK

A valid URI chunk.

It contains only RFC 3986 “unreserved” characters: alphanumerics, underscores, hyphens, periods and tildes.

#define TE_FILL_SPEC_WORD

A sequence of Latin letters.

#define TE_FILL_SPEC_XML_NAME

A valid XML name.

It contains only alphanumerics, underscores, hyphens and periods, and it starts with either an alphanumeric or an underscore.

#define TE_FILL_SPEC_XML_TEXT

A valid XML text.

It contains any printable characters except quotes, apostrophes, ampersands and angle brackets. It may contain newlines.