Skip to content

Return false from Duration.TryParse when the reduced fraction overflows int [patch] - #435

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/434-duration-tryparse-overflow
Oct 18, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/434-duration-tryparse-overflow

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #434

Before: Duration.TryParse("-2147483648/-1", out _) threw OverflowException. Every parser that reads durations through it threw too: Note, Rest, ChordEvent, Section, Progression and Arrangement.

After: TryParse returns false, and Parse throws the same FormatException it throws for any other bad text. Duration.Create(int.MinValue, -1) still throws OverflowException as #306 intended.

How: TryParse now catches the OverflowException from Create and returns false. I didn't use the guard the issue suggests (numerator == int.MinValue && denominator < 0), because it is wrong in both directions:

  • It would miss -2147483648/-3. Any odd negative denominator leaves 2^31 after reduction, which overflows too.
  • It would wrongly reject -2147483648/-2, which reduces to 2^30 and fits.

Catching the exception lets Reduce remain the one place that decides what fits.

Tests (in DurationTests)

  • TryParseFailsWhenTheReducedFractionDoesNotFitInInt covers -2147483648/-1 and /-3, for both TryParse and Parse.
  • TryParseAcceptsIntMinValueOverANegativeDenominatorWhenTheReducedFractionFits covers -2147483648/-2.
  • ContainerTryParseFailsRatherThanThrowingOnAnOverflowingDuration covers ChordEvent and Progression.
  • With the fix reverted, 3 of these fail. With it, the full Semantics.Test suite passes on net10.0 (1703 tests).
  • Semantics.Music builds every target framework with no warnings.
  • The local Sonar build finds nothing in Duration.cs. It does report S1192 in Mode.cs and S3267 in Section.cs, both in files this PR doesn't touch.

Generated by Claude Code

…ws int [patch]

"-2147483648/-1" (or any odd negative denominator under int.MinValue)
made Create throw OverflowException, which escaped TryParse and every
container parser that reads durations through it: Note, Rest,
ChordEvent, Section, Progression and Arrangement. Catch it and fail the
parse instead, so Parse reports FormatException as for other bad text.

Fixes #434

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014uT14TvqqVJCgHTyBKHpKx
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 28b9836 into main Oct 18, 2026
16 checks passed
@matt-edmondson
matt-edmondson deleted the fix/434-duration-tryparse-overflow branch October 18, 2026 10:48
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.

Duration.TryParse("-2147483648/-1") throws OverflowException instead of returning false, and so do Note/Rest/ChordEvent/Progression/Arrangement.TryParse

2 participants