Преглед на файлове

fix #245, always reuse existing value even UseNumber

Tao Wen преди 7 години
родител
ревизия
25fa392355
променени са 2 файла, в които са добавени 23 реда и са изтрити 0 реда
  1. 6 0
      config.go
  2. 17 0
      misc_tests/jsoniter_object_test.go

+ 6 - 0
config.go

@@ -7,6 +7,7 @@ import (
 	"sync"
 	"unsafe"
 	"github.com/modern-go/concurrent"
+	"reflect"
 )
 
 // Config customize how the API should behave.
@@ -192,6 +193,11 @@ func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) {
 
 func (cfg *frozenConfig) useNumber(extension DecoderExtension) {
 	extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
+		exitingValue := *((*interface{})(ptr))
+		if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr {
+			iter.ReadVal(exitingValue)
+			return
+		}
 		if iter.WhatIsNext() == NumberValue {
 			*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
 		} else {

+ 17 - 0
misc_tests/jsoniter_object_test.go

@@ -130,3 +130,20 @@ func Test_reader_and_load_more(t *testing.T) {
 	obj := TestObject{}
 	should.Nil(decoder.Decode(&obj))
 }
+
+func Test_unmarshal_into_existing_value(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 int
+		Field2 interface{}
+	}
+	var obj TestObject
+	m := map[string]interface{}{}
+	obj.Field2 = &m
+	cfg := jsoniter.Config{UseNumber: true}.Froze()
+	err := cfg.Unmarshal([]byte(`{"Field1":1,"Field2":{"k":"v"}}`), &obj)
+	should.NoError(err)
+	should.Equal(map[string]interface{}{
+		"k": "v",
+	}, m)
+}