Closed
Description
Go version
1.24
Output of go env
in your module/workspace:
It works even in the go playground, however here is my go env output:
AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE='on'
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN='/Users/mgk/go/bin'
GOCACHE='/Users/mgk/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/mgk/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/48/cr9dcv1d6tqghyswpt5d306m0000gn/T/go-build3280202846=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/Users/mgk/go/pkg/mod'
GOOS='darwin'
GOPATH='/Users/mgk/go'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/mgk/sdk/go1.24.1'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/mgk/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/mgk/sdk/go1.24.1/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.24.1'
GOWORK=''
PKG_CONFIG='pkg-config'
What did you do?
I am working on a pretty big project where multiple libraries are working together. I have recently found out the weird following behaviour after one of the libraries in use produced a string with a nil-data pointer and a non-zero length.
https://go.dev/play/p/xGBLKtttmdC
I have put the example into this string, however here once again:
var s string
// Der Stacktrace zeigt uns nen String wie diesen hier
// Sowas kann im Normalfall gar nicht entstehen, aber zur Demo Hier mal ein Beispiel
hdr := reflect.StringHeader{
Data: 0, // nil pointer
Len: 40, // non-zero length
}
// Convert to string using unsafe
s = *(*string)(unsafe.Pointer(&hdr))
// Extract StringHeader from the resulting string
hdr2 := (*reflect.StringHeader)(unsafe.Pointer(&s))
// Print pointer and length
fmt.Printf("Data pointer: %v\n", hdr2.Data)
fmt.Printf("Length: %d\n", hdr2.Len)
// This will panic:
for i, r := range s {
fmt.Printf("Index: %d, Rune: %c\n", i, r)
}
What did you see happen?
The range will panic since (presumably) the range does only check if the len is greater than 0, not if the Data pointer is valid.
What did you expect to see?
I am not sure if this is expected behaviour in the go runtime. I can also not tell you which of the libraries I use in my project produced such a string, however I will continue to investigate and try to find the broken library.