Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.0
-
None
-
None
Description
JSON_VALID indicates whether a value is a valid JSON document. Several
byte strings that no JSON grammar admits are reported valid, and the
lexer is inconsistent with itself as well as with the standard.
SELECT JSON_VALID('1.') AS v, JSON_TYPE('1.') AS t, JSON_DEPTH('1.') AS d; |
v t d
|
1 DOUBLE 1 |
No warning. RFC 8259 and ECMA-404 both require at least one digit after
the decimal point. Yet the neighbouring malformed numbers are rejected:
SELECT JSON_VALID('.1') AS leading_point, JSON_VALID('1e') AS bare_exponent; |
leading_point bare_exponent
|
0 0
|
So `1.` is accepted while `.1` and `1e` are refused, which no reading of
the grammar produces.
How to repeat
SELECT JSON_VALID('1.') AS trailing_point; -- 1 |
SELECT JSON_VALID('1.e5') AS point_then_exp; -- 1 |
SELECT JSON_VALID('.1') AS leading_point; -- 0 |
SELECT JSON_VALID('1e') AS bare_exponent; -- 0 |
SELECT JSON_VALID('+1') AS leading_plus; -- 0 |
 |
-- an escape the standard does not define
|
-- 1, STRING
|
SELECT JSON_VALID('"a\q"') AS bad_escape, JSON_TYPE('"a\q"') AS t; |
The standard permits only the escapes `" \ / b f n r t u`.
Why it matters
JSON_VALID() is the CHECK constraint of a JSON-typed column, so
whatever it admits, a JSON column stores:
CREATE TABLE t1 (j JSON); |
INSERT INTO t1 VALUES ('1.'); |
SELECT j, JSON_TYPE(j), JSON_VALID(j) FROM t1; |
j JSON_TYPE(j) JSON_VALID(j)
|
1. DOUBLE 1 |
DROP TABLE t1; |
The insert succeeds and the row reads back as a document, so the column
type is not the guarantee it appears to be.
Root cause
The number and string lexers accept forms the grammar does not define.
This is a deliberate-looking leniency in places and an oversight in
others; either way the two halves disagree with each other.
Contract, `scripts/fill_help_tables.sql:467`: *"Indicates whether the
given value is a valid JSON document or not. Returns 1 if valid, 0 if
not, and NULL if the argument is NULL."*
Affected versions
JSON_VALID was added in 10.2.3. JSON-typed columns, whose CHECK
constraint is JSON_VALID(), arrived in 10.4.3, from which point the
leniency reaches stored data.
Verified on 10.11 only (10.11.19-MariaDB-debug, commit 1dab253482d).
Other branches were not tested.
Note
Found while auditing the JSON functions against their documented
contracts. Pinned as the lenient behaviour rather than the
contract - func_json_invalid.result:126-128 records JSON_VALID('1.')
= 1. A fix would have to move that recorded line.
Attachments
Issue Links
- split from
-
MDEV-40642 Project "JSON Phoenix" (placeholder)
-
- Open
-