fix: avoid infinite recursion when formatting ranges as short npm

TryFormat for the "ns" format returned false for any set that can
not be expressed as a caret/tilde range. The public ToString
routes through DefaultInterpolatedStringHandler, whose buffer-full
fallback re-enters ToString, causing an infinite loop / stack overflow.

For "ns", fall back to the full comparator ("n") form when the
compact form cannot represent the set, so the call always succeeds
for a representable range. A genuine buffer overflow still returns
false as before.

Add failing-then-passing tests.
This commit is contained in:
Louis Seubert 2026-07-11 21:57:23 +02:00
commit ae2163188f
3 changed files with 34 additions and 1 deletions

View file

@ -257,6 +257,21 @@ internal sealed class SemanticVersionRangeTests
await Assert.That(range.Contains(SemanticVersion.Parse("1.2.4"))).IsFalse();
}
[Test]
[Arguments("[1.2.3,1.4.0)", ">=1.2.3 <1.4.0")]
[Arguments(">1.0.0", ">1.0.0")]
[Arguments("[1.2,1.3]", ">=1.2.0 <=1.3.0")]
[Arguments("(,1.4.0]", "<=1.4.0")]
public async Task I_can_format_ranges_as_short_npm_even_when_not_caret_tilde(string range, string expected)
{
var value = SemanticVersionRange.Parse(range);
var destination = new char[256];
var success = value.TryFormat(destination, out var charsWritten, "ns", null);
await Assert.That(success).IsTrue();
await Assert.That(new string(destination[..charsWritten])).IsEqualTo(expected);
}
[Test]
public async Task I_fail_formatting_when_the_tentative_short_form_overflows()
{