2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00

fix: ignore overflow error when decoding json.Number (#207)

This commit is contained in:
Yi Duan 2022-03-24 16:00:08 +08:00 committed by GitHub
parent c381c8b679
commit 94232a7b2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 4 deletions

View file

@ -581,6 +581,15 @@ func (self *_Assembler) check_err() {
self.Sjmp("JS" , _LB_parsing_error_v) // JNE _parsing_error_v
}
func (self *_Assembler) check_err_num() {
self.Emit("MOVQ" , _VAR_st_Vt, _AX) // MOVQ st.Vt, AX
self.Emit("TESTQ", _AX, _AX) // CMPQ AX, ${native.V_STRING}
self.Sjmp("JNS" , "check_err_end_{n}")
self.Emit("CMPQ" , _AX, jit.Imm(-int64(types.ERR_FLOAT_INFINITY)))
self.Sjmp("JNE" , _LB_parsing_error_v)
self.Link("check_err_end_{n}")
}
func (self *_Assembler) check_eof(d int64) {
if d == 1 {
self.Emit("CMPQ", _IC, _IL) // CMPQ IC, IL
@ -1171,7 +1180,8 @@ func (self *_Assembler) _asm_OP_num(_ *_Instr) {
self.Emit("MOVQ", jit.Imm(1), _VAR_fl)
self.Emit("ADDQ", jit.Imm(1), _IC)
self.Link("_parse_number_{n}")
self.parse_number() // PARSE NUMBER
self.call_vf(_F_vnumber) // call vnumber
self.check_err_num()
self.slice_from(_VAR_st_Ep, 0) // SLICE st.Ep, $0
self.Emit("BTQ", jit.Imm(_F_copy_string), _ARG_fv)
self.Sjmp("JNC", "_num_write_{n}")

View file

@ -591,6 +591,15 @@ func (self *_Assembler) check_err() {
self.Sjmp("JS" , _LB_parsing_error_v) // JNE _parsing_error_v
}
func (self *_Assembler) check_err_num() {
self.Emit("MOVQ" , _VAR_st_Vt, _AX) // MOVQ st.Vt, AX
self.Emit("TESTQ", _AX, _AX) // CMPQ AX, ${native.V_STRING}
self.Sjmp("JNS" , "check_err_end_{n}")
self.Emit("CMPQ" , _AX, jit.Imm(-int64(types.ERR_FLOAT_INFINITY)))
self.Sjmp("JNE" , _LB_parsing_error_v)
self.Link("check_err_end_{n}")
}
func (self *_Assembler) check_eof(d int64) {
if d == 1 {
self.Emit("CMPQ", _IC, _IL) // CMPQ IC, IL
@ -1168,7 +1177,8 @@ func (self *_Assembler) _asm_OP_num(_ *_Instr) {
self.Emit("MOVQ", jit.Imm(1), _VAR_fl)
self.Emit("ADDQ", jit.Imm(1), _IC)
self.Link("_parse_number_{n}")
self.parse_number() // PARSE NUMBER
self.call_vf(_F_vnumber)
self.check_err_num()
self.slice_from(_VAR_st_Ep, 0) // SLICE st.Ep, $0
self.Emit("BTQ", jit.Imm(_F_copy_string), _ARG_fv)
self.Sjmp("JNC", "_num_write_{n}")

View file

@ -273,8 +273,14 @@ func (self *_ValueDecoder) compile() {
/* check for errors */
self.Emit("MOVQ" , _VAR_ss_Vt, _AX) // MOVQ ss.Vt, AX
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
self.Sjmp("JS" , "_parsing_error") // JS _parsing_error
self.Sjmp("JZ" , "_invalid_vtype") // JZ _invalid_vtype
self.Sjmp("JNS" , "_not_sign") // JNS
self.Emit("CMPQ" , _AX, jit.Imm(-int64(types.ERR_FLOAT_INFINITY)))
self.Sjmp("JNE" , "_parsing_error")
self.Emit("BTQ" , jit.Imm(_F_use_number), _VAR_df) // BTQ _F_use_number, df
self.Sjmp("JNC" , "_parsing_error")
self.Emit("MOVQ" , jit.Imm(int64(types.V_DOUBLE)), _AX)
self.Link("_not_sign")
self.Emit("CMPQ" , _AX, _V_max) // CMPQ AX, _V_max
self.Sjmp("JA" , "_invalid_vtype") // JA _invalid_vtype

View file

@ -288,8 +288,14 @@ func (self *_ValueDecoder) compile() {
/* check for errors */
self.Emit("MOVQ" , _VAR_ss_Vt, _AX) // MOVQ ss.Vt, AX
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, AX
self.Sjmp("JS" , "_parsing_error") // JS _parsing_error
self.Sjmp("JZ" , "_invalid_vtype") // JZ _invalid_vtype
self.Sjmp("JNS" , "_not_sign") // JNS
self.Emit("CMPQ" , _AX, jit.Imm(-int64(types.ERR_FLOAT_INFINITY)))
self.Sjmp("JNE" , "_parsing_error")
self.Emit("BTQ" , jit.Imm(_F_use_number), _VAR_df) // BTQ _F_use_number, df
self.Sjmp("JNC" , "_parsing_error")
self.Emit("MOVQ" , jit.Imm(int64(types.V_DOUBLE)), _AX)
self.Link("_not_sign")
self.Emit("CMPQ" , _AX, _V_max) // CMPQ AX, _V_max
self.Sjmp("JA" , "_invalid_vtype") // JA _invalid_vtype

View file

@ -0,0 +1,57 @@
/*
* Copyright 2021 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package issue_test
import (
`bytes`
`encoding/json`
`strings`
`testing`
`github.com/stretchr/testify/require`
`github.com/bytedance/sonic`
`github.com/bytedance/sonic/decoder`
)
var issue_19x_idata = "\"" + strings.Repeat("9", 1000) + "\""
var issue_19x_fdata = "\"" + strings.Repeat("9", 100) + "." + strings.Repeat("9", 1000) + "\""
var issue_19x_ndata = strings.Repeat("9", 1000)
func TestDecodeLongStringToJsonNumber(t *testing.T) {
var objs, obje json.Number
errs := sonic.UnmarshalString(issue_19x_idata, &objs)
erre := json.Unmarshal([]byte(issue_19x_idata), &obje)
require.Equal(t, erre, errs)
require.Equal(t, obje, objs)
var fobjs, fobje json.Number
errs = sonic.UnmarshalString(issue_19x_fdata, &fobjs)
erre = json.Unmarshal([]byte(issue_19x_fdata), &fobje)
require.Equal(t, erre, errs)
require.Equal(t, fobje, fobjs)
var iobjs, iobje interface{}
dc := decoder.NewDecoder(issue_19x_ndata)
dc.UseNumber()
errs = dc.Decode(&iobjs)
r := json.NewDecoder(bytes.NewBufferString(issue_19x_ndata))
r.UseNumber()
erre = r.Decode(&iobje)
require.Equal(t, erre, errs)
require.Equal(t, iobje, iobjs)
}