Skip to content

strings: Builder.String should either reset the Builder or avoid using unsafe semantics #60580

@oakad

Description

@oakad

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions