diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs index b169310c64c0c6..8a194858acbb75 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs @@ -3418,6 +3418,11 @@ private int ReadData() { _ps.bytesUsed = 0; } + else if (bytesLeft < 0) + { + // This can happen when encoding switch causes bytePos to be calculated incorrectly for malformed data + Throw(SR.Xml_InvalidCharInThisEncoding); + } else { Debug.Assert(_ps.bytes != null); diff --git a/src/libraries/System.Private.Xml/tests/XmlReader/Tests/ReaderEncodingTests.cs b/src/libraries/System.Private.Xml/tests/XmlReader/Tests/ReaderEncodingTests.cs index d5beb6db2532c4..d0b8657d5fff79 100644 --- a/src/libraries/System.Private.Xml/tests/XmlReader/Tests/ReaderEncodingTests.cs +++ b/src/libraries/System.Private.Xml/tests/XmlReader/Tests/ReaderEncodingTests.cs @@ -122,5 +122,19 @@ public static void ReadWithIncompleteBytes() XmlException ex = Assert.Throws(() => reader.Read()); Assert.Contains(_invalidCharMessageStart, ex.Message); } + + [Fact] + public static void ReadWithMalformedUtf8InXmlDeclaration() + { + // This test verifies the fix for issue dotnet/runtime#113061 where malformed UTF-8 sequences + // in XML declaration caused ArgumentOutOfRangeException instead of XmlException + string data = ""; + byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data); + var reader = XmlReader.Create(new MemoryStream(bytes)); + + // Should throw XmlException, not ArgumentOutOfRangeException + XmlException ex = Assert.Throws(() => reader.Read()); + Assert.Contains(_invalidCharInThisEncoding, ex.Message); + } } }