c-json-stdout: fixed broken buffering

Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
This commit is contained in:
Toni Uhlig
2020-08-14 15:24:40 +02:00
parent 4b9b695946
commit 37e46a506a

View File

@@ -23,7 +23,7 @@ int main(void)
uint8_t buf[NETWORK_BUFFER_MAX_SIZE];
size_t buf_used = 0;
size_t json_start = 0;
unsigned long long int buf_wanted = 0;
unsigned long long int json_bytes = 0;
#ifdef USE_JSON
jsmn_parser parser;
jsmntok_t tokens[128];
@@ -60,78 +60,80 @@ int main(void)
}
buf_used += bytes_read;
if (buf_wanted == 0)
while (json_bytes == 0 && buf_used >= nDPIsrvd_JSON_BYTES + 1)
{
if (buf[nDPIsrvd_JSON_BYTES] != '{')
{
fprintf(stderr, "BUG: JSON invalid opening character: '%c'", buf[nDPIsrvd_JSON_BYTES]);
exit(1);
}
char * json_str_start = NULL;
errno = 0;
/* the first bytes are the textual representation of the following JSON string */
buf_wanted = strtoull((char *)buf, &json_str_start, 10);
json_bytes = strtoull((char *)buf, &json_str_start, 10);
json_bytes += (uint8_t *)json_str_start - buf;
json_start = (uint8_t *)json_str_start - buf;
buf_wanted += json_start;
if (errno == ERANGE)
{
buf_used = 0;
buf_wanted = 0;
fprintf(stderr, "Size of JSON exceeds limit\n");
continue;
fprintf(stderr, "BUG: Size of JSON exceeds limit");
exit(1);
}
if ((uint8_t *)json_str_start == buf)
{
fprintf(stderr, "Missing size before JSON string: %.*s\n", (int)buf_used, buf);
buf_used = 0;
buf_wanted = 0;
continue;
fprintf(stderr, "BUG: Missing size before JSON string: \"%.*s\"", nDPIsrvd_JSON_BYTES, buf);
exit(1);
}
if (buf_wanted > sizeof(buf))
if (json_bytes > sizeof(buf))
{
fprintf(stderr, "BUG: JSON string too big: %llu > %zu\n", buf_wanted, sizeof(buf));
buf_used = 0;
buf_wanted = 0;
continue;
fprintf(stderr, "BUG: JSON string too big: %llu > %zu", json_bytes, sizeof(buf));
exit(1);
}
if (json_bytes > buf_used)
{
break;
}
}
/* buffered enough data (full JSON String) ? */
if (buf_wanted > buf_used)
{
continue;
}
/* after buffering complete, last character should always be a '}' (end of object) */
if (buf[buf_wanted - 1] != '}')
{
fprintf(stderr, "Invalid JSON string: %.*s\n", (int)buf_wanted, buf);
buf_used = 0;
buf_wanted = 0;
continue;
}
if (buf[json_bytes - 1] != '}')
{
fprintf(stderr, "BUG: Invalid JSON string: %.*s", (int)json_bytes, buf);
exit(1);
}
#ifdef USE_JSON
int r;
jsmn_init(&parser);
r = jsmn_parse(&parser, (char *)(buf + json_start), buf_wanted - json_start,
tokens, sizeof(tokens) / sizeof(tokens[0]));
if (r < 0 || tokens[0].type != JSMN_OBJECT) {
fprintf(stderr, "JSON parsing failed with return value %d at position %u\n", r, parser.pos);
fprintf(stderr, "JSON string: '%.*s'\n", (int)(buf_wanted - json_start), (char *)(buf + json_start));
}
for (int i = 1; i < r; i++) {
if (i % 2 == 1) {
printf("[%.*s : ", tokens[i].end - tokens[i].start,
(char *)(buf + json_start) + tokens[i].start);
} else {
printf("%.*s] ", tokens[i].end - tokens[i].start,
(char *)(buf + json_start) + tokens[i].start);
int r;
jsmn_init(&parser);
r = jsmn_parse(&parser,
(char *)(buf + json_start),
json_bytes - json_start,
tokens,
sizeof(tokens) / sizeof(tokens[0]));
if (r < 0 || tokens[0].type != JSMN_OBJECT)
{
fprintf(stderr, "JSON parsing failed with return value %d at position %u\n", r, parser.pos);
fprintf(stderr, "JSON string: '%.*s'\n", (int)(json_bytes - json_start), (char *)(buf + json_start));
}
}
printf("EoF\n");
for (int i = 1; i < r; i++)
{
if (i % 2 == 1)
{
printf("[%.*s : ", tokens[i].end - tokens[i].start, (char *)(buf + json_start) + tokens[i].start);
}
else
{
printf("%.*s] ", tokens[i].end - tokens[i].start, (char *)(buf + json_start) + tokens[i].start);
}
}
printf("EoF\n");
#else
printf("RECV[%llu,%zd]: '%.*s'\n\n", buf_wanted, bytes_read, (int)buf_wanted, buf);
printf("RECV[%llu,%zd]: '%.*s'\n\n", buf_wanted, bytes_read, (int)buf_wanted, buf);
#endif
memmove(buf, buf + buf_wanted, buf_used - buf_wanted);
buf_used -= buf_wanted;
buf_wanted = 0;
memmove(buf, buf + json_bytes, buf_used - json_bytes);
buf_used -= json_bytes;
json_bytes = 0;
json_start = 0;
}
}
return 0;