From 992784d169e8255c9f53ad477ca429e0ca6c903b Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Sat, 29 Mar 2025 09:34:03 +0100 Subject: [PATCH] clean payload parsing --- morep_valid.c | 111 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 38 deletions(-) diff --git a/morep_valid.c b/morep_valid.c index f40d094..cc7008b 100644 --- a/morep_valid.c +++ b/morep_valid.c @@ -49,36 +49,99 @@ void sig_handler (int sig) } } -char *readstream (FILE *sd, int *length) +char *read_stream (FILE *sd, int *plen) { - VERBOSE (morep, TRACE, PRINTF ("readstream\n")); + VERBOSE (morep, TRACE, PRINTF ("read_stream\n")); + /* read and store */ char *buffer = NULL; size_t size = 0; int blocklen = 0; - int _length = 0; + int length = 0; do { size += BUFMAX + (size == 0); buffer = (char *) realloc (buffer, size); memset (buffer + size - BUFMAX - 1, 0, BUFMAX + 1); blocklen = fread (buffer + size - BUFMAX - 1, 1, BUFMAX, sd); - _length += blocklen; - VERBOSE (morep, DEBUG, PRINTF ("buffer: 0x%p 0x%p %d %d %d\n", buffer, buffer + size - BUFMAX - 1, (int)size, _length, blocklen)); + length += blocklen; + VERBOSE (morep, DEBUG, PRINTF ("buffer: 0x%p 0x%p %d %d %d\n", buffer, buffer + size - BUFMAX - 1, (int)size, length, blocklen)); } while (blocklen > 0); /* check size */ - VERBOSE (morep, DEBUG, PRINTF ("read length: %d\n", _length)); - if (_length == 0) { + VERBOSE (morep, DEBUG, PRINTF ("read length: %d\n", length)); + if (length == 0) { free (buffer); buffer = NULL; } - if (length) { - *length = _length; + + if (plen) { + *plen = length; } return buffer; } +uint8_t *parse_payload (char *value, int *plen) +{ + int slen = strlen (value); + uint8_t *payload = NULL; + int length = 0; + + /* string payload: "..." */ + if ((*value == '"') && (slen > 1)) { + if (value[slen - 1] == '"') { + length = slen - 2; + payload = (uint8_t *) calloc (length + 1, 1); + memcpy (payload, value + 1, length); + } else { + VERBOSE (morep, ERROR, PRINTF ("incomplet string '%s'\n", value)); + } + } + + /* file payload: @filename */ + else if (*value == '@') { + FILE *fid = fopen (value + 1, "r"); + if (fid != NULL) { + payload = (uint8_t *) read_stream (fid, &length); + fclose (fid); + } else { + VERBOSE (morep, ERROR, PRINTF ("can't open file '%s'\n", value)); + } + } + + /* hexa string: xxxxxx */ + else if (slen % 2 == 0) { + length = slen / 2; + payload = (uint8_t *) calloc (length, 1); + int i; + for (i = 0; i < length; i++) { + char digit[3] = {0}; + char *ptr = NULL; + digit[0] = value[2 * i]; + digit[1] = value[2 * i + 1]; + payload[i] = strtol (digit, &ptr, 16); + if (*ptr != '\0') { + VERBOSE (morep, ERROR, PRINTF ("unrecognize hexa string (%d) '%s'\n", 2 * i, value)); + free (payload); + payload = NULL; + break; + } + } + } + + /* unrecognize format */ + else { + VERBOSE (morep, WARNING, PRINTF ("can't parse payload '%s'\n", value)); + } + + if (plen) { + *plen = length; + } + + return payload; +} + + int parse_line (char *line, uint8_t *msgtype, uint8_t **payload) { int rc = -1; @@ -106,35 +169,7 @@ int parse_line (char *line, uint8_t *msgtype, uint8_t **payload) rc = 0; } } else if (strcmp ("PAYLOAD", var) == 0) { - if ((*val == '"') && (val[strlen (val) - 1] == '"')) { - val++; - rc = strlen (val); - uint8_t *buf = *payload = (uint8_t *) calloc (rc, 1); - do { - *buf++ = *val++; - } while (*val != '\0'); - buf[-1] = '\0'; - } else if (*val == '@') { - FILE *fid = fopen (++val, "r"); - if (fid == NULL) { - VERBOSE (morep, ERROR, PRINTF ("can't open file '%s'\n", val)); - break; - } - *payload = (uint8_t *) readstream (fid, &rc); - fclose (fid); - } else if (strlen (val) % 2 == 0) { - rc = strlen (val) / 2; - uint8_t *buf = *payload = (uint8_t *) calloc (rc, 1); - while (*val != '\0') { - char digit[3] = {0}; - digit[0] = *val++; - digit[1] = *val++; - *buf++ = strtol (digit, NULL, 16); - } - } else { - VERBOSE (morep, WARNING, PRINTF ("can't parse payload '%s'\n", val)); - break; - } + *payload = parse_payload (val, &rc); } else { VERBOSE (morep, WARNING, PRINTF ("unknown word '%s'\n", var)); break; -- 2.30.2