diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index b9e64ca855d1..7395de80b056 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -172,21 +172,38 @@ internal static void ValidateNumber(ReadOnlySpan utf8FormattedNumber) return; } + // The non digit character inside the number byte val = utf8FormattedNumber[i]; if (val == '.') { i++; + + while (i < utf8FormattedNumber.Length && JsonHelpers.IsDigit(utf8FormattedNumber[i])) + { + i++; + } + + if (utf8FormattedNumber.Length < i) + { + throw new ArgumentException(SR.RequiredDigitNotFoundEndOfData, nameof(utf8FormattedNumber)); + } } - else if (val == 'e' || val == 'E') + + if (i == utf8FormattedNumber.Length) + { + return; + } + + val = utf8FormattedNumber[i]; + + if (val == 'e' || val == 'E') { i++; - if (i >= utf8FormattedNumber.Length) + if (utf8FormattedNumber.Length <= i) { - throw new ArgumentException( - SR.RequiredDigitNotFoundEndOfData, - nameof(utf8FormattedNumber)); + throw new ArgumentException(SR.RequiredDigitNotFoundEndOfData, nameof(utf8FormattedNumber)); } val = utf8FormattedNumber[i]; @@ -203,11 +220,9 @@ internal static void ValidateNumber(ReadOnlySpan utf8FormattedNumber) nameof(utf8FormattedNumber)); } - if (i >= utf8FormattedNumber.Length) + if (utf8FormattedNumber.Length <= i) { - throw new ArgumentException( - SR.RequiredDigitNotFoundEndOfData, - nameof(utf8FormattedNumber)); + throw new ArgumentException(SR.RequiredDigitNotFoundEndOfData, nameof(utf8FormattedNumber)); } while (i < utf8FormattedNumber.Length && JsonHelpers.IsDigit(utf8FormattedNumber[i])) diff --git a/src/System.Text.Json/tests/JsonElementWriteTests.cs b/src/System.Text.Json/tests/JsonElementWriteTests.cs index 7866ef6cf17a..25830ea6274d 100644 --- a/src/System.Text.Json/tests/JsonElementWriteTests.cs +++ b/src/System.Text.Json/tests/JsonElementWriteTests.cs @@ -30,11 +30,39 @@ public static void WriteNumber(bool indented) } [Theory] - [InlineData(false)] - [InlineData(true)] - public static void WriteNumberScientific(bool indented) + [InlineData("1e6", false)] + [InlineData("1e6", true)] + [InlineData("1e+6", false)] + [InlineData("1e+6", true)] + [InlineData("1e-6", false)] + [InlineData("1e-6", true)] + [InlineData("-1e6", false)] + [InlineData("-1e6", true)] + [InlineData("-1e+6", true)] + [InlineData("-1e+6", true)] + [InlineData("-1e-6", false)] + [InlineData("-1e-6", true)] + public static void WriteNumberScientific(string value, bool indented) + { + WriteSimpleValue(indented, value); + } + + [Theory] + [InlineData("5.012e-20", false)] + [InlineData("5.012e-20", true)] + [InlineData("5.012e20", false)] + [InlineData("5.012e20", true)] + [InlineData("5.012e+20", false)] + [InlineData("5.012e+20", true)] + [InlineData("-5.012e-20", false)] + [InlineData("-5.012e-20", true)] + [InlineData("-5.012e20", false)] + [InlineData("-5.012e20", true)] + [InlineData("-5.012e+20", false)] + [InlineData("-5.012e+20", true)] + public static void WriteNumberDecimalScientific(string value, bool indented) { - WriteSimpleValue(indented, "1e6"); + WriteSimpleValue(indented, value); } [Theory] diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index 8b8500894ecd..1cc9e0e12bbb 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -3747,6 +3747,7 @@ public void WriteNumbers(bool formatted, bool skipValidation, string keyString) doubles[2] = double.MinValue; doubles[3] = 12.345e1; doubles[4] = -123.45e1; + for (int i = 5; i < numberOfItems; i++) { var value = random.NextDouble();