Skip to content

avoid sharing title casing state between generators - #14

Merged
Splode merged 1 commit into
Splode:mainfrom
crazy-max:fix-concurrent-title-casing
Oct 24, 2026
Merged

Splode merged 1 commit into
Splode:mainfrom
crazy-max:fix-concurrent-title-casing

Conversation

@crazy-max

@crazy-max crazy-max commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Generating title-cased names concurrently can race and panic even when each goroutine owns a separate Generator, as the documentation recommends. All generators currently share a package-level cases.Caser, whose mutable state is modified during conversion. Create a fresh caser for each title conversion to eliminate the shared state while preserving existing Unicode casing behavior.

Before the fix, this produced data-race reports followed by the following panic. Note that the panic and its exact message depend on goroutine scheduling.

--- FAIL: TestGenerateTitleConcurrent (0.00s)
    --- FAIL: TestGenerateTitleConcurrent/unicode (0.00s)
        testing.go:1867: race detected during execution of test
panic: runtime error: slice bounds out of range [7:5] [recovered, repanicked]

The panic originated in golang.org/x/text/transform.String, called through cases.Caser.String and Generator.applyCasing.

The package-level title caser shares mutable state even when each
goroutine owns a separate Generator, causing data races and panics.
Create a fresh caser for each title conversion to preserve the existing
Unicode casing behavior without sharing state.
@Splode
Splode merged commit ac639c9 into Splode:main Oct 24, 2026
7 checks passed
@Splode

Splode commented Oct 24, 2026

Copy link
Copy Markdown
Owner

Brilliant. Thank you for the contribution, @crazy-max

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

Successfully merging this pull request may close these issues.

2 participants