diff options
| author | Philipp Stephani | 2017-12-23 17:56:36 +0100 |
|---|---|---|
| committer | Philipp Stephani | 2017-12-30 23:16:51 +0100 |
| commit | a5835dfee139322de7aa071f1c87ef015acbecad (patch) | |
| tree | 992b5222049f2aa2a124f8c3484bbd074eaecfd1 /src/json.c | |
| parent | 30ffc256abe7443a02b44490c518baf9a122b4c8 (diff) | |
| download | emacs-a5835dfee139322de7aa071f1c87ef015acbecad.tar.gz emacs-a5835dfee139322de7aa071f1c87ef015acbecad.zip | |
Improve error reporting when serializing non-Unicode strings to JSON
* src/coding.c (utf8_string_p): New helper function.
(syms_of_coding) <utf-8-unix>: Move from json.c.
* src/json.c (json_check_utf8): New helper function.
(lisp_to_json_toplevel_1, lisp_to_json): Use it. To save a bit of
time, check for invalid UTF-8 strings only after encountering an
error, since Jansson already rejects them.
* test/src/json-tests.el (json-serialize/invalid-unicode): Adapt
expected error symbol.
Diffstat (limited to 'src/json.c')
| -rw-r--r-- | src/json.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/json.c b/src/json.c index 88db86ad2e3..93dcc730dae 100644 --- a/src/json.c +++ b/src/json.c | |||
| @@ -316,6 +316,15 @@ json_check (json_t *object) | |||
| 316 | return object; | 316 | return object; |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | /* If STRING is not a valid UTF-8 string, signal an error of type | ||
| 320 | `wrong-type-argument'. STRING must be a unibyte string. */ | ||
| 321 | |||
| 322 | static void | ||
| 323 | json_check_utf8 (Lisp_Object string) | ||
| 324 | { | ||
| 325 | CHECK_TYPE (utf8_string_p (string), Qutf_8_string_p, string); | ||
| 326 | } | ||
| 327 | |||
| 319 | static json_t *lisp_to_json (Lisp_Object); | 328 | static json_t *lisp_to_json (Lisp_Object); |
| 320 | 329 | ||
| 321 | /* Convert a Lisp object to a toplevel JSON object (array or object). | 330 | /* Convert a Lisp object to a toplevel JSON object (array or object). |
| @@ -363,9 +372,12 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json) | |||
| 363 | int status = json_object_set_new (*json, key_str, | 372 | int status = json_object_set_new (*json, key_str, |
| 364 | lisp_to_json (HASH_VALUE (h, i))); | 373 | lisp_to_json (HASH_VALUE (h, i))); |
| 365 | if (status == -1) | 374 | if (status == -1) |
| 366 | /* FIXME: A failure here might also indicate that the | 375 | { |
| 367 | key is not a valid Unicode string. */ | 376 | /* A failure can be caused either by an invalid key or |
| 368 | json_out_of_memory (); | 377 | by low memory. */ |
| 378 | json_check_utf8 (key); | ||
| 379 | json_out_of_memory (); | ||
| 380 | } | ||
| 369 | } | 381 | } |
| 370 | clear_unwind_protect (count); | 382 | clear_unwind_protect (count); |
| 371 | return unbind_to (count, Qnil); | 383 | return unbind_to (count, Qnil); |
| @@ -447,9 +459,15 @@ lisp_to_json (Lisp_Object lisp) | |||
| 447 | else if (STRINGP (lisp)) | 459 | else if (STRINGP (lisp)) |
| 448 | { | 460 | { |
| 449 | Lisp_Object encoded = json_encode (lisp); | 461 | Lisp_Object encoded = json_encode (lisp); |
| 450 | /* FIXME: We might throw an out-of-memory error here if the | 462 | json_t *json = json_stringn (SSDATA (encoded), SBYTES (encoded)); |
| 451 | string is not valid Unicode. */ | 463 | if (json == NULL) |
| 452 | return json_check (json_stringn (SSDATA (encoded), SBYTES (encoded))); | 464 | { |
| 465 | /* A failure can be caused either by an invalid string or by | ||
| 466 | low memory. */ | ||
| 467 | json_check_utf8 (encoded); | ||
| 468 | json_out_of_memory (); | ||
| 469 | } | ||
| 470 | return json; | ||
| 453 | } | 471 | } |
| 454 | 472 | ||
| 455 | /* LISP now must be a vector, hashtable, or alist. */ | 473 | /* LISP now must be a vector, hashtable, or alist. */ |
| @@ -863,8 +881,7 @@ syms_of_json (void) | |||
| 863 | 881 | ||
| 864 | DEFSYM (Qstring_without_embedded_nulls_p, "string-without-embedded-nulls-p"); | 882 | DEFSYM (Qstring_without_embedded_nulls_p, "string-without-embedded-nulls-p"); |
| 865 | DEFSYM (Qjson_value_p, "json-value-p"); | 883 | DEFSYM (Qjson_value_p, "json-value-p"); |
| 866 | 884 | DEFSYM (Qutf_8_string_p, "utf-8-string-p"); | |
| 867 | DEFSYM (Qutf_8_unix, "utf-8-unix"); | ||
| 868 | 885 | ||
| 869 | DEFSYM (Qjson_error, "json-error"); | 886 | DEFSYM (Qjson_error, "json-error"); |
| 870 | DEFSYM (Qjson_out_of_memory, "json-out-of-memory"); | 887 | DEFSYM (Qjson_out_of_memory, "json-out-of-memory"); |