cjson error handling

ginodecock
Posts: 30
Joined: Thu Jun 29, 2017 7:10 pm

cjson error handling

Postby ginodecock » Mon Jul 09, 2018 6:31 pm

Hi,

I am using the buildin cjson component to parse json data. When the data is not well formed the esp32 crashes:

Code: Select all

Guru Meditation Error: Core  0 panic'ed (LoadProhibited)
. Exception was unhandled.
Register dump:
PC      : 0x4010ad64  PS      : 0x00060e30  A0      : 0x8013e2fd  A1      : 0x3fff0510
0x4010ad64: cc_callback at C:/msys32/home/projects/sl_ulp_ijzer_templogger/main/cc_client.c:183

A2      : 0x4000beb8  A3      : 0x00000000  A4      : 0x0000005a  A5      : 0x00000000
A6      : 0x3ffdc558  A7      : 0x0000000c  A8      : 0x8010ad64  A9      : 0x3fff04f0
A10     : 0x00000000  A11     : 0x3f40ca12  A12     : 0x0000000a  A13     : 0x3ffdc6e4
A14     : 0x3ffdc6e4  A15     : 0x00000076  SAR     : 0x00000008  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000014  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000

Backtrace: 0x4010ad64:0x3fff0510 0x4013e2fa:0x3fff0650 0x4010ac06:0x3fff0710 0x4010ad25:0x3fff42e0
0x4010ad64: cc_callback at C:/msys32/home/projects/sl_ulp_ijzer_templogger/main/cc_client.c:183

0x4013e2fa: req_process_download at C:/msys32/home/projects/sl_ulp_ijzer_templogger/components/esp-request/esp_request.c:710
 (inlined by) req_perform at C:/msys32/home/projects/sl_ulp_ijzer_templogger/components/esp-request/esp_request.c:680

0x4010ac06: cc_offload at C:/msys32/home/projects/sl_ulp_ijzer_templogger/main/cc_client.c:183

0x4010ad25: cc_https_task at C:/msys32/home/projects/sl_ulp_ijzer_templogger/main/cc_client.c:183

This is the code for the parsing:
int cc_callback(request_t *req, char *data, int len)

Code: Select all

{
	cJSON_Hooks memoryHook;

	memoryHook.malloc_fn = malloc;
	memoryHook.free_fn = free;
	cJSON_InitHooks(&memoryHook);
	struct timeval now;
	cJSON * root   = cJSON_Parse(data);
	cc_nextOffload = cJSON_GetObjectItem(root,"nextoffload")->valueint;
	cc_firmware = cJSON_GetObjectItem(root,"firmware")->valueint;
	cc_time = cJSON_GetObjectItem(root,"time")->valueint;
	cc_temphigh = cJSON_GetObjectItem(root,"temphigh")->valueint;
	cc_templow = cJSON_GetObjectItem(root,"templow")->valueint;
	cc_display = cJSON_GetObjectItem(root,"display")->valueint;
	char * rendered = cJSON_Print(root);
	ESP_LOGI(TAG,"%s\n", rendered);
	free(rendered);
	cJSON_Delete(root);
	ESP_LOGI(TAG,"nextOffload found nextOffload= %d",cc_nextOffload);
	ESP_LOGI(TAG,"Thermostat temperature high found tempHigh= %d",cc_temphigh);
	ESP_LOGI(TAG,"Thermostat temperature low found tempLow= %d",cc_templow);
	ESP_LOGI(TAG,"Display message to show= %d",cc_display);
       return 0;
}
I suppose the core reason of the crash is that cjson is not thread safe.
Please if someone knows best practice how to use cjson to parse safely?

Thanks,

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: cjson error handling

Postby kolban » Mon Jul 09, 2018 8:43 pm

At which source line in your application is the failure occurring?
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

ESP_igrr
Posts: 2067
Joined: Tue Dec 01, 2015 8:37 am

Re: cjson error handling

Postby ESP_igrr » Tue Jul 10, 2018 1:14 am

Based on the call stack, the error does not come from cjson. You may get more precise error indication if you enable GDBStub, but my guess would be that one of cJSON_GetObjectItem calls returns NULL, which you immediately dereference with ->valueint. Try checking the return value before dereferencing.

ginodecock
Posts: 30
Joined: Thu Jun 29, 2017 7:10 pm

Re: cjson error handling

Postby ginodecock » Tue Jul 10, 2018 10:46 am

Hi,

@ESP_igrr your guess is right.
checking if the returns is NULL before dereferencing makes the json parsing robust.

Who is online

Users browsing this forum: Majestic-12 [Bot] and 172 guests