mirror of
https://github.com/zap-proto/zip.git
synced 2026-10-19 15:38:57 +00:00
zap reads text zero-copy over the frame that arrived, and Call releases that frame to the pool when it returns, so a reply's strings pointed into memory the next call overwrites. The generated codecs already copy text for this reason; the reflective decoder now does the same. Co-Authored-By: Claude Opus 5.5 <[email protected]>
35 lines
956 B
Go
35 lines
956 B
Go
package zapenc_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/zap-proto/zip/internal/zapenc"
|
|
)
|
|
|
|
// A decoded value owns its strings. The transport hands Unmarshal a pooled frame
|
|
// and reuses it for the next call, so a string that still pointed into the frame
|
|
// would change under whoever kept it.
|
|
func TestDecodedTextOutlivesTheFrame(t *testing.T) {
|
|
type site struct {
|
|
Bucket string
|
|
Prefix string
|
|
Opt *string
|
|
Inner inner
|
|
}
|
|
s := "gone"
|
|
frame, err := zapenc.Marshal(&site{Bucket: "hanzo-sites", Prefix: "hanzo/bootnode", Opt: &s, Inner: inner{Slug: "bootnode"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var got site
|
|
if err := zapenc.Unmarshal(frame, &got); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for i := range frame {
|
|
frame[i] = 'x'
|
|
}
|
|
if got.Bucket != "hanzo-sites" || got.Prefix != "hanzo/bootnode" || got.Opt == nil || *got.Opt != "gone" || got.Inner.Slug != "bootnode" {
|
|
t.Fatalf("decoded strings follow the frame: %+v opt=%v", got, got.Opt)
|
|
}
|
|
}
|