From 95436465a558264fb97883f1ded7497dcb490772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Wed, 28 Feb 2024 17:32:00 +0100 Subject: [PATCH 1/3] reset runtime context options before releasing it back into pool --- encode_test.go | 38 +++++++++++++++++++++++++++++-------- internal/decoder/context.go | 1 + internal/encoder/context.go | 1 + 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/encode_test.go b/encode_test.go index 1165f6a6..0c26d84a 100644 --- a/encode_test.go +++ b/encode_test.go @@ -1999,30 +1999,33 @@ type marshalContextKey struct{} type marshalContextStructType struct{} func (t *marshalContextStructType) MarshalJSON(ctx context.Context) ([]byte, error) { + if ctx == nil { + return []byte(`"no context"`), nil + } v := ctx.Value(marshalContextKey{}) + if v == nil { + return []byte(`"no value in context"`), nil + } s, ok := v.(string) if !ok { - return nil, fmt.Errorf("failed to propagate parent context.Context") + return []byte(`"unexpected value in context"`), nil } - if s != "hello" { - return nil, fmt.Errorf("failed to propagate parent context.Context") - } - return []byte(`"success"`), nil + return []byte(`"` + s + `"`), nil } func TestEncodeContextOption(t *testing.T) { t.Run("MarshalContext", func(t *testing.T) { - ctx := context.WithValue(context.Background(), marshalContextKey{}, "hello") + ctx := context.WithValue(context.Background(), marshalContextKey{}, "success") b, err := json.MarshalContext(ctx, &marshalContextStructType{}) if err != nil { t.Fatal(err) } if string(b) != `"success"` { - t.Fatal("failed to encode with MarshalerContext") + t.Fatal("failed to encode with MarshalContext") } }) t.Run("EncodeContext", func(t *testing.T) { - ctx := context.WithValue(context.Background(), marshalContextKey{}, "hello") + ctx := context.WithValue(context.Background(), marshalContextKey{}, "success") buf := bytes.NewBuffer([]byte{}) if err := json.NewEncoder(buf).EncodeContext(ctx, &marshalContextStructType{}); err != nil { t.Fatal(err) @@ -2031,6 +2034,25 @@ func TestEncodeContextOption(t *testing.T) { t.Fatal("failed to encode with EncodeContext") } }) + t.Run("Marshal after MarshalContext", func(t *testing.T) { + // Regression test for https://github.com/goccy/go-json/issues/499 + ctx := context.WithValue(context.Background(), marshalContextKey{}, "success") + b, err := json.MarshalContext(ctx, &marshalContextStructType{}) + if err != nil { + t.Fatal(err) + } + if string(b) != `"success"` { + t.Fatal("failed to encode with MarshalContext") + } + + b, err = json.Marshal(&marshalContextStructType{}) + if err != nil { + t.Fatal(err) + } + if string(b) != `"no context"` { + t.Fatal("failed to encode with Marshal") + } + }) } func TestInterfaceWithPointer(t *testing.T) { diff --git a/internal/decoder/context.go b/internal/decoder/context.go index cb2ffdaf..74b09978 100644 --- a/internal/decoder/context.go +++ b/internal/decoder/context.go @@ -27,6 +27,7 @@ func TakeRuntimeContext() *RuntimeContext { } func ReleaseRuntimeContext(ctx *RuntimeContext) { + ctx.Option = &Option{} runtimeContextPool.Put(ctx) } diff --git a/internal/encoder/context.go b/internal/encoder/context.go index 3833d0c8..14c0f769 100644 --- a/internal/encoder/context.go +++ b/internal/encoder/context.go @@ -101,5 +101,6 @@ func TakeRuntimeContext() *RuntimeContext { } func ReleaseRuntimeContext(ctx *RuntimeContext) { + ctx.Option = &Option{} runtimeContextPool.Put(ctx) } From abd07bc4a7c0aa395054725910d707f4000ce69f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Thu, 9 May 2024 14:42:26 +0200 Subject: [PATCH 2/3] trigger CI From 51b231f87e8798aa38eedd1883a125c4de5c8e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lovro=20Ma=C5=BEgon?= Date: Tue, 21 May 2024 18:55:24 +0200 Subject: [PATCH 3/3] set context to nil --- internal/decoder/context.go | 2 +- internal/encoder/context.go | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/decoder/context.go b/internal/decoder/context.go index 74b09978..ff2b3696 100644 --- a/internal/decoder/context.go +++ b/internal/decoder/context.go @@ -27,7 +27,7 @@ func TakeRuntimeContext() *RuntimeContext { } func ReleaseRuntimeContext(ctx *RuntimeContext) { - ctx.Option = &Option{} + ctx.Option.Context = nil runtimeContextPool.Put(ctx) } diff --git a/internal/encoder/context.go b/internal/encoder/context.go index 14c0f769..c6795ea6 100644 --- a/internal/encoder/context.go +++ b/internal/encoder/context.go @@ -1,7 +1,6 @@ package encoder import ( - "context" "sync" "unsafe" @@ -69,7 +68,6 @@ var ( ) type RuntimeContext struct { - Context context.Context Buf []byte MarshalBuf []byte Ptrs []uintptr @@ -101,6 +99,6 @@ func TakeRuntimeContext() *RuntimeContext { } func ReleaseRuntimeContext(ctx *RuntimeContext) { - ctx.Option = &Option{} + ctx.Option.Context = nil runtimeContextPool.Put(ctx) }