Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rlp: allow encoding non-empty interface values #260

Merged
merged 1 commit into from
Jan 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 4 additions & 1 deletion rlp/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func makeDecoder(typ reflect.Type) (dec decoder, err error) {
return makeStructDecoder(typ)
case kind == reflect.Ptr:
return makePtrDecoder(typ)
case kind == reflect.Interface && typ.NumMethod() == 0:
case kind == reflect.Interface:
return decodeInterface, nil
default:
return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ)
Expand Down Expand Up @@ -378,6 +378,9 @@ func makePtrDecoder(typ reflect.Type) (decoder, error) {
var ifsliceType = reflect.TypeOf([]interface{}{})

func decodeInterface(s *Stream, val reflect.Value) error {
if val.Type().NumMethod() != 0 {
return fmt.Errorf("rlp: type %v is not RLP-serializable", val.Type())
}
kind, _, err := s.Kind()
if err != nil {
return err
Expand Down
5 changes: 5 additions & 0 deletions rlp/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,11 @@ var decodeTests = []decodeTest{
{input: "850505050505", ptr: new(interface{}), value: []byte{5, 5, 5, 5, 5}},
{input: "C0", ptr: new(interface{}), value: []interface{}{}},
{input: "C50183040404", ptr: new(interface{}), value: []interface{}{[]byte{1}, []byte{4, 4, 4}}},
{
input: "C3010203",
ptr: new([]io.Reader),
error: "rlp: type io.Reader is not RLP-serializable",
},
}

func uintp(i uint) *uint { return &i }
Expand Down
3 changes: 1 addition & 2 deletions rlp/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ func (r *encReader) next() []byte {

var (
encoderInterface = reflect.TypeOf(new(Encoder)).Elem()
emptyInterface = reflect.TypeOf(new(interface{})).Elem()
big0 = big.NewInt(0)
)

Expand All @@ -292,7 +291,7 @@ func makeWriter(typ reflect.Type) (writer, error) {
return writeEncoder, nil
case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface):
return writeEncoderNoPtr, nil
case typ == emptyInterface:
case kind == reflect.Interface:
return writeInterface, nil
case typ.AssignableTo(reflect.PtrTo(bigInt)):
return writeBigIntPtr, nil
Expand Down
13 changes: 13 additions & 0 deletions rlp/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,19 @@ func (e byteEncoder) EncodeRLP(w io.Writer) error {
return nil
}

type encodableReader struct {
A, B uint
}

func (e *encodableReader) Read(b []byte) (int, error) {
panic("called")
}

var (
_ = Encoder(&testEncoder{})
_ = Encoder(byteEncoder(0))

reader io.Reader = &encodableReader{1, 2}
)

type encTest struct {
Expand Down Expand Up @@ -176,6 +186,9 @@ var encTests = []encTest{
{val: (*[]struct{ uint })(nil), output: "C0"},
{val: (*interface{})(nil), output: "C0"},

// interfaces
{val: []io.Reader{reader}, output: "C3C20102"}, // the contained value is a struct

// Encoder
{val: (*testEncoder)(nil), output: "00000000"},
{val: &testEncoder{}, output: "00010001000100010001"},
Expand Down