diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs index 5ecc71f0a76a49..95d386036f78d3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs @@ -380,13 +380,14 @@ internal static ParsingStatus TryParseBinaryIntegerStyle(ReadOn } else { - value = value.Slice(index); - index = 0; + // Slice a copy rather than reassigning value, so that index (and thus the number + // of elements reported as consumed) stays relative to the original input. + ReadOnlySpan remaining = value.Slice(index); ReadOnlySpan positiveSign = info.PositiveSignTChar(); ReadOnlySpan negativeSign = info.NegativeSignTChar(); - if (!positiveSign.IsEmpty && value.StartsWith(positiveSign)) + if (!positiveSign.IsEmpty && remaining.StartsWith(positiveSign)) { index += positiveSign.Length; @@ -396,7 +397,7 @@ internal static ParsingStatus TryParseBinaryIntegerStyle(ReadOn } num = TChar.CastToUInt32(value[index]); } - else if (!negativeSign.IsEmpty && value.StartsWith(negativeSign)) + else if (!negativeSign.IsEmpty && remaining.StartsWith(negativeSign)) { isNegative = true; index += negativeSign.Length; diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.cs index d3ce9ec7460708..fb1e4896557d39 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.cs @@ -1056,6 +1056,15 @@ public static IEnumerable TryParsePartial_TestData() // Stop at null character yield return new object[] { "123\0abc", NumberStyles.Integer, null, 123, 4 }; + + // Leading whitespace is counted as consumed even when the signs aren't the invariant "+"/"-" + NumberFormatInfo nonInvariantSignFormat = new NumberFormatInfo() { NegativeSign = "\u2212" }; + yield return new object[] { " 5", NumberStyles.Integer, nonInvariantSignFormat, 5, 2 }; + yield return new object[] { " 123abc", NumberStyles.Integer, nonInvariantSignFormat, 123, 5 }; + yield return new object[] { " +123abc", NumberStyles.Integer, nonInvariantSignFormat, 123, 6 }; + yield return new object[] { " \u2212456xyz", NumberStyles.Integer, nonInvariantSignFormat, -456, 6 }; + yield return new object[] { " \u2212456", NumberStyles.Integer, nonInvariantSignFormat, -456, 6 }; + yield return new object[] { " 123 abc", NumberStyles.Integer, nonInvariantSignFormat, 123, 7 }; } [Theory] diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.cs index 97b880831bcd68..3fa6f34c20745a 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.cs @@ -481,6 +481,12 @@ public static IEnumerable TryParsePartial_TestData() // Valid number without trailing characters yield return new object[] { "123", NumberStyles.Integer, null, 123u, 3 }; + + // Leading whitespace is counted as consumed even when the signs aren't the invariant "+"/"-" + NumberFormatInfo nonInvariantSignFormat = new NumberFormatInfo() { NegativeSign = "\u2212" }; + yield return new object[] { " 5", NumberStyles.Integer, nonInvariantSignFormat, 5u, 2 }; + yield return new object[] { " 123abc", NumberStyles.Integer, nonInvariantSignFormat, 123u, 5 }; + yield return new object[] { " +123abc", NumberStyles.Integer, nonInvariantSignFormat, 123u, 6 }; } [Theory]