mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
rlp: allow private fields after "tail" struct tag
This commit is contained in:
parent
d059c60a63
commit
f0d231fe6f
2 changed files with 25 additions and 3 deletions
|
|
@ -347,6 +347,12 @@ type tailUint struct {
|
||||||
Tail []uint `rlp:"tail"`
|
Tail []uint `rlp:"tail"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tailPrivateFields struct {
|
||||||
|
A uint
|
||||||
|
Tail []uint `rlp:"tail"`
|
||||||
|
x, y bool
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
veryBigInt = big.NewInt(0).Add(
|
veryBigInt = big.NewInt(0).Add(
|
||||||
big.NewInt(0).Lsh(big.NewInt(0xFFFFFFFFFFFFFF), 16),
|
big.NewInt(0).Lsh(big.NewInt(0xFFFFFFFFFFFFFF), 16),
|
||||||
|
|
@ -510,6 +516,11 @@ var decodeTests = []decodeTest{
|
||||||
ptr: new(tailRaw),
|
ptr: new(tailRaw),
|
||||||
value: tailRaw{A: 1, Tail: []RawValue{}},
|
value: tailRaw{A: 1, Tail: []RawValue{}},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
input: "C3010203",
|
||||||
|
ptr: new(tailPrivateFields),
|
||||||
|
value: tailPrivateFields{A: 1, Tail: []uint{2, 3}},
|
||||||
|
},
|
||||||
|
|
||||||
// struct tag "-"
|
// struct tag "-"
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -96,9 +96,10 @@ type field struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func structFields(typ reflect.Type) (fields []field, err error) {
|
func structFields(typ reflect.Type) (fields []field, err error) {
|
||||||
|
lastPublic := lastPublicField(typ)
|
||||||
for i := 0; i < typ.NumField(); i++ {
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
if f := typ.Field(i); f.PkgPath == "" { // exported
|
if f := typ.Field(i); f.PkgPath == "" { // exported
|
||||||
tags, err := parseStructTag(typ, i)
|
tags, err := parseStructTag(typ, i, lastPublic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +116,7 @@ func structFields(typ reflect.Type) (fields []field, err error) {
|
||||||
return fields, nil
|
return fields, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseStructTag(typ reflect.Type, fi int) (tags, error) {
|
func parseStructTag(typ reflect.Type, fi, lastPublic int) (tags, error) {
|
||||||
f := typ.Field(fi)
|
f := typ.Field(fi)
|
||||||
var ts tags
|
var ts tags
|
||||||
for _, t := range strings.Split(f.Tag.Get("rlp"), ",") {
|
for _, t := range strings.Split(f.Tag.Get("rlp"), ",") {
|
||||||
|
|
@ -127,7 +128,7 @@ func parseStructTag(typ reflect.Type, fi int) (tags, error) {
|
||||||
ts.nilOK = true
|
ts.nilOK = true
|
||||||
case "tail":
|
case "tail":
|
||||||
ts.tail = true
|
ts.tail = true
|
||||||
if fi != typ.NumField()-1 {
|
if fi != lastPublic {
|
||||||
return ts, fmt.Errorf(`rlp: invalid struct tag "tail" for %v.%s (must be on last field)`, typ, f.Name)
|
return ts, fmt.Errorf(`rlp: invalid struct tag "tail" for %v.%s (must be on last field)`, typ, f.Name)
|
||||||
}
|
}
|
||||||
if f.Type.Kind() != reflect.Slice {
|
if f.Type.Kind() != reflect.Slice {
|
||||||
|
|
@ -140,6 +141,16 @@ func parseStructTag(typ reflect.Type, fi int) (tags, error) {
|
||||||
return ts, nil
|
return ts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func lastPublicField(typ reflect.Type) int {
|
||||||
|
last := 0
|
||||||
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
|
if typ.Field(i).PkgPath == "" {
|
||||||
|
last = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return last
|
||||||
|
}
|
||||||
|
|
||||||
func genTypeInfo(typ reflect.Type, tags tags) (info *typeinfo, err error) {
|
func genTypeInfo(typ reflect.Type, tags tags) (info *typeinfo, err error) {
|
||||||
info = new(typeinfo)
|
info = new(typeinfo)
|
||||||
if info.decoder, err = makeDecoder(typ, tags); err != nil {
|
if info.decoder, err = makeDecoder(typ, tags); err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue