Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

regexp: calling json.Marshal on a wrapped *regexp.Regexp causes "panic: runtime error: invalid memory address or nil pointer dereference" #63784

Closed
mlucic opened this issue Oct 27, 2023 · 2 comments

Comments

@mlucic
Copy link

mlucic commented Oct 27, 2023

What version of Go are you using (go version)?

1.21

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

Go playground

What did you do?

Example in playground: https://go.dev/play/p/AfP164Go__e

When wrapping *regexp.Regexp in a struct, then making an instance of that struct leaving Regexp as nil, calling json.Marshal on the struct will result in a panic.

panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x49689a]

goroutine 1 [running]:
encoding/json.(*encodeState).marshal.func1()
	/usr/local/go-faketime/src/encoding/json/encode.go:291 +0x6d
panic({0x4a34a0?, 0x554da0?})
	/usr/local/go-faketime/src/runtime/panic.go:914 +0x21f
regexp.(*Regexp).String(...)
	/usr/local/go-faketime/src/regexp/regexp.go:110
regexp.(*Regexp).MarshalText(...)
	/usr/local/go-faketime/src/regexp/regexp.go:1294
encoding/json.textMarshalerEncoder(0xc00001c080, {0x4b24a0?, 0xc000042020?, 0xc00001c080?}, {0x40?, 0x0?})
	/usr/local/go-faketime/src/encoding/json/encode.go:483 +0xe2
encoding/json.(*encodeState).reflectValue(0xc00001c080?, {0x4b24a0?, 0xc000042020?, 0x40c3c5?}, {0x38?, 0x0?})
	/usr/local/go-faketime/src/encoding/json/encode.go:323 +0x73
encoding/json.(*encodeState).marshal(0xc00003e730?, {0x4b24a0?, 0xc000042020?}, {0x5?, 0xdd?})
	/usr/local/go-faketime/src/encoding/json/encode.go:295 +0xb9
encoding/json.Marshal({0x4b24a0, 0xc000042020})
	/usr/local/go-faketime/src/encoding/json/encode.go:162 +0xd0
main.main()
	/tmp/sandbox508103789/prog.go:15 +0x2d

This did not happen in go 1.20. You can see switch the version on the playground to 1.20 and the program will succeed. The dev branch also has the same problem.

What did you expect to see?

There should not be a panic when invoking json.Marshal on the struct.

What did you see instead?

There was a panic.

@rittneje
Copy link

Go 1.21 added a MarshalText method to regexp.Regexp. Since you are embedding it, your struct inherits that method. Consequently, json.Marshal calls it. However, regexp.Regexp.MarshalText panics if the receiver is nil, which normally is fine since json.Marshal wouldn't call it in that case. But here it did because it believes it is calling a method on your struct, which isn't nil.

I'll also note that even without the panic, the 1.20 behavior cannot be restored, because json.Marshal will only consider the inherited MarshalText method and will no longer marshal your struct the usual way. (That is, it will marshal as a string not as an object.)

As there is no way to avoid inheriting a particular method, your only options are to either not embed regexp.Regexp, or explicitly add a MarshalJSON method to your struct.

As an aside, it would be nice if json.Marshal could tell whether MarshalText/MarshalJSON was inherited, since it seems like something that isn't generally intended (or at least you could use `json:"-"` to ignore it).

@seankhliao
Copy link
Member

see above, unfortunate but I don't think there's anything to change.

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Oct 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants