From 22ff3962884dcebab714478d727660c6da47f3ee Mon Sep 17 00:00:00 2001 From: Eyal Gal Date: Thu, 30 Apr 2020 20:58:08 +0300 Subject: [PATCH] adding string length to string objects there is an isssue with the strings in this library. on one hand when parsing the string it's parsed from \" till \" on the other hand when you want to actually get the data it's aviable but if you had something like this: "data\u0000\n" it's a problem since the \0 is before the end of the string. To solve the zero teminrated string i added an extra value stringvalue_len that can be retrived using a function that holds the length of the pased string. The length takes into account the parsing of special escaped chars. --- cJSON.c | 20 ++++++++++++++++++-- cJSON.h | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cJSON.c b/cJSON.c index 23270c4..d20cea5 100644 --- a/cJSON.c +++ b/cJSON.c @@ -102,6 +102,17 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) return item->valuestring; } +CJSON_PUBLIC(size_t) cJSON_GetStringValueLength(cJSON *item) +{ + if (!cJSON_IsString(item)) + { + return 0; + } + + return item->valuestring_len; +} + + CJSON_PUBLIC(double) cJSON_GetNumberValue(cJSON *item) { if (!cJSON_IsNumber(item)) @@ -769,7 +780,9 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; unsigned char *output_pointer = NULL; + unsigned char *output_pointer_before = NULL; unsigned char *output = NULL; + size_t string_length = 0; /* not a string */ if (buffer_at_offset(input_buffer)[0] != '\"') @@ -808,8 +821,8 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu { goto fail; /* allocation failure */ } + string_length = allocation_length - sizeof("") + skipped_bytes; } - output_pointer = output; /* loop through the string literal */ while (input_pointer < input_end) @@ -852,26 +865,29 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu /* UTF-16 literal */ case 'u': + output_pointer_before = output_pointer; sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); if (sequence_length == 0) { /* failed to convert UTF16-literal to UTF-8 */ goto fail; } + string_length += (unsigned int)(output_pointer - output_pointer_before); break; default: goto fail; } input_pointer += sequence_length; + string_length -= sequence_length; } } /* zero terminate the output */ *output_pointer = '\0'; - item->type = cJSON_String; item->valuestring = (char*)output; + item->valuestring_len = string_length; input_buffer->offset = (size_t) (input_end - input_buffer->content); input_buffer->offset++; diff --git a/cJSON.h b/cJSON.h index 0c6c8e0..e482d34 100644 --- a/cJSON.h +++ b/cJSON.h @@ -120,6 +120,7 @@ typedef struct cJSON /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ char *string; + size_t valuestring_len; } cJSON; typedef struct cJSON_Hooks @@ -177,6 +178,7 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); /* Check item type and return its value */ CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item); +CJSON_PUBLIC(size_t) cJSON_GetStringValueLength(cJSON *item); CJSON_PUBLIC(double) cJSON_GetNumberValue(cJSON *item); /* These functions check the type of an item */