Subject: Re: bug#24252: 25.1; json.el doesn't distinguish null and empty object

From: Yoichi Nakayama <[email-masked]>
Date: Sun, 21 Aug 2016 21:11:16 +0900

There was another potential bug that json-encode-key wrongly interpret
symbols internally used in json.el.
The problem is not caused by my previous patch, but the patch
introduces another internal
symbol :json-null and increase possibility to encounter it.

Following patch will fix it and make it safe to apply my second patch

>From 4d3ad1d3bbe6b3e47743f42427ac26cf316c12b5 Mon Sep 17 00:00:00 2001
From: Yoichi Nakayama <[email-masked]>
Date: Sun, 21 Aug 2016 20:24:03 +0900
Subject: [PATCH] Make json-encode-key not to signal with valid keys

Despite strings like ":json-false", "t", "nil" are valid object key,
their elisp representation were confused with internal symbols in
json-encode-key and cause json-key-format error unexpectedly.

* (json-encode-key): Rewrite without using json-encode.
---
 lisp/json.el | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/lisp/json.el b/lisp/json.el
index a439f77..a387b08 100644
--- a/lisp/json.el
+++ b/lisp/json.el
@@ -425,14 +425,30 @@ representation will be parsed correctly."
     (push "\"" res)
     (apply #'concat "\"" (nreverse res))))

-(defun json-encode-key (object)
-  "Return a JSON representation of OBJECT.
-If the resulting JSON object isn't a valid JSON object key,
-this signals `json-key-format'."
-  (let ((encoded (json-encode object)))
-    (unless (stringp (json-read-from-string encoded))
-      (signal 'json-key-format (list object)))
-    encoded))
+(defun json-encode-key (key)
+  "Return a JSON representation of object key.
+If key isn't valid Elisp object as key, this signals `json-key-format'."
+  (let ((json-key-type
+         (if (eq json-key-type nil)
+             (cdr (assq json-object-type '((hash-table . string)
+                                           (alist . symbol)
+                                           (plist . keyword))))
+           json-key-type)))
+    (json-encode-string
+     (cond ((eq json-key-type 'string)
+            (if (stringp key)
+                key
+              (signal 'json-key-format (list key))))
+           ((eq json-key-type 'symbol)
+            (if (symbolp key)
+                (symbol-name key)
+              (signal 'json-key-format (list key))))
+           ((eq json-key-type 'keyword)
+            (if (keywordp key)
+                (substring (symbol-name key) 1)
+              (signal 'json-key-format (list key))))
+           (t
+            (signal 'json-error (list key)))))))

 ;;; JSON Objects

-- 
2.8.1