mirror of
https://github.com/ii64/sonic.git
synced 2026-06-23 01:46:44 +08:00
fix: ignore overflow error when decoding json.Number (#207)
This commit is contained in:
parent
c381c8b679
commit
94232a7b2e
5 changed files with 93 additions and 4 deletions
|
|
@ -581,6 +581,15 @@ func (self *_Assembler) check_err() {
|
||||||
self.Sjmp("JS" , _LB_parsing_error_v) // JNE _parsing_error_v
|
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) {
|
func (self *_Assembler) check_eof(d int64) {
|
||||||
if d == 1 {
|
if d == 1 {
|
||||||
self.Emit("CMPQ", _IC, _IL) // CMPQ IC, IL
|
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("MOVQ", jit.Imm(1), _VAR_fl)
|
||||||
self.Emit("ADDQ", jit.Imm(1), _IC)
|
self.Emit("ADDQ", jit.Imm(1), _IC)
|
||||||
self.Link("_parse_number_{n}")
|
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.slice_from(_VAR_st_Ep, 0) // SLICE st.Ep, $0
|
||||||
self.Emit("BTQ", jit.Imm(_F_copy_string), _ARG_fv)
|
self.Emit("BTQ", jit.Imm(_F_copy_string), _ARG_fv)
|
||||||
self.Sjmp("JNC", "_num_write_{n}")
|
self.Sjmp("JNC", "_num_write_{n}")
|
||||||
|
|
|
||||||
|
|
@ -591,6 +591,15 @@ func (self *_Assembler) check_err() {
|
||||||
self.Sjmp("JS" , _LB_parsing_error_v) // JNE _parsing_error_v
|
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) {
|
func (self *_Assembler) check_eof(d int64) {
|
||||||
if d == 1 {
|
if d == 1 {
|
||||||
self.Emit("CMPQ", _IC, _IL) // CMPQ IC, IL
|
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("MOVQ", jit.Imm(1), _VAR_fl)
|
||||||
self.Emit("ADDQ", jit.Imm(1), _IC)
|
self.Emit("ADDQ", jit.Imm(1), _IC)
|
||||||
self.Link("_parse_number_{n}")
|
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.slice_from(_VAR_st_Ep, 0) // SLICE st.Ep, $0
|
||||||
self.Emit("BTQ", jit.Imm(_F_copy_string), _ARG_fv)
|
self.Emit("BTQ", jit.Imm(_F_copy_string), _ARG_fv)
|
||||||
self.Sjmp("JNC", "_num_write_{n}")
|
self.Sjmp("JNC", "_num_write_{n}")
|
||||||
|
|
|
||||||
|
|
@ -273,8 +273,14 @@ func (self *_ValueDecoder) compile() {
|
||||||
/* check for errors */
|
/* check for errors */
|
||||||
self.Emit("MOVQ" , _VAR_ss_Vt, _AX) // MOVQ ss.Vt, AX
|
self.Emit("MOVQ" , _VAR_ss_Vt, _AX) // MOVQ ss.Vt, AX
|
||||||
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, 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("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.Emit("CMPQ" , _AX, _V_max) // CMPQ AX, _V_max
|
||||||
self.Sjmp("JA" , "_invalid_vtype") // JA _invalid_vtype
|
self.Sjmp("JA" , "_invalid_vtype") // JA _invalid_vtype
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -288,8 +288,14 @@ func (self *_ValueDecoder) compile() {
|
||||||
/* check for errors */
|
/* check for errors */
|
||||||
self.Emit("MOVQ" , _VAR_ss_Vt, _AX) // MOVQ ss.Vt, AX
|
self.Emit("MOVQ" , _VAR_ss_Vt, _AX) // MOVQ ss.Vt, AX
|
||||||
self.Emit("TESTQ", _AX, _AX) // TESTQ AX, 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("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.Emit("CMPQ" , _AX, _V_max) // CMPQ AX, _V_max
|
||||||
self.Sjmp("JA" , "_invalid_vtype") // JA _invalid_vtype
|
self.Sjmp("JA" , "_invalid_vtype") // JA _invalid_vtype
|
||||||
|
|
||||||
|
|
|
||||||
57
issue_test/issue206_test.go
Normal file
57
issue_test/issue206_test.go
Normal 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)
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue