Skip to content

Commit 0c63444

Browse files
bieluclaude
andcommitted
fix: accept only unsigned digits as pointer array indices and strip one integer sign
Parse JSON pointer array tokens with NumberStyles.None and the invariant culture, so tokens such as "-0", "+0" or " 0" no longer resolve to an element. When explaining an invalid integer, strip at most one leading sign so values such as "+-1" are reported as malformed rather than out of range. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 1084c6f commit 0c63444

3 files changed

Lines changed: 14 additions & 3 deletions

File tree

‎src/ByteBard.AsyncAPI.Readers/ParseNodes/JsonPointerExtensions.cs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
namespace ByteBard.AsyncAPI.Readers.ParseNodes
22
{
3+
using System.Globalization;
34
using System.Text.Json.Nodes;
45

56
public static class JsonPointerExtensions
@@ -16,7 +17,7 @@ public static JsonNode Find(this JsonPointer currentPointer, JsonNode baseJsonNo
1617
{
1718
if (pointer is JsonArray sequence)
1819
{
19-
if (!int.TryParse(token, out var index) || index < 0 || index >= sequence.Count)
20+
if (!int.TryParse(token, NumberStyles.None, CultureInfo.InvariantCulture, out var index) || index >= sequence.Count)
2021
{
2122
return null;
2223
}

‎src/ByteBard.AsyncAPI.Readers/ParseNodes/ValueNode.cs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,12 @@ public override AsyncApiAny CreateAny()
119119
private string DescribeInvalidInteger(string typeName, long min, long max)
120120
{
121121
var value = this.GetScalarValue();
122-
var digits = value?.Trim().TrimStart('+', '-');
122+
var digits = value?.Trim();
123+
if (digits?.Length > 0 && (digits[0] == '+' || digits[0] == '-'))
124+
{
125+
digits = digits.Substring(1);
126+
}
127+
123128
var isWholeNumber = !string.IsNullOrEmpty(digits) && digits.All(c => c >= '0' && c <= '9');
124129

125130
return isWholeNumber

‎test/ByteBard.AsyncAPI.Tests/ReaderErrorDetails_Should.cs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ internal class ReaderErrorDetails_Should : TestBase
1111
{
1212
[TestCase("abc", "Value 'abc' could not parse to integer. Expected a whole number.")]
1313
[TestCase("1.5", "Value '1.5' could not parse to integer. Expected a whole number.")]
14-
[TestCase("99999999999", "Value '99999999999' could not parse to integer. It must be between -2147483648 and 2147483647.")]
14+
[TestCase("+-1", "Value '+-1' could not parse to integer. Expected a whole number.")]
15+
[TestCase("--1", "Value '--1' could not parse to integer. Expected a whole number.")]
16+
[TestCase("99999999999","Value '99999999999' could not parse to integer. It must be between -2147483648 and 2147483647.")]
1517
public void SchemaIntegerField_ReportsTheValueAndWhyItIsInvalid(string value, string expectedMessage)
1618
{
1719
var yaml = $"type: string\nmaxLength: '{value}'";
@@ -49,6 +51,9 @@ public void MissingLocalReference_IsReportedOnce()
4951
[TestCase("/info/title/nested")]
5052
[TestCase("/tags/5")]
5153
[TestCase("/tags/name")]
54+
[TestCase("/tags/-0")]
55+
[TestCase("/tags/+0")]
56+
[TestCase("/tags/ 0")]
5257
[TestCase("/missing")]
5358
public void Find_ReturnsNull_WhenThePointerDoesNotLeadToANode(string pointer)
5459
{

0 commit comments

Comments
 (0)