Undefined behaviour / program freeze while accessing first token
V10lator opened this issue · comments
This is my code:
#define JSMN_STATIC
#include "jsmn/jsmn.h"
-- SNIP --
debugPrintf("First 3 characters of RAM file: %c%c%c", ramFile[0], ramFile[1], ramFile[3]);
debugPrintf("Last 3 characters of RAM file: %c%c%c", ramFile[ramIndex - 2], ramFile[ramIndex - 1], ramFile[ramIndex]);
debugPrintf("Parsing keys.json...");
jsmn_parser parser;
jsmn_init(&parser);
debugPrintf("Parser initialized!");
int tn = jsmn_parse(&parser, ramFile, ramIndex, NULL, 0);
//TODO: Error checking
debugPrintf("Found %d JSON tokens", tn);
jsmntok_t tokens[tn];
jsmn_init(&parser);
debugPrintf("Parser reinitialized!");
if(jsmn_parse(&parser, ramFile, ramIndex, tokens, tn) != tn)
{
debugPrintf("Parsing error 1");
//TODO
}
else
debugPrintf("Parser reinitialized!");
if(tokens[0].type != JSMN_ARRAY)
{
debugPrintf("Parsing error 2: %d", tokens[0].type);
//TODO
}
else
debugPrintf("JSON Array found!");
And this is the result of the debugging prints:
First 3 characters of RAM file: [{t
Last 3 characters of RAM file: "}]
Parsing keys.json...
Parser initialized!
Found 39832 JSON tokens
Parser reinitialized!
So it freezes at the line if(tokens[0].type != JSMN_ARRAY)
which should have been initialized by JSMN.
Please note that this is on an architecture which does not guarantee any memory to be zero allocated.
//EDIT: Was too fast. New code:
debugPrintf("First 5 characters of RAM file: %c%c%c%c%c", ramFile[0], ramFile[1], ramFile[2], ramFile[3], ramFile[4]);
debugPrintf("Last 5 characters of RAM file: %c%c%c%c%c", ramFile[ramIndex - 4], ramFile[ramIndex - 3], ramFile[ramIndex - 2], ramFile[ramIndex - 1], ramFile[ramIndex]);
debugPrintf("Parsing keys.json...");
jsmn_parser parser;
jsmn_init(&parser);
debugPrintf("Parser initialized!");
int tn = jsmn_parse(&parser, ramFile, ramIndex, NULL, 0);
//TODO: Error checking
debugPrintf("Found %d JSON tokens", tn);
jsmntok_t tokens[tn];
jsmn_init(&parser);
debugPrintf("Parser reinitialized!");
if(jsmn_parse(&parser, ramFile, ramIndex, tokens, tn) != tn)
{
debugPrintf("Parsing error 1");
//TODO
}
else
debugPrintf("Tokens initialized!");
debugPrintf("Examining tokens[0]:");
debugPrintf("\ttype = %#010x", tokens[0].type);
debugPrintf("\tstart = %#010x", tokens[0].start);
debugPrintf("\tend = %#010x", tokens[0].end);
debugPrintf("\tsize = %#010x", tokens[0].size);
Debugging output:
First 5 characters of RAM file: [{"ti
Last 5 characters of RAM file: 00"}]
Parsing keys.json...
Parser initialized!
Found 39832 JSON tokens
Spoofing tokens[0]...
Parser reinitialized!
So it's freezing at if(jsmn_parse(&parser, ramFile, ramIndex, tokens, tn) != tn)
.
Please note that the ramFile string is not terminated by a '\0' char. Could this cause the issue?
//EDIT²: Yes, fixed by adding \0 to the end. Not sure if you want to fix this (we pass the size of the JSON string to JSMN, so why doesn't it use that info?),
First thing, can you revert any changes and test with #define JSMN_STRICT
?
The non-strict mode, sadly the default for now, doesn't really work well and is planned to be removed. Have a feeling it might be causing the problems.
I tried as you suggested but the error is still the same.
If you need to know what data I'm trying to parse, it's this: http://cldr.xyz/json
I have tested your case with my eyes and valgrind and seems like the problem might be at some other point in your code as it doesn't seem to be in here. You should look around for possible memory corruption before this piece of code.
I will close this issue for now but feel free to reopen if you believe the problem is definitely with JSMN.
That JSON parsing is almost the first thing happening in the app. It only initializes a few things, reads a json config file, downloads the json file from the link above to ram and parses it. Also porting to another json library fixed the problem for me, so I'm really not sure what happened here.
Anyway, thanks for your support. I'll check JSMN out again at a later point in time (maybe I'm really overlooking some corruption but I searched for it the whole day before making this report... But I also need to inform myself how to use i.e. Valgrind on the platform I'm developing for).