Ver código fonte

Merge pull request #200 from rmallins/cJSON_ParseWithOpts_fix_ErrorPtr_behaviour

Fix error pointer behaviour of cJSON_ParseWithOpts()
Max Bruckner 7 anos atrás
pai
commit
e4980b65b9
4 arquivos alterados com 38 adições e 10 exclusões
  1. 2 4
      cJSON.c
  2. 1 1
      cJSON.h
  3. 18 1
      tests/parse_examples.c
  4. 17 4
      tests/parse_with_opts.c

+ 2 - 4
cJSON.c

@@ -1006,10 +1006,8 @@ fail:
         {
             *return_parse_end = (const char*)local_error.json + local_error.position;
         }
-        else
-        {
-            global_error = local_error;
-        }
+ 
+        global_error = local_error;
     }
 
     return NULL;

+ 1 - 1
cJSON.h

@@ -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. */

+ 18 - 1
tests/parse_examples.c

@@ -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)
     {
@@ -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();
@@ -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();
 }

+ 17 - 4
tests/parse_with_opts.c

@@ -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)
@@ -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);
 }
 
@@ -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);