Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5a1ed5b
mysql/json: reject numbers a double cannot hold, as MySQL does
arthurschreiber Jul 28, 2026
f4aa5ec
mysql/json: cover the exponent spellings called out on the issue
arthurschreiber Jul 28, 2026
e68bd7e
mysql/json: bound the exponent as written, not just as converted
arthurschreiber Jul 28, 2026
fa351ff
mysql/json: read numbers by JSON's grammar, not Go's
arthurschreiber Jul 28, 2026
fe181de
mysql/json: stop reading nan as a number
arthurschreiber Jul 28, 2026
b450fe6
mysql/json: decide what a double can hold the way MySQL decides it
arthurschreiber Jul 28, 2026
139a987
mysql/json: keep each significand digit to two roundings
arthurschreiber Jul 28, 2026
16c9c69
mysql/json: count only an exponent that moves the point right
arthurschreiber Jul 28, 2026
0c64ad5
mysql/json: say what readFloat's exponent is, and what it is not
arthurschreiber Jul 28, 2026
879d156
mysql/json: read the power-of-ten table with strconv
arthurschreiber Jul 28, 2026
78c4bfa
mysql/json: say which reader the number check follows
arthurschreiber Jul 28, 2026
ed1fe05
mysql/json: record RapidJSON's licence alongside the number check
arthurschreiber Jul 28, 2026
2fe54bb
mysql/json: benchmark the paths the number reader takes
arthurschreiber Jul 28, 2026
e3010e5
mysql/json: count the digits that can reach past a double, not the st…
arthurschreiber Jul 28, 2026
97552c6
mysql/json: cover a negative exponent written past what an int holds
arthurschreiber Jul 28, 2026
a3fb097
mysql/json: abbreviate the number an error reports on
arthurschreiber Jul 28, 2026
94366cc
mysql/json: abbreviate the document every rejection names
arthurschreiber Jul 28, 2026
97ea69c
mysql/json: benchmark documents that reach the magnitude check
arthurschreiber Jul 28, 2026
0886b6f
mysql/json: pin the tightened grammar on the SQL-marshal path
arthurschreiber Jul 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions go/mysql/json/LICENSE.rapidjson
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Tencent is pleased to support the open source community by making RapidJSON
available.

Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.

Parts of parser.go are derived from RapidJSON 1.1.0, the JSON parser MySQL
parses documents with, so that Vitess accepts exactly the documents MySQL does:
mysqlNumberFits follows GenericReader::ParseNumber in
include/rapidjson/reader.h, scaleByPow10 and movePoint follow
StrtodNormalPrecision and FastPath in include/rapidjson/internal/strtod.h, and
the pow10 table holds the same values as Pow10 in
include/rapidjson/internal/pow10.h. No RapidJSON source is included here; the Go
code was written to reproduce what those functions decide.

RapidJSON is licensed under the MIT License:

The MIT License (MIT)

Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
2 changes: 1 addition & 1 deletion go/mysql/json/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ func (w *sqlWriter) writeNumber(top bool) error {
// Use the parser's readFloat to validate number grammar, rejecting
// malformed inputs like "1+2", "1..2", or "1e+" that a simple
// character-class loop would accept.
n, ok := readFloat(w.data[w.pos:])
n, _, ok := readFloat(w.data[w.pos:])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply the magnitude check in the raw SQL marshaller

This call discards the exponent returned by readFloat, so AppendMarshalSQL and MarshalSQLValue still accept numbers that the updated parser rejects, such as 1e309 or 1.7976931348623159e308. They emit expressions such as CAST(1e309 as JSON) or JSON_ARRAY(1e309), which MySQL rejects when vreplication executes them; apply the same mayExceedFloat64/mysqlNumberFits validation here so callers fail before constructing an unusable replication statement.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is tracked in #20727 and is not really a reachable issue.

if !ok || n == 0 {
return fmt.Errorf("invalid number at position %d in JSON", w.pos)
}
Expand Down
Loading
Loading