Tighten json_decode() to reject invalid JSON that was previously accepted.
Lone surrogate rejection: Fix the surrogate pair range check from 0xDFFF to 0xDBFF so that only high surrogates (U+D800-U+DBFF) trigger pair decoding. Additionally, reject lone surrogates (any codepoint in U+D800-U+DFFF that did not form a valid pair) instead of passing them through to utf_char2bytes(), which would produce invalid UTF-8.
Case-sensitive keyword matching: json_decode() used STRNICMP (case-insensitive) for matching true, false, null, NaN, Infinity, and -Infinity. This means "True", "FALSE", "Null", etc. were all silently accepted. RFC 7159 requires these keywords to be lowercase. js_decode() retains the case-insensitive behavior.
Both of these lenient behaviors were intentionally introduced by me in the original JSON support patches, and I recall that Bram's position at the time was that Vim should not perform strict decoding. However, with the current landscape — LSP support, ch_listen(), and broader use of JSON for inter-process communication — silently accepting invalid JSON is a risk rather than a feature.
https://github.com/vim/vim/pull/19807
(2 files)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@mattn pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@mattn pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@chrisbra commented on this pull request.
In src/json.c:
> @@ -954,7 +973,13 @@ json_decode_item(js_read_T *reader, typval_T *res, int options) retval = OK; break; } - if (STRNICMP((char *)p, "false", 5) == 0) + // In strinct JSON mode, keywords must be lowercase.⬇️ Suggested change
- // In strinct JSON mode, keywords must be lowercase. + // In strict JSON mode, keywords must be lowercase.
> @@ -151,6 +151,11 @@ func Test_json_decode()
call assert_equal(type(v:none), type(json_decode('')))
call assert_equal("", json_decode('""'))
+ " json_decode() requires lowercase keywords (RFC 7159)
+ call assert_fails('call json_decode("True")', 'E491:')
+ call assert_fails('call json_decode("FALSE")', 'E491:')
+ call assert_fails('call json_decode("Null")', 'E491:')
can you add tests, that js_decode() with those values still works? I think we should also document that js_encode()/js_decode() allows special keywords ignoring the case here.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
@mattn pushed 1 commit.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@mattn pushed 10 commits.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@mattn pushed 5 commits.
—
View it on GitHub.
You are receiving this because you are subscribed to this thread.![]()