diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs index c2aa7970b546f..d593a97e7d56e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs @@ -760,7 +760,7 @@ public override void WriteComment(string? text) { try { - if (null != text && (text.Contains("--") || text.StartsWith('-'))) + if (null != text && (text.Contains("--") || text.EndsWith('-'))) { throw new ArgumentException(SR.Xml_InvalidCommentChars); } diff --git a/src/libraries/System.Private.Xml/tests/XmlWriter/System.Xml.RW.XmlWriter.Tests.csproj b/src/libraries/System.Private.Xml/tests/XmlWriter/System.Xml.RW.XmlWriter.Tests.csproj index c3e76cb1a3047..3e074e9a835e3 100644 --- a/src/libraries/System.Private.Xml/tests/XmlWriter/System.Xml.RW.XmlWriter.Tests.csproj +++ b/src/libraries/System.Private.Xml/tests/XmlWriter/System.Xml.RW.XmlWriter.Tests.csproj @@ -7,5 +7,6 @@ + \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/XmlWriter/XmlTextWriterTests.cs b/src/libraries/System.Private.Xml/tests/XmlWriter/XmlTextWriterTests.cs new file mode 100644 index 0000000000000..5b1063a1fc606 --- /dev/null +++ b/src/libraries/System.Private.Xml/tests/XmlWriter/XmlTextWriterTests.cs @@ -0,0 +1,92 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using Xunit; + +namespace System.Xml.Tests +{ + public class XmlTextWriterTests + { + public static IEnumerable PositiveTestCases + { + get + { + yield return new string[] { null }; // will be normalized to empty string + yield return new string[] { "" }; + yield return new string[] { "This is some data." }; + yield return new string[] { " << brackets and whitespace >> " }; // brackets & surrounding whitespace are ok + yield return new string[] { "&" }; // entities are ok (treated opaquely) + yield return new string[] { "Hello\r\nthere." }; // newlines are ok + yield return new string[] { "\U0001F643 Upside-down smiley \U0001F643" }; // correctly paired surrogates are ok + yield return new string[] { "\uFFFD\uFFFE\uFFFF" }; // replacement char & private use are ok + } + } + + public static IEnumerable BadSurrogateTestCases + { + get + { + yield return new string[] { "\uD800 Unpaired high surrogate." }; + yield return new string[] { "\uDFFF Unpaired low surrogate." }; + yield return new string[] { "Unpaired high surrogate at end. \uD800" }; + yield return new string[] { "Unpaired low surrogate at end. \uDFFF" }; + yield return new string[] { "Unpaired surrogates \uDFFF\uD800 in middle." }; + } + } + + [Theory] + [MemberData(nameof(PositiveTestCases))] + [InlineData("]]")] // ]] without trailing > is ok + [InlineData("-->")] // end of comment marker ok (meaningless to cdata tag) + public void WriteCData_SuccessCases(string cdataText) + { + StringWriter sw = new StringWriter(); + XmlTextWriter xw = new XmlTextWriter(sw); + + xw.WriteCData(cdataText); + + Assert.Equal($"", sw.ToString()); + } + + [Theory] + [MemberData(nameof(BadSurrogateTestCases), DisableDiscoveryEnumeration = true)] // disable enumeration to avoid test harness misinterpreting unpaired surrogates + [InlineData("]]>")] // end of cdata marker forbidden (ambiguous close tag) + public void WriteCData_FailureCases(string cdataText) + { + StringWriter sw = new StringWriter(); + XmlTextWriter xw = new XmlTextWriter(sw); + + Assert.Throws(() => xw.WriteCData(cdataText)); + } + + [Theory] + [MemberData(nameof(PositiveTestCases))] + [InlineData("-12345")] // hyphen at beginning is ok + [InlineData("123- -45")] // single hyphens are ok in middle + [InlineData("]]>")] // end of cdata marker ok (meaningless to comment tag) + public void WriteComment_SuccessCases(string commentText) + { + StringWriter sw = new StringWriter(); + XmlTextWriter xw = new XmlTextWriter(sw); + + xw.WriteComment(commentText); + + Assert.Equal($"", sw.ToString()); + } + + [Theory] + [MemberData(nameof(BadSurrogateTestCases), DisableDiscoveryEnumeration = true)] // disable enumeration to avoid test harness misinterpreting unpaired surrogates + [InlineData("123--45")] // double-hyphen in middle is forbidden (ambiguous comment close tag) + [InlineData("12345-")] // hyphen at end is forbidden (ambiguous comment close tag) + [InlineData("-->")] // end of comment marker forbidden (ambiguous close tag) + public void WriteComment_FailureCases(string commentText) + { + StringWriter sw = new StringWriter(); + XmlTextWriter xw = new XmlTextWriter(sw); + + Assert.Throws(() => xw.WriteComment(commentText)); + } + } +}