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

reflect: StructOf field offset calculation may overflow #52740

lmb opened this issue May 6, 2022 · 1 comment

reflect: StructOf field offset calculation may overflow #52740

lmb opened this issue May 6, 2022 · 1 comment


Copy link

@lmb lmb commented May 6, 2022

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

% go version
go version go1.18.1 darwin/arm64

Does this issue reproduce with the latest release?


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

Darwin / amd64.

What did you do?

func TestLargeArray(t *testing.T) {
	elem := reflect.TypeOf(uint32(0))
	max := int(^uintptr(0) / elem.Size())
	arr := reflect.ArrayOf(max, elem)

	fields := []reflect.StructField{
		{Name: "A", Type: arr},
		{Name: "B", Type: reflect.TypeOf("")},

	typ := reflect.StructOf(fields)
	var offset uintptr
	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		if i > 0 && field.Offset == offset {
			t.Fatalf("field %d: duplicate offset %d", i, field.Offset)
		} else {
			t.Logf("field %d: offset %d", i, field.Offset)
		offset = field.Offset

What did you expect to see?

I'd expect offsets to be correct or StructOf to panic.

What did you see instead?

=== RUN   TestLargeArray
    foo_test.go:107: field 0: offset 0
    foo_test.go:105: field 1: duplicate offset 0
--- FAIL: TestLargeArray (0.00s)

I think the problem lies in this call to align:

offset := align(size, uintptr(ft.align))

On my machine, size is 0xfffffffffffffffc and ft.align is 8 for field B. 0xfffffffffffffffc + 0x7 is 0x10000000000000003 aka 0x0000000000000003 due to truncation / overflow.

Copy link

@randall77 randall77 commented May 6, 2022

Looks like structs aren't defensive against overflow in general. Adding complication, we only store 63 bits of size, not 64.

@randall77 randall77 added this to the Go1.19 milestone May 6, 2022
@randall77 randall77 added the NeedsFix label May 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

No branches or pull requests

2 participants