Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error pointer behaviour of cJSON_ParseWithOpts() #200

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions cJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -1006,10 +1006,8 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return
{
*return_parse_end = (const char*)local_error.json + local_error.position;
}
else
{
global_error = local_error;
}

global_error = local_error;
}

return NULL;
Expand Down
2 changes: 1 addition & 1 deletion cJSON.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
/* 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. If not, then cJSON_GetErrorPtr() does the job. */
/* 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(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);

/* Render a cJSON entity to text for transfer/storage. */
Expand Down
19 changes: 18 additions & 1 deletion tests/parse_examples.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ static void file_test6_should_not_be_parsed(void)
tree = cJSON_Parse(test6);
TEST_ASSERT_NULL_MESSAGE(tree, "Should fail to parse what is not JSON.");

TEST_ASSERT_EQUAL_STRING_MESSAGE(test6, cJSON_GetErrorPtr(), "Error pointer is incorrect.");
TEST_ASSERT_EQUAL_PTR_MESSAGE(test6, cJSON_GetErrorPtr(), "Error pointer is incorrect.");

if (test6 != NULL)
{
Expand Down Expand Up @@ -179,6 +179,22 @@ static void file_test11_should_be_parsed_and_printed(void)
do_test("test11");
}

static void test12_should_not_be_parsed(void)
{
const char *test12 = "{ \"name\": ";
cJSON *tree = NULL;

tree = cJSON_Parse(test12);
TEST_ASSERT_NULL_MESSAGE(tree, "Should fail to parse incomplete JSON.");

TEST_ASSERT_EQUAL_PTR_MESSAGE(test12 + strlen(test12), cJSON_GetErrorPtr(), "Error pointer is incorrect.");

if (tree != NULL)
{
cJSON_Delete(tree);
}
}

int main(void)
{
UNITY_BEGIN();
Expand All @@ -193,5 +209,6 @@ int main(void)
RUN_TEST(file_test9_should_be_parsed_and_printed);
RUN_TEST(file_test10_should_be_parsed_and_printed);
RUN_TEST(file_test11_should_be_parsed_and_printed);
RUN_TEST(test12_should_not_be_parsed);
return UNITY_END();
}
21 changes: 17 additions & 4 deletions tests/parse_with_opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,23 @@ static void parse_with_opts_should_handle_empty_strings(void)
{
const char empty_string[] = "";
const char *error_pointer = NULL;

TEST_ASSERT_NULL(cJSON_ParseWithOpts(empty_string, NULL, false));
error_pointer = cJSON_GetErrorPtr();
TEST_ASSERT_EQUAL_INT(0, error_pointer - empty_string);
TEST_ASSERT_EQUAL_PTR(empty_string, cJSON_GetErrorPtr());

TEST_ASSERT_NULL(cJSON_ParseWithOpts(empty_string, &error_pointer, false));
TEST_ASSERT_EQUAL_INT(0, error_pointer - empty_string);
TEST_ASSERT_EQUAL_PTR(empty_string, error_pointer);
TEST_ASSERT_EQUAL_PTR(empty_string, cJSON_GetErrorPtr());
}

static void parse_with_opts_should_handle_incomplete_json(void)
{
const char json[] = "{ \"name\": ";
const char *parse_end = NULL;

TEST_ASSERT_NULL(cJSON_ParseWithOpts(json, &parse_end, false));
TEST_ASSERT_EQUAL_PTR(json + strlen(json), parse_end);
TEST_ASSERT_EQUAL_PTR(json + strlen(json), cJSON_GetErrorPtr());
}

static void parse_with_opts_should_require_null_if_requested(void)
Expand All @@ -65,7 +77,7 @@ static void parse_with_opts_should_return_parse_end(void)

cJSON *item = cJSON_ParseWithOpts(json, &parse_end, false);
TEST_ASSERT_NOT_NULL(item);
TEST_ASSERT_EQUAL_INT(2, parse_end - json);
TEST_ASSERT_EQUAL_PTR(json + 2, parse_end);
cJSON_Delete(item);
}

Expand All @@ -75,6 +87,7 @@ int main(void)

RUN_TEST(parse_with_opts_should_handle_null);
RUN_TEST(parse_with_opts_should_handle_empty_strings);
RUN_TEST(parse_with_opts_should_handle_incomplete_json);
RUN_TEST(parse_with_opts_should_require_null_if_requested);
RUN_TEST(parse_with_opts_should_return_parse_end);

Expand Down