Affects all Go versions since ever.
In some situation it may be desirable to build several strings which happen to prefix each other. Examples of such uses are filesystem hierarchies, x509 OIDs and other similar objects.
Nothing in the strings.Builder documentation implies, that an enterprising user will not be able to keep adding fragments to the builder after calling the String method once or twice.
Let's consider the following example:
var b strings.Builder
b.Grow(20)
b.WriteString("aaa")
x := b.String()
fmt.Printf("%s %p\n", x, unsafe.StringData(x))
b.WriteString("bbb")
y := b.String()
fmt.Printf("%s %p\n", y, unsafe.StringData(y))
Outputs:
aaa 0xc0000b2000
aaabbb 0xc0000b2000
Basically, we are able to break a cornerstone Go invariant with some really basic usage of "beginner" level facilities without any warning.
As a side note, it is not obvious why Builder is explicitly made non-copyable. Nothing bad will happen if a similar structure is copied here and there, it keeps working just fine, unlike this here issue.