encoding
encoding copied to clipboard
proto: unexpected fault address when deref struct field
func TestIssue110(t *testing.T) {
type message struct {
A *uint32 `protobuf:"fixed32,1,opt"`
}
var a uint32 = 0x41c06db4
data, _ := Marshal(message{
A: &a,
})
var m message
err := Unmarshal(data, &m)
if err != nil {
t.Fatal(err)
}
if *m.A != 0x41c06db4 {
t.Errorf("m.A mismatch, want 0x41c06db4 but got %x", m.A)
}
}
expected pass test but got
unexpected fault address 0x41c06db4
fatal error: fault
[signal 0xc0000005 code=0x0 addr=0x41c06db4 pc=0x86ec3c]
goroutine 6 [running]:
runtime.throw({0x8be436, 0x89ce00})
C:/Users/wdvxdr/sdk/go1.17.1/src/runtime/panic.go:1198 +0x76 fp=0xc00004deb8 sp=0xc00004de88 pc=0x738896
runtime.sigpanic()
C:/Users/wdvxdr/sdk/go1.17.1/src/runtime/signal_windows.go:260 +0x10c fp=0xc00004df00 sp=0xc00004deb8 pc=0x74b52c
github.com/segmentio/encoding/proto.TestFix32Decode(0xc000037d40)
C:/Users/wdvxdr/Documents/Project/encoding/proto/decode_test.go:164 +0xbc fp=0xc00004df70 sp=0xc00004df00 pc=0x86ec3c
testing.tRunner(0xc000037d40, 0x8cd970)
C:/Users/wdvxdr/sdk/go1.17.1/src/testing/testing.go:1259 +0x102 fp=0xc00004dfc0 sp=0xc00004df70 pc=0x7f9dc2
testing.(*T).Run·dwrap·21()
C:/Users/wdvxdr/sdk/go1.17.1/src/testing/testing.go:1306 +0x2a fp=0xc00004dfe0 sp=0xc00004dfc0 pc=0x7faaca
runtime.goexit()
C:/Users/wdvxdr/sdk/go1.17.1/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc00004dfe8 sp=0xc00004dfe0 pc=0x767801
created by testing.(*T).Run
C:/Users/wdvxdr/sdk/go1.17.1/src/testing/testing.go:1306 +0x35a
goroutine 1 [chan receive]:
testing.(*T).Run(0xc000037ba0, {0x8c098e, 0x76a0d3}, 0x8cd970)
C:/Users/wdvxdr/sdk/go1.17.1/src/testing/testing.go:1307 +0x375
testing.runTests.func1(0xc0000706c0)
C:/Users/wdvxdr/sdk/go1.17.1/src/testing/testing.go:1598 +0x6e
testing.tRunner(0xc000037ba0, 0xc000079d18)
C:/Users/wdvxdr/sdk/go1.17.1/src/testing/testing.go:1259 +0x102
testing.runTests(0xc000102080, {0xa1a4e0, 0x17, 0x17}, {0x78a74d, 0x8c0705, 0x0})
C:/Users/wdvxdr/sdk/go1.17.1/src/testing/testing.go:1596 +0x43f
testing.(*M).Run(0xc000102080)
C:/Users/wdvxdr/sdk/go1.17.1/src/testing/testing.go:1504 +0x51d
main.main()
_testmain.go:119 +0x14b
Process finished with the exit code 1
Here is patch to fix this issue:
diff --git a/proto/struct.go b/proto/struct.go
--- a/proto/struct.go (revision cdc7e6667693911275e6060390016eff961cfa9d)
+++ b/proto/struct.go (date 1637659001795)
@@ -83,16 +83,16 @@
case Fixed32:
switch baseKindOf(f.Type) {
case reflect.Uint32:
- field.codec = &fixed32Codec
+ field.codec = fixPtrCodec(f.Type, &fixed32Codec)
case reflect.Float32:
- field.codec = &float32Codec
+ field.codec = fixPtrCodec(f.Type, &float32Codec)
}
case Fixed64:
switch baseKindOf(f.Type) {
case reflect.Uint64:
- field.codec = &fixed64Codec
+ field.codec = fixPtrCodec(f.Type, &fixed64Codec)
case reflect.Float64:
- field.codec = &float64Codec
+ field.codec = fixPtrCodec(f.Type, &float64Codec)
}
}
}
@@ -163,6 +163,18 @@
return t
}
+func fixPtrCodec(t reflect.Type, c *codec) *codec {
+ if t.Kind() == reflect.Ptr {
+ p := new(codec)
+ p.wire = c.wire
+ p.size = pointerSizeFuncOf(t, c)
+ p.encode = pointerEncodeFuncOf(t, c)
+ p.decode = pointerDecodeFuncOf(t, c)
+ c = p
+ }
+ return c
+}
+
func structSizeFuncOf(t reflect.Type, fields []structField) sizeFunc {
var inlined = inlined(t)
var unique, repeated []*structField