mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
cJSON_Parse{,WithOpts}: Skip UTF-8 (Byte Order Marks)
This commit is contained in:
parent
b26e71f960
commit
5baa77f86c
19
cJSON.c
19
cJSON.c
@ -958,6 +958,22 @@ static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
|
||||||
|
static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
|
||||||
|
{
|
||||||
|
if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
|
||||||
|
{
|
||||||
|
buffer->offset += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse an object - create a new root, and populate. */
|
/* Parse an object - create a new root, and populate. */
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -984,7 +1000,7 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parse_value(item, buffer_skip_whitespace(&buffer)))
|
if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
|
||||||
{
|
{
|
||||||
/* parse failure. ep is set. */
|
/* parse failure. ep is set. */
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -1222,7 +1238,6 @@ static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buf
|
|||||||
return parse_object(item, input_buffer);
|
return parse_object(item, input_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,6 +410,30 @@ static void cjson_functions_shouldnt_crash_with_null_pointers(void)
|
|||||||
cJSON_Delete(item);
|
cJSON_Delete(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void skip_utf8_bom_should_skip_bom(void)
|
||||||
|
{
|
||||||
|
const unsigned char string[] = "\xEF\xBB\xBF{}";
|
||||||
|
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
|
||||||
|
buffer.content = string;
|
||||||
|
buffer.length = sizeof(string);
|
||||||
|
buffer.hooks = global_hooks;
|
||||||
|
|
||||||
|
TEST_ASSERT_TRUE(skip_utf8_bom(&buffer) == &buffer);
|
||||||
|
TEST_ASSERT_EQUAL_UINT(3U, (unsigned int)buffer.offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void skip_utf8_bom_should_not_skip_bom_if_not_at_beginning(void)
|
||||||
|
{
|
||||||
|
const unsigned char string[] = " \xEF\xBB\xBF{}";
|
||||||
|
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
|
||||||
|
buffer.content = string;
|
||||||
|
buffer.length = sizeof(string);
|
||||||
|
buffer.hooks = global_hooks;
|
||||||
|
buffer.offset = 1;
|
||||||
|
|
||||||
|
TEST_ASSERT_NULL(skip_utf8_bom(&buffer));
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
@ -425,6 +449,8 @@ int main(void)
|
|||||||
RUN_TEST(cjson_replace_item_via_pointer_should_replace_items);
|
RUN_TEST(cjson_replace_item_via_pointer_should_replace_items);
|
||||||
RUN_TEST(cjson_replace_item_in_object_should_preserve_name);
|
RUN_TEST(cjson_replace_item_in_object_should_preserve_name);
|
||||||
RUN_TEST(cjson_functions_shouldnt_crash_with_null_pointers);
|
RUN_TEST(cjson_functions_shouldnt_crash_with_null_pointers);
|
||||||
|
RUN_TEST(skip_utf8_bom_should_skip_bom);
|
||||||
|
RUN_TEST(skip_utf8_bom_should_not_skip_bom_if_not_at_beginning);
|
||||||
|
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,22 @@ static void parse_with_opts_should_return_parse_end(void)
|
|||||||
cJSON_Delete(item);
|
cJSON_Delete(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parse_with_opts_should_parse_utf8_bom(void)
|
||||||
|
{
|
||||||
|
cJSON *with_bom = NULL;
|
||||||
|
cJSON *without_bom = NULL;
|
||||||
|
|
||||||
|
with_bom = cJSON_ParseWithOpts("\xEF\xBB\xBF{}", NULL, true);
|
||||||
|
TEST_ASSERT_NOT_NULL(with_bom);
|
||||||
|
without_bom = cJSON_ParseWithOpts("{}", NULL, true);
|
||||||
|
TEST_ASSERT_NOT_NULL(with_bom);
|
||||||
|
|
||||||
|
TEST_ASSERT_TRUE(cJSON_Compare(with_bom, without_bom, true));
|
||||||
|
|
||||||
|
cJSON_Delete(with_bom);
|
||||||
|
cJSON_Delete(without_bom);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
@ -77,6 +93,7 @@ int main(void)
|
|||||||
RUN_TEST(parse_with_opts_should_handle_empty_strings);
|
RUN_TEST(parse_with_opts_should_handle_empty_strings);
|
||||||
RUN_TEST(parse_with_opts_should_require_null_if_requested);
|
RUN_TEST(parse_with_opts_should_require_null_if_requested);
|
||||||
RUN_TEST(parse_with_opts_should_return_parse_end);
|
RUN_TEST(parse_with_opts_should_return_parse_end);
|
||||||
|
RUN_TEST(parse_with_opts_should_parse_utf8_bom);
|
||||||
|
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user