Skip to content

fix: prevent stack overflow on circular key references during value expansion - #412

Closed
AdamMagued wants to merge 1 commit into
go-ini:mainfrom
AdamMagued:fix-circular-reference-stack-overflow
Closed

AdamMagued wants to merge 1 commit into
go-ini:mainfrom
AdamMagued:fix-circular-reference-stack-overflow

Conversation

@AdamMagued

Copy link
Copy Markdown

When resolving variable references (%(name)s), circular references between keys (such as a = %(b)s and b = %(a)s, or self-references in the default section) result in infinite mutual recursive expansion during Key.String() evaluation, causing a fatal goroutine stack overflow crash.

Root Cause

Key.transformValue recursively called nk.String() to resolve nested variable substitutions without tracking visited keys or bounding the recursion depth across calls. In the presence of a reference cycle, this led to unbounded recursive calls.

Changes

  1. Track visited *Key pointers along the expansion chain using hasVisitedKey and transformValueWithVisited.
  2. Terminate expansion cleanly when a circular key reference or recursion depth exceeding depthValues (99) is encountered.
  3. Stop repeating substitution when the resolved value contains the variable token itself, avoiding redundant loops on unresolvable references.
  4. Add regression tests in key_test.go covering two-key mutual circular references, default section self-references, and multi-key cycles.

Fixes #409

…xpansion

When expanding variable references (%(name)s), circular references
between keys (such as a = %(b)s and b = %(a)s, or self-references
in the default section) lead to infinite recursion during Key.String()
evaluation, resulting in a fatal goroutine stack overflow panic.

Track visited keys along the expansion path and enforce the recursion
depth limit depthValues during recursive substitution. When a circular
reference or unresolvable key is encountered, stop recursion cleanly and
return the current string without crashing. Add regression tests covering
mutual circular references, default section self-references, and multi-key cycles.

Fixes go-ini#409
@AdamMagued

Copy link
Copy Markdown
Author

Closing in favor of earlier community PR #410 to keep the review queue clean.

@AdamMagued AdamMagued closed this Oct 2, 2026
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.

Key.String() overflows the stack when two keys reference each other

1 participant