]> git.eshelyaron.com Git - emacs.git/commitdiff
JSON serialization: reject duplicate keys in hashtables
authorPhilipp Stephani <phst@google.com>
Mon, 18 Dec 2017 23:04:29 +0000 (00:04 +0100)
committerPhilipp Stephani <phst@google.com>
Sun, 24 Dec 2017 12:52:30 +0000 (13:52 +0100)
* src/json.c (lisp_to_json_toplevel_1): Reject duplicate keys in
hashtables.

* test/src/json-tests.el (json-serialize/object-with-duplicate-keys):
Add unit tests.

src/json.c
test/src/json-tests.el

index 689f6ac510e3e44d8099c05ebb78997f345d0b26..c1daba199c387e3f693f014a38222e410ab28110 100644 (file)
@@ -352,7 +352,12 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
             /* We can't specify the length, so the string must be
                null-terminated.  */
             check_string_without_embedded_nulls (key);
-            int status = json_object_set_new (*json, SSDATA (key),
+            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)
+              wrong_type_argument (Qjson_value_p, lisp);
+            int status = json_object_set_new (*json, key_str,
                                               lisp_to_json (HASH_VALUE (h, i)));
             if (status == -1)
               /* FIXME: A failure here might also indicate that the
index 9884e9a2d57f2938f8a3c7e2fde992816ec98b83..5d9f6b3840c681af44d00537c0b367dcf0a2da0f 100644 (file)
     (should (equal (json-serialize table)
                    "{\"abc\":[1,2,true],\"def\":null}"))))
 
+(ert-deftest json-serialize/object-with-duplicate-keys ()
+  (skip-unless (fboundp 'json-serialize))
+  (let ((table (make-hash-table :test #'eq)))
+    (puthash (copy-sequence "abc") [1 2 t] table)
+    (puthash (copy-sequence "abc") :null table)
+    (should (equal (hash-table-count table) 2))
+    (should-error (json-serialize table) :type 'wrong-type-argument)))
+
 (ert-deftest json-parse-string/object ()
   (skip-unless (fboundp 'json-parse-string))
   (let ((input