mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
In a multithreaded environment, the use of global_error does not work properly. There is a data race.
This commit is contained in:
parent
5437b79086
commit
b4cdf6ae97
16
cJSON.c
16
cJSON.c
@ -64,12 +64,6 @@ typedef struct {
|
|||||||
const unsigned char *json;
|
const unsigned char *json;
|
||||||
size_t position;
|
size_t position;
|
||||||
} error;
|
} error;
|
||||||
static error global_error = { NULL, 0 };
|
|
||||||
|
|
||||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
|
|
||||||
{
|
|
||||||
return (const char*) (global_error.json + global_error.position);
|
|
||||||
}
|
|
||||||
|
|
||||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item)
|
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item)
|
||||||
{
|
{
|
||||||
@ -1025,15 +1019,11 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse an object - create a new root, and populate. */
|
/* Parse an object - create a new root, and populate. */
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated)
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated, char *err_ptr)
|
||||||
{
|
{
|
||||||
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
|
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
|
||||||
cJSON *item = NULL;
|
cJSON *item = NULL;
|
||||||
|
|
||||||
/* reset error position */
|
|
||||||
global_error.json = NULL;
|
|
||||||
global_error.position = 0;
|
|
||||||
|
|
||||||
if (value == NULL || 0 == buffer_length)
|
if (value == NULL || 0 == buffer_length)
|
||||||
{
|
{
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -1078,7 +1068,7 @@ fail:
|
|||||||
cJSON_Delete(item);
|
cJSON_Delete(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value != NULL)
|
if (value != NULL && err_ptr)
|
||||||
{
|
{
|
||||||
error local_error;
|
error local_error;
|
||||||
local_error.json = (const unsigned char*)value;
|
local_error.json = (const unsigned char*)value;
|
||||||
@ -1098,7 +1088,7 @@ fail:
|
|||||||
*return_parse_end = (const char*)local_error.json + local_error.position;
|
*return_parse_end = (const char*)local_error.json + local_error.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
global_error = local_error;
|
*err_ptr= (char*) (local_error.json + local_error.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
6
cJSON.h
6
cJSON.h
@ -140,9 +140,9 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
|||||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match err_ptr. */
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated, char **err_ptr);
|
||||||
|
|
||||||
/* Render a cJSON entity to text for transfer/storage. */
|
/* Render a cJSON entity to text for transfer/storage. */
|
||||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||||
@ -164,8 +164,6 @@ CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
|||||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
|
||||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
|
||||||
|
|
||||||
/* Check item type and return its value */
|
/* Check item type and return its value */
|
||||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
||||||
|
Loading…
Reference in New Issue
Block a user