From f810369f2d91ab47b97b0f82adc1a92344d56d89 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Tue, 11 Jan 2022 15:11:17 +0900 Subject: [PATCH] Fix encoding of MarshalText operation with head offset --- encode_test.go | 31 ++++++++++++++++++++++++++ internal/cmd/generator/vm.go.tmpl | 17 +++++++++----- internal/encoder/vm/vm.go | 17 +++++++++----- internal/encoder/vm_color/vm.go | 17 +++++++++----- internal/encoder/vm_color_indent/vm.go | 17 +++++++++----- internal/encoder/vm_indent/vm.go | 17 +++++++++----- 6 files changed, 86 insertions(+), 30 deletions(-) diff --git a/encode_test.go b/encode_test.go index 1b88d52..ce6a336 100644 --- a/encode_test.go +++ b/encode_test.go @@ -2308,3 +2308,34 @@ func TestMarshalIndent(t *testing.T) { t.Fatalf("expected: %q but got %q", expected, got) } } + +type issue318Embedded struct { + _ [64]byte +} + +type issue318 struct { + issue318Embedded `json:"-"` + ID issue318MarshalText `json:"id,omitempty"` +} + +type issue318MarshalText struct { + ID string +} + +func (i issue318MarshalText) MarshalText() ([]byte, error) { + return []byte(i.ID), nil +} + +func TestIssue318(t *testing.T) { + v := issue318{ + ID: issue318MarshalText{ID: "1"}, + } + b, err := json.Marshal(v) + if err != nil { + t.Fatal(err) + } + expected := `{"id":"1"}` + if string(b) != expected { + t.Fatalf("failed to encode. expected %s but got %s", expected, string(b)) + } +} diff --git a/internal/cmd/generator/vm.go.tmpl b/internal/cmd/generator/vm.go.tmpl index fb1ec4d..91b11e1 100644 --- a/internal/cmd/generator/vm.go.tmpl +++ b/internal/cmd/generator/vm.go.tmpl @@ -705,14 +705,15 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } - u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + p += uintptr(code.Offset) + u64 := ptrToUint64(p, code.NumBitSize) v := u64 & ((1 << code.NumBitSize) - 1) if v == 0 { code = code.NextField } else { b = appendStructKey(ctx, code, b) b = append(b, '"') - b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendInt(ctx, b, p, code) b = append(b, '"') b = appendComma(ctx, b) code = code.Next @@ -2953,9 +2954,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b b = appendStructHead(ctx, b) } b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { @@ -2994,9 +2996,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } iface := ptrToInterface(code, p) @@ -3114,9 +3117,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b b = appendStructHead(ctx, b) } b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { @@ -3155,9 +3159,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { diff --git a/internal/encoder/vm/vm.go b/internal/encoder/vm/vm.go index fb1ec4d..91b11e1 100644 --- a/internal/encoder/vm/vm.go +++ b/internal/encoder/vm/vm.go @@ -705,14 +705,15 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } - u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + p += uintptr(code.Offset) + u64 := ptrToUint64(p, code.NumBitSize) v := u64 & ((1 << code.NumBitSize) - 1) if v == 0 { code = code.NextField } else { b = appendStructKey(ctx, code, b) b = append(b, '"') - b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendInt(ctx, b, p, code) b = append(b, '"') b = appendComma(ctx, b) code = code.Next @@ -2953,9 +2954,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b b = appendStructHead(ctx, b) } b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { @@ -2994,9 +2996,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } iface := ptrToInterface(code, p) @@ -3114,9 +3117,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b b = appendStructHead(ctx, b) } b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { @@ -3155,9 +3159,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { diff --git a/internal/encoder/vm_color/vm.go b/internal/encoder/vm_color/vm.go index 1ce3fc1..5c6c52c 100644 --- a/internal/encoder/vm_color/vm.go +++ b/internal/encoder/vm_color/vm.go @@ -705,14 +705,15 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } - u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + p += uintptr(code.Offset) + u64 := ptrToUint64(p, code.NumBitSize) v := u64 & ((1 << code.NumBitSize) - 1) if v == 0 { code = code.NextField } else { b = appendStructKey(ctx, code, b) b = append(b, '"') - b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendInt(ctx, b, p, code) b = append(b, '"') b = appendComma(ctx, b) code = code.Next @@ -2953,9 +2954,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b b = appendStructHead(ctx, b) } b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { @@ -2994,9 +2996,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } iface := ptrToInterface(code, p) @@ -3114,9 +3117,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b b = appendStructHead(ctx, b) } b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { @@ -3155,9 +3159,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { diff --git a/internal/encoder/vm_color_indent/vm.go b/internal/encoder/vm_color_indent/vm.go index 506c10c..42dc11c 100644 --- a/internal/encoder/vm_color_indent/vm.go +++ b/internal/encoder/vm_color_indent/vm.go @@ -705,14 +705,15 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } - u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + p += uintptr(code.Offset) + u64 := ptrToUint64(p, code.NumBitSize) v := u64 & ((1 << code.NumBitSize) - 1) if v == 0 { code = code.NextField } else { b = appendStructKey(ctx, code, b) b = append(b, '"') - b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendInt(ctx, b, p, code) b = append(b, '"') b = appendComma(ctx, b) code = code.Next @@ -2953,9 +2954,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b b = appendStructHead(ctx, b) } b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { @@ -2994,9 +2996,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } iface := ptrToInterface(code, p) @@ -3114,9 +3117,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b b = appendStructHead(ctx, b) } b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { @@ -3155,9 +3159,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { diff --git a/internal/encoder/vm_indent/vm.go b/internal/encoder/vm_indent/vm.go index 5e17673..dfe0cc6 100644 --- a/internal/encoder/vm_indent/vm.go +++ b/internal/encoder/vm_indent/vm.go @@ -705,14 +705,15 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } - u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize) + p += uintptr(code.Offset) + u64 := ptrToUint64(p, code.NumBitSize) v := u64 & ((1 << code.NumBitSize) - 1) if v == 0 { code = code.NextField } else { b = appendStructKey(ctx, code, b) b = append(b, '"') - b = appendInt(ctx, b, p+uintptr(code.Offset), code) + b = appendInt(ctx, b, p, code) b = append(b, '"') b = appendComma(ctx, b) code = code.Next @@ -2953,9 +2954,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b b = appendStructHead(ctx, b) } b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { @@ -2994,9 +2996,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } iface := ptrToInterface(code, p) @@ -3114,9 +3117,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b b = appendStructHead(ctx, b) } b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { @@ -3155,9 +3159,10 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b if code.Flags&encoder.AnonymousHeadFlags == 0 { b = appendStructHead(ctx, b) } + p += uintptr(code.Offset) if (code.Flags & encoder.IsNilableTypeFlags) != 0 { if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { - p = ptrToPtr(p + uintptr(code.Offset)) + p = ptrToPtr(p) } } if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {