mirror of
https://github.com/ii64/sonic.git
synced 2026-06-21 00:46:43 +08:00
fix: fix nil pointer on value receiver (#58)
This commit is contained in:
parent
e88411dafe
commit
c2ea100389
2 changed files with 63 additions and 2 deletions
|
|
@ -416,7 +416,7 @@ func (self *_Compiler) compileRec(p *_Program, sp int, vt reflect.Type, pv bool)
|
|||
|
||||
/* check for `json.Marshaler` */
|
||||
if vt.Implements(jsonMarshalerType) {
|
||||
p.rtt(_OP_marshal, vt)
|
||||
self.compileMarshaler(p, _OP_marshal, vt, jsonMarshalerType)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -428,7 +428,7 @@ func (self *_Compiler) compileRec(p *_Program, sp int, vt reflect.Type, pv bool)
|
|||
|
||||
/* check for `encoding.TextMarshaler` */
|
||||
if vt.Implements(encodingTextMarshalerType) {
|
||||
p.rtt(_OP_marshal_text, vt)
|
||||
self.compileMarshaler(p, _OP_marshal_text, vt, encodingTextMarshalerType)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -820,3 +820,23 @@ func (self *_Compiler) compileInterface(p *_Program, vt reflect.Type) {
|
|||
p.add(_OP_null)
|
||||
p.pin(e)
|
||||
}
|
||||
|
||||
func (self *_Compiler) compileMarshaler(p *_Program, op _Op, vt reflect.Type, mt reflect.Type) {
|
||||
pc := p.pc()
|
||||
vk := vt.Kind()
|
||||
|
||||
/* direct receiver */
|
||||
if vk != reflect.Ptr || !vt.Elem().Implements(mt) {
|
||||
p.rtt(op, vt)
|
||||
return
|
||||
}
|
||||
|
||||
/* value receiver with a pointer type, check for nil before calling the marshaler */
|
||||
p.add(_OP_is_nil)
|
||||
p.rtt(op, vt)
|
||||
i := p.pc()
|
||||
p.add(_OP_goto)
|
||||
p.pin(pc)
|
||||
p.add(_OP_null)
|
||||
p.pin(i)
|
||||
}
|
||||
|
|
|
|||
41
issue58_test.go
Normal file
41
issue58_test.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 sonic
|
||||
|
||||
import (
|
||||
`testing`
|
||||
|
||||
`github.com/stretchr/testify/require`
|
||||
)
|
||||
|
||||
type (
|
||||
Issue58ValueReceiver struct {}
|
||||
Issue58PointerReceiver struct {}
|
||||
)
|
||||
|
||||
func (_ Issue58ValueReceiver) MarshalJSON() ([]byte, error) { return []byte(`"value"`), nil }
|
||||
func (_ *Issue58PointerReceiver) MarshalJSON() ([]byte, error) { return []byte(`"pointer"`), nil }
|
||||
|
||||
func TestIssue58_NilPointerOnValueMethod(t *testing.T) {
|
||||
v := struct {
|
||||
X *Issue58ValueReceiver
|
||||
Y *Issue58PointerReceiver
|
||||
}{}
|
||||
buf, err := Marshal(v)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []byte(`{"X":null,"Y":"pointer"}`), buf)
|
||||
}
|
||||
Loading…
Reference in a new issue