diff options
author | Joshua Clark <clarkis117@live.com> | 2018-03-21 06:02:07 +0300 |
---|---|---|
committer | Krzysztof Wicher <mordotymoja@gmail.com> | 2018-03-21 06:02:07 +0300 |
commit | 97ccece028cfddef84355da591ceb753042b1a54 (patch) | |
tree | 45295f73296ecad73d0e2eadc5643f82d7066440 /src/System.Private.Xml | |
parent | 25c570b2937498bc988276f9a4dc9061893de19a (diff) |
Fix UTF32Encoding BOM being emitted by XmlWriter when ByteOrderMark set to false (#28194)
* initial fix and initial test
* add comments
Diffstat (limited to 'src/System.Private.Xml')
-rw-r--r-- | src/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs | 6 | ||||
-rw-r--r-- | src/System.Private.Xml/tests/XmlWriter/WriteWithEncoding.cs | 40 |
2 files changed, 45 insertions, 1 deletions
diff --git a/src/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs b/src/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs index a1e6c3e1d2..3c8f752f65 100644 --- a/src/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs +++ b/src/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs @@ -171,6 +171,11 @@ namespace System.Xml _textContentMarks[0] = 1; _charEntityFallback = new CharEntityEncoderFallback(); + + // grab bom before possibly changing encoding settings + ReadOnlySpan<byte> bom = encoding.Preamble; + + // the encoding instance this creates can differ from the one passed in this.encoding = Encoding.GetEncoding( settings.Encoding.CodePage, _charEntityFallback, @@ -180,7 +185,6 @@ namespace System.Xml if (!stream.CanSeek || stream.Position == 0) { - ReadOnlySpan<byte> bom = encoding.Preamble; if (bom.Length != 0) { this.stream.Write(bom); diff --git a/src/System.Private.Xml/tests/XmlWriter/WriteWithEncoding.cs b/src/System.Private.Xml/tests/XmlWriter/WriteWithEncoding.cs index 78c191a4d8..29bfd9bc56 100644 --- a/src/System.Private.Xml/tests/XmlWriter/WriteWithEncoding.cs +++ b/src/System.Private.Xml/tests/XmlWriter/WriteWithEncoding.cs @@ -3,7 +3,9 @@ // See the LICENSE file in the project root for more information. using System.IO; +using System.Linq; using System.Text; +using System.Xml.Xsl; using Xunit; namespace System.Xml.Tests @@ -36,5 +38,43 @@ namespace System.Xml.Tests Assert.Equal("<orderID>1-456-ab١</orderID><orderID>2-36-00a𐀀𐐁</orderID>", s); } + + [Fact] + public void WriteWithUtf32EncodingNoBom() + { + // Given + var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<breakfast_menu>\n <food>\n <name>Belgian Waffles</name>\n <price>$5.95</price>\n <description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>\n <calories>650</calories>\n </food>\n <food>\n <name>Strawberry Belgian Waffles</name>\n <price>$7.95</price>\n <description>Light Belgian waffles covered with strawberries and whipped cream</description>\n <calories>900</calories>\n </food>\n</breakfast_menu>"; + var xsl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<html xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xsl:version=\"1.0\">\n <body style=\"font-family:Arial;font-size:12pt;background-color:#EEEEEE\">\n <xsl:for-each select=\"breakfast_menu/food\">\n <div style=\"background-color:teal;color:white;padding:4px\">\n <span style=\"font-weight:bold\">\n <xsl:value-of select=\"name\" />\n -\n </span>\n <xsl:value-of select=\"price\" />\n </div>\n <div style=\"margin-left:20px;margin-bottom:1em;font-size:10pt\">\n <p>\n <xsl:value-of select=\"description\" />\n <span style=\"font-style:italic\">\n (\n <xsl:value-of select=\"calories\" />\n calories per serving)\n </span>\n </p>\n </div>\n </xsl:for-each>\n </body>\n</html>"; + + // set encoding to UTF32 with no BOM + var settings = new XmlWriterSettings + { + Encoding = new UTF32Encoding(false, false, true) + }; + + string resultString; + using (TextReader xslReader = new StringReader(xsl), + xmlReader = new StringReader(xml)) + { + using (var result = new MemoryStream()) + { + var xslXmlReader = XmlReader.Create(xslReader); + var xmlXmlReader = XmlReader.Create(xmlReader); + + // BOM can be written in this call + var resultXmlTextWriter = XmlWriter.Create(result, settings); + + // When, do work and get result + var xslTransform = new XslCompiledTransform(); + xslTransform.Load(xslXmlReader); + xslTransform.Transform(xmlXmlReader, resultXmlTextWriter); + result.Position = 0; + resultString = settings.Encoding.GetString(result.ToArray()); + } + } + + // Then + Assert.Equal("<?xml version=\"1.0\" encoding=\"utf-32\"?>", string.Concat(resultString.Take(39))); + } } } |