Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.0
-
None
Description
JSON_LENGTH is documented to raise an error when the document is
invalid. A scalar value is answered for and returned before the check
that the rest of the document parses, so several byte strings that are
not documents come back with a length of 1 and no diagnostic.
SELECT JSON_LENGTH('01') AS v; |
v
|
1
|
01 is not a JSON number: a leading zero may not be followed by another
digit. The server agrees everywhere else:
SELECT JSON_VALID('01') AS va, JSON_TYPE('01') AS ty, JSON_DEPTH('01') AS de; |
va ty de
|
0 NULL NULL |
Warnings:
|
Note 4038 Syntax error in JSON text in argument 1 |
to function 'json_valid' at position 2 |
Warning 4038 Syntax error in JSON text in argument 1 |
to function 'json_type' at position 2 |
Warning 4038 Syntax error in JSON text in argument 1 |
to function 'json_depth' at position 2 |
How to repeat
SELECT JSON_LENGTH('01') AS bad_number; -- 1, silent |
SELECT JSON_LENGTH('{"a":1 "b":2}', '$.a') AS with_path; -- 1, silent |
SELECT JSON_LENGTH('[1 2]', '$[0]') AS with_index; -- 1, silent |
The same function refuses the same bytes when the path is left off:
-- NULL + Warning 4038 at position 8
|
SELECT JSON_LENGTH('{"a":1 "b":2}') AS v; |
-- NULL + Warning 4038 at position 4
|
SELECT JSON_LENGTH('[1 2]') AS v; |
and it refuses trailing rubbish after a container while accepting it
after a scalar:
SELECT JSON_LENGTH('{"a":1} rubbish') AS after_a_container; |
-- NULL + Warning 4038 at position 9
|
SELECT JSON_LENGTH('1 rubbish') AS after_a_scalar; |
-- 1, silent
|
Root cause
`sql/item_jsonfunc.cc` returns for a scalar value before the loop that
reads the rest of the document to check it:
if (json_value_scalar(&je)) |
return 1; |
The loop twenty lines below, introduced with the comment *"Parse to the
end of the JSON just to check it's valid"*, is never reached on that
path.
Contract, `scripts/fill_help_tables.sql:445`: *"An error occurs if the
JSON document is invalid, the path is invalid or if the path contains a
or wildcard."*
Affected versions
JSON_LENGTH was added in 10.2.3 and the scalar early return has
been there throughout.
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. The container cases are pinned
(func_json.result:468, :2899); nothing pins the scalar path.
Attachments
Issue Links
- split from
-
MDEV-40642 Project "JSON Phoenix" (placeholder)
-
- Open
-