Assuming this input data:
char input[] = {
0x01, 0x02, 0x0a, 0x0b, /* A 32bit integer */
'h', 'e', 'l', 'l', 'o', 0x00,
'w', 'o', 'r', 'l', 'd', 0x00,
0x00 /* Necessary to make the end of the payload. */
};
A 32 integer in the beginning gives:
const size_t header_size = sizeof (uint32_t);
Parsing the input can be done by identifying the "string"'s 1st character and storing a pointer to it and then moving on exactly as much as the string found is long (1+) then start over until the end of input had been reached.
size_t strings_elements = 1; /* Set this to which ever start size you like. */
size_t delta = 1; /* 1 is conservative and slow for larger input,
increase as needed. */
/* Result as array of pointers to "string": */
char ** strings = malloc(strings_elements * sizeof *strings);
{
char * pc = input + header_size;
size_t strings_found = 0;
/* Parse input, if necessary increase result array, and populate its elements: */
while ('\0' != *pc)
{
if (strings_found >= strings_elements)
{
strings_elements += delta;
void * pvtmp = realloc(
strings,
(strings_elements + 1) * sizeof *strings /* Allocate one more to have a
stopper, being set to NULL as a sentinel.*/
);
if (NULL == pvtmp)
{
perror("realloc() failed");
exit(EXIT_FAILURE);
}
strings = pvtmp;
}
strings[strings_found] = pc;
++strings_found;
pc += strlen(pc) + 1;
}
strings[strings_found] = NULL; /* Set a stopper element.
NULL terminate the pointer array. */
}
/* Print result: */
{
char ** ppc = strings;
for(; NULL != *ppc; ++ppc)
{
printf("%zu: '%s'\n", ppc - strings + 1, *ppc)
}
}
/* Clean up: */
free(strings);
If you need to copy on split, replace this line
strings[strings_found] = pc;
by
strings[strings_found] = strdup(pc);
and add clean-up code after using and before free()
ing strings
:
{
char ** ppc = strings;
for(; NULL != *ppc; ++ppc)
{
free(*ppc);
}
}
The code above assume that at least 1 '\0'
(NUL
aka null-character) follows the payload.
If the latter condition is not met you need to either have any other terminating sequence be defined/around or need know the size of the input from some other source. If you don't your issue is not solvable.
The code above needs the following headers:
#include <inttypes.h> /* for int32_t */
#include <stdio.h> /* for printf(), perror() */
#include <string.h> /* for strlen() */
#include <stdlib.h> /* for realloc(), free(), exit() */
as well as it might need one of the following defines:
#define _POSIX_C_SOURCE 200809L
#define _GNU_SOURCE
or what else your C compiler requires to make strdup()
available.