Skip to content

Fix integer overflow in TextHelpAppendable.indexOfWrap - #437

Merged
garydgregory merged 2 commits into
apache:masterfrom
rootvector2:indexofwrap-overflow
Aug 8, 2026
Merged

Fix integer overflow in TextHelpAppendable.indexOfWrap#437
garydgregory merged 2 commits into
apache:masterfrom
rootvector2:indexofwrap-overflow

Conversation

@rootvector2

Copy link
Copy Markdown
Contributor

indexOfWrap computes the wrap boundary as startPos + width in int math. width is Integer.MAX_VALUE for any TextStyle left at the default UNSET_MAX_WIDTH, so once startPos > 0 (any text containing a break character) the sum overflows negative, indexOfWrap returns a negative index, and makeColumnQueue calls subSequence(startPos, <negative>), throwing StringIndexOutOfBoundsException. Found while reviewing the help text wrapping.

Repro:

new TextHelpAppendable(new StringBuilder()).printWrapped("Hello\nWorld", TextStyle.DEFAULT);
// StringIndexOutOfBoundsException: Range [6, -2147483644) out of bounds for length 11

Computing the boundary as a long keeps every in-range result identical. The added indexOfWrap assertion returns the negative index before the change and the string length after.

  • Read the contribution guidelines for this project.
  • Read the ASF Generative Tooling Guidance if you use Artificial Intelligence (AI).
  • I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute?
  • Run a successful build using the default Maven goal with mvn; that's mvn on the command line by itself.
  • Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process.

startPos + width overflowed to a negative value when width is Integer.MAX_VALUE (the default TextStyle.UNSET_MAX_WIDTH), so indexOfWrap returned a negative wrap position and makeColumnQueue threw StringIndexOutOfBoundsException. Compute the wrap boundary as a long.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an integer overflow in TextHelpAppendable.indexOfWrap when a TextStyle uses the unbounded sentinel width (UNSET_MAX_WIDTH / Integer.MAX_VALUE), preventing negative wrap indexes that can crash wrapping logic (e.g., via makeColumnQueue).

Changes:

  • Compute the wrap boundary (startPos + width) using long arithmetic to avoid int overflow.
  • Update boundary comparisons and limits to use the long boundary safely.
  • Add unit tests covering the overflow scenario with Integer.MAX_VALUE width.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/main/java/org/apache/commons/cli/help/TextHelpAppendable.java Avoids int overflow in wrap-boundary calculation by using long, preventing negative wrap indices.
src/test/java/org/apache/commons/cli/help/TextHelpAppendableTest.java Adds regression assertions for the unbounded-width overflow scenario.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/test/java/org/apache/commons/cli/help/TextHelpAppendableTest.java Outdated
@garydgregory garydgregory changed the title fix integer overflow in TextHelpAppendable.indexOfWrap Fix integer overflow in TextHelpAppendable.indexOfWrap Aug 8, 2026
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@garydgregory
garydgregory merged commit dc69e84 into apache:master Aug 8, 2026
10 of 11 checks passed
@garydgregory

Copy link
Copy Markdown
Member

Thank you @rootvector2 , merged 🚀

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.

3 participants