[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 3e3e23f: Fix pointer misuse in JSON parser
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] master 3e3e23f: Fix pointer misuse in JSON parser |
Date: |
Sat, 9 Jun 2018 20:57:34 -0400 (EDT) |
branch: master
commit 3e3e23fb88fdc19e859c0aa2ab51b86afd323c71
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
Fix pointer misuse in JSON parser
* src/json.c (lisp_to_json_toplevel_1): Fix pointer misuse not
caught by C type checking (json_t ** converted to void * where
the program expected json_t *). Bug caught on Fedora 28 x86-64 via
'./configure CFLAGS="-g3 -O2 -fsanitize=address" CANNOT_DUMP=yes'.
Avoid similar problems in the future by rewriting to use
json_t * instead of json_t **.
---
src/json.c | 60 ++++++++++++++++++++++++++++--------------------------------
1 file changed, 28 insertions(+), 32 deletions(-)
diff --git a/src/json.c b/src/json.c
index afb8158..c28e14d 100644
--- a/src/json.c
+++ b/src/json.c
@@ -327,36 +327,35 @@ json_check_utf8 (Lisp_Object string)
static json_t *lisp_to_json (Lisp_Object);
-/* Convert a Lisp object to a toplevel JSON object (array or object).
- This returns Lisp_Object so we can use unbind_to. The return value
- is always nil. */
+/* Convert a Lisp object to a toplevel JSON object (array or object). */
-static _GL_ARG_NONNULL ((2)) Lisp_Object
-lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
+static json_t *
+lisp_to_json_toplevel_1 (Lisp_Object lisp)
{
+ json_t *json;
+ ptrdiff_t count;
+
if (VECTORP (lisp))
{
ptrdiff_t size = ASIZE (lisp);
- *json = json_check (json_array ());
- ptrdiff_t count = SPECPDL_INDEX ();
+ json = json_check (json_array ());
+ count = SPECPDL_INDEX ();
record_unwind_protect_ptr (json_release_object, json);
for (ptrdiff_t i = 0; i < size; ++i)
{
int status
- = json_array_append_new (*json, lisp_to_json (AREF (lisp, i)));
+ = json_array_append_new (json, lisp_to_json (AREF (lisp, i)));
if (status == -1)
json_out_of_memory ();
}
- eassert (json_array_size (*json) == size);
- clear_unwind_protect (count);
- return unbind_to (count, Qnil);
+ eassert (json_array_size (json) == size);
}
else if (HASH_TABLE_P (lisp))
{
struct Lisp_Hash_Table *h = XHASH_TABLE (lisp);
- *json = json_check (json_object ());
- ptrdiff_t count = SPECPDL_INDEX ();
- record_unwind_protect_ptr (json_release_object, *json);
+ json = json_check (json_object ());
+ count = SPECPDL_INDEX ();
+ record_unwind_protect_ptr (json_release_object, json);
for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i)
if (!NILP (HASH_HASH (h, i)))
{
@@ -367,9 +366,9 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
const char *key_str = SSDATA (key);
/* Reject duplicate keys. These are possible if the hash
table test is not `equal'. */
- if (json_object_get (*json, key_str) != NULL)
+ if (json_object_get (json, key_str) != NULL)
wrong_type_argument (Qjson_value_p, lisp);
- int status = json_object_set_new (*json, key_str,
+ int status = json_object_set_new (json, key_str,
lisp_to_json (HASH_VALUE (h,
i)));
if (status == -1)
{
@@ -379,20 +378,15 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
json_out_of_memory ();
}
}
- clear_unwind_protect (count);
- return unbind_to (count, Qnil);
}
else if (NILP (lisp))
- {
- *json = json_check (json_object ());
- return Qnil;
- }
+ return json_check (json_object ());
else if (CONSP (lisp))
{
Lisp_Object tail = lisp;
- *json = json_check (json_object ());
- ptrdiff_t count = SPECPDL_INDEX ();
- record_unwind_protect_ptr (json_release_object, *json);
+ json = json_check (json_object ());
+ count = SPECPDL_INDEX ();
+ record_unwind_protect_ptr (json_release_object, json);
bool is_plist = !CONSP (XCAR (tail));
FOR_EACH_TAIL (tail)
{
@@ -427,19 +421,22 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
key_str = &key_str[1];
}
/* Only add element if key is not already present. */
- if (json_object_get (*json, key_str) == NULL)
+ if (json_object_get (json, key_str) == NULL)
{
int status
- = json_object_set_new (*json, key_str, lisp_to_json (value));
+ = json_object_set_new (json, key_str, lisp_to_json (value));
if (status == -1)
json_out_of_memory ();
}
}
CHECK_LIST_END (tail, lisp);
- clear_unwind_protect (count);
- return unbind_to (count, Qnil);
}
- wrong_type_argument (Qjson_value_p, lisp);
+ else
+ wrong_type_argument (Qjson_value_p, lisp);
+
+ clear_unwind_protect (count);
+ unbind_to (count, Qnil);
+ return json;
}
/* Convert LISP to a toplevel JSON object (array or object). Signal
@@ -451,8 +448,7 @@ lisp_to_json_toplevel (Lisp_Object lisp)
{
if (++lisp_eval_depth > max_lisp_eval_depth)
xsignal0 (Qjson_object_too_deep);
- json_t *json;
- lisp_to_json_toplevel_1 (lisp, &json);
+ json_t *json = lisp_to_json_toplevel_1 (lisp);
--lisp_eval_depth;
return json;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master 3e3e23f: Fix pointer misuse in JSON parser,
Paul Eggert <=