From: Stephen Toub Date: Fri, 20 Sep 2019 20:29:39 +0000 (-0400) Subject: Enable better trimming of derived XmlReader/Writer-derived types (dotnet/corefx#41235) X-Git-Tag: submit/tizen/20210909.063632~11031^2~426 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=238d39b139b938c5b74343b7c452bb4b25db34bb;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Enable better trimming of derived XmlReader/Writer-derived types (dotnet/corefx#41235) Commit migrated from https://github.com/dotnet/corefx/commit/b893e604ce832ccf4e9cbcbdfe0b0ae2b23195bf --- diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs index e02d5b9..5f62b31 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReader.cs @@ -2,14 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.IO; -using System.Text; -using System.Security; -using System.Diagnostics; using System.Collections; +using System.Diagnostics; using System.Globalization; -using System.Xml.Schema; +using System.IO; using System.Runtime.Versioning; +using System.Security; +using System.Text; +using System.Threading; +using System.Xml.Schema; namespace System.Xml { @@ -1752,7 +1753,18 @@ namespace System.Xml // Creates an XmlReader for parsing XML from the given Uri. public static XmlReader Create(string inputUri) { - return XmlReader.Create(inputUri, (XmlReaderSettings)null, (XmlParserContext)null); + if (inputUri == null) + { + throw new ArgumentNullException(nameof(inputUri)); + } + if (inputUri.Length == 0) + { + throw new ArgumentException(SR.XmlConvert_BadUri, nameof(inputUri)); + } + + // Avoid using XmlReader.Create(string, XmlReaderSettings), as it references a lot of types + // that then can't be trimmed away. + return new XmlTextReaderImpl(inputUri, XmlReaderSettings.s_defaultReaderSettings, null, new XmlUrlResolver()); } // Creates an XmlReader according to the settings for parsing XML from the given Uri. @@ -1764,17 +1776,21 @@ namespace System.Xml // Creates an XmlReader according to the settings and parser context for parsing XML from the given Uri. public static XmlReader Create(string inputUri, XmlReaderSettings settings, XmlParserContext inputContext) { - if (settings == null) - { - settings = new XmlReaderSettings(); - } + settings ??= XmlReaderSettings.s_defaultReaderSettings; return settings.CreateReader(inputUri, inputContext); } // Creates an XmlReader according for parsing XML from the given stream. public static XmlReader Create(Stream input) { - return Create(input, (XmlReaderSettings)null, (string)string.Empty); + if (input == null) + { + throw new ArgumentNullException(nameof(input)); + } + + // Avoid using XmlReader.Create(Stream, XmlReaderSettings), as it references a lot of types + // that then can't be trimmed away. + return new XmlTextReaderImpl(input, null, 0, XmlReaderSettings.s_defaultReaderSettings, null, string.Empty, null, false); } // Creates an XmlReader according to the settings for parsing XML from the given stream. @@ -1786,27 +1802,28 @@ namespace System.Xml // Creates an XmlReader according to the settings and base Uri for parsing XML from the given stream. public static XmlReader Create(Stream input, XmlReaderSettings settings, string baseUri) { - if (settings == null) - { - settings = new XmlReaderSettings(); - } + settings ??= XmlReaderSettings.s_defaultReaderSettings; return settings.CreateReader(input, null, (string)baseUri, null); } // Creates an XmlReader according to the settings and parser context for parsing XML from the given stream. public static XmlReader Create(Stream input, XmlReaderSettings settings, XmlParserContext inputContext) { - if (settings == null) - { - settings = new XmlReaderSettings(); - } + settings ??= XmlReaderSettings.s_defaultReaderSettings; return settings.CreateReader(input, null, (string)string.Empty, inputContext); } // Creates an XmlReader according for parsing XML from the given TextReader. public static XmlReader Create(TextReader input) { - return Create(input, (XmlReaderSettings)null, (string)string.Empty); + if (input == null) + { + throw new ArgumentNullException(nameof(input)); + } + + // Avoid using XmlReader.Create(TextReader, XmlReaderSettings), as it references a lot of types + // that then can't be trimmed away. + return new XmlTextReaderImpl(input, XmlReaderSettings.s_defaultReaderSettings, string.Empty, null); } // Creates an XmlReader according to the settings for parsing XML from the given TextReader. @@ -1818,30 +1835,21 @@ namespace System.Xml // Creates an XmlReader according to the settings and baseUri for parsing XML from the given TextReader. public static XmlReader Create(TextReader input, XmlReaderSettings settings, string baseUri) { - if (settings == null) - { - settings = new XmlReaderSettings(); - } + settings ??= XmlReaderSettings.s_defaultReaderSettings; return settings.CreateReader(input, baseUri, null); } // Creates an XmlReader according to the settings and parser context for parsing XML from the given TextReader. public static XmlReader Create(TextReader input, XmlReaderSettings settings, XmlParserContext inputContext) { - if (settings == null) - { - settings = new XmlReaderSettings(); - } + settings ??= XmlReaderSettings.s_defaultReaderSettings; return settings.CreateReader(input, string.Empty, inputContext); } // Creates an XmlReader according to the settings wrapped over the given reader. public static XmlReader Create(XmlReader reader, XmlReaderSettings settings) { - if (settings == null) - { - settings = new XmlReaderSettings(); - } + settings ??= XmlReaderSettings.s_defaultReaderSettings; return settings.CreateReader(reader); } @@ -1854,10 +1862,7 @@ namespace System.Xml { throw new ArgumentNullException(nameof(input)); } - if (settings == null) - { - settings = new XmlReaderSettings(); - } + settings ??= XmlReaderSettings.s_defaultReaderSettings; XmlReader reader; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs index 4d9c43e..e74adf0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs @@ -13,6 +13,8 @@ namespace System.Xml // XmlReaderSettings class specifies basic features of an XmlReader. public sealed class XmlReaderSettings { + internal static readonly XmlReaderSettings s_defaultReaderSettings = new XmlReaderSettings() { ReadOnly = true }; + // // Fields // @@ -424,11 +426,7 @@ namespace System.Xml } // resolve and open the url - XmlResolver tmpResolver = this.GetXmlResolver(); - if (tmpResolver == null) - { - tmpResolver = CreateDefaultResolver(); - } + XmlResolver tmpResolver = this.GetXmlResolver() ?? new XmlUrlResolver(); // create text XML reader XmlReader reader = new XmlTextReaderImpl(inputUri, this, inputContext, tmpResolver); @@ -579,11 +577,6 @@ namespace System.Xml IsXmlResolverSet = false; } - private static XmlResolver CreateDefaultResolver() - { - return new XmlUrlResolver(); - } - internal XmlReader AddValidation(XmlReader reader) { XmlResolver resolver = null; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs index 04897e5..1327eb9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs @@ -659,68 +659,100 @@ namespace System.Xml // Creates an XmlWriter for writing into the provided file. public static XmlWriter Create(string outputFileName) { - return Create(outputFileName, null); + if (outputFileName == null) + { + throw new ArgumentNullException(nameof(outputFileName)); + } + + // Avoid using XmlWriter.Create(string, XmlReaderSettings), as it references a lot of types + // that then can't be trimmed away. + var fs = new FileStream(outputFileName, FileMode.Create, FileAccess.Write, FileShare.Read); + try + { + var settings = new XmlWriterSettings() { CloseOutput = true }; + XmlWriter writer = new XmlEncodedRawTextWriter(fs, settings); + return new XmlWellFormedWriter(writer, settings); + } + catch + { + fs.Dispose(); + throw; + } } // Creates an XmlWriter for writing into the provided file with the specified settings. public static XmlWriter Create(string outputFileName, XmlWriterSettings settings) { - if (settings == null) - { - settings = new XmlWriterSettings(); - } + settings ??= XmlWriterSettings.s_defaultWriterSettings; return settings.CreateWriter(outputFileName); } // Creates an XmlWriter for writing into the provided stream. public static XmlWriter Create(Stream output) { - return Create(output, null); + if (output == null) + { + throw new ArgumentNullException(nameof(output)); + } + + // Avoid using XmlWriter.Create(Stream, XmlReaderSettings), as it references a lot of types + // that then can't be trimmed away. + XmlWriterSettings settings = XmlWriterSettings.s_defaultWriterSettings; + XmlWriter writer = new XmlUtf8RawTextWriter(output, settings); + return new XmlWellFormedWriter(writer, settings); } // Creates an XmlWriter for writing into the provided stream with the specified settings. public static XmlWriter Create(Stream output, XmlWriterSettings settings) { - if (settings == null) - { - settings = new XmlWriterSettings(); - } + settings ??= XmlWriterSettings.s_defaultWriterSettings; return settings.CreateWriter(output); } // Creates an XmlWriter for writing into the provided TextWriter. public static XmlWriter Create(TextWriter output) { - return Create(output, null); + if (output == null) + { + throw new ArgumentNullException(nameof(output)); + } + + // Avoid using XmlWriter.Create(TextWriter, XmlReaderSettings), as it references a lot of types + // that then can't be trimmed away. + XmlWriterSettings settings = XmlWriterSettings.s_defaultWriterSettings; + XmlWriter writer = new XmlEncodedRawTextWriter(output, settings); + return new XmlWellFormedWriter(writer, settings); } // Creates an XmlWriter for writing into the provided TextWriter with the specified settings. public static XmlWriter Create(TextWriter output, XmlWriterSettings settings) { - if (settings == null) - { - settings = new XmlWriterSettings(); - } + settings ??= XmlWriterSettings.s_defaultWriterSettings; return settings.CreateWriter(output); } // Creates an XmlWriter for writing into the provided StringBuilder. public static XmlWriter Create(StringBuilder output) { - return Create(output, null); + if (output == null) + { + throw new ArgumentNullException(nameof(output)); + } + + // Avoid using XmlWriter.Create(StringBuilder, XmlReaderSettings), as it references a lot of types + // that then can't be trimmed away. + return Create(new StringWriter(output, CultureInfo.InvariantCulture)); } // Creates an XmlWriter for writing into the provided StringBuilder with the specified settings. public static XmlWriter Create(StringBuilder output, XmlWriterSettings settings) { - if (settings == null) - { - settings = new XmlWriterSettings(); - } if (output == null) { throw new ArgumentNullException(nameof(output)); } + + settings ??= XmlWriterSettings.s_defaultWriterSettings; return settings.CreateWriter(new StringWriter(output, CultureInfo.InvariantCulture)); } @@ -733,10 +765,7 @@ namespace System.Xml // Creates an XmlWriter wrapped around the provided XmlWriter with the specified settings. public static XmlWriter Create(XmlWriter output, XmlWriterSettings settings) { - if (settings == null) - { - settings = new XmlWriterSettings(); - } + settings ??= XmlWriterSettings.s_defaultWriterSettings; return settings.CreateWriter(output); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterSettings.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterSettings.cs index 1cab648..db261c3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterSettings.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriterSettings.cs @@ -43,6 +43,8 @@ namespace System.Xml // XmlWriterSettings class specifies basic features of an XmlWriter. public sealed class XmlWriterSettings { + internal static readonly XmlWriterSettings s_defaultWriterSettings = new XmlWriterSettings() { ReadOnly = true }; + // // Fields // diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs index 1df93e6..f1ea427 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs @@ -45,9 +45,6 @@ namespace System.Xml.Xsl public sealed class XslCompiledTransform { - // Reader settings used when creating XmlReader from inputUri - private static readonly XmlReaderSettings s_readerSettings = new XmlReaderSettings(); - #if FEATURE_COMPILED_XSL // Version for GeneratedCodeAttribute private static readonly Version s_version = typeof(XslCompiledTransform).Assembly.GetName().Version; @@ -362,7 +359,7 @@ namespace System.Xml.Xsl public void Transform(string inputUri, XmlWriter results) { CheckArguments(inputUri, results); - using (XmlReader reader = XmlReader.Create(inputUri, s_readerSettings)) + using (XmlReader reader = XmlReader.Create(inputUri)) { Transform(reader, (XsltArgumentList)null, results, CreateDefaultResolver()); } @@ -372,7 +369,7 @@ namespace System.Xml.Xsl public void Transform(string inputUri, XsltArgumentList arguments, XmlWriter results) { CheckArguments(inputUri, results); - using (XmlReader reader = XmlReader.Create(inputUri, s_readerSettings)) + using (XmlReader reader = XmlReader.Create(inputUri)) { Transform(reader, arguments, results, CreateDefaultResolver()); } @@ -382,7 +379,7 @@ namespace System.Xml.Xsl public void Transform(string inputUri, XsltArgumentList arguments, TextWriter results) { CheckArguments(inputUri, results); - using (XmlReader reader = XmlReader.Create(inputUri, s_readerSettings)) + using (XmlReader reader = XmlReader.Create(inputUri)) using (XmlWriter writer = XmlWriter.Create(results, OutputSettings)) { Transform(reader, arguments, writer, CreateDefaultResolver()); @@ -394,7 +391,7 @@ namespace System.Xml.Xsl public void Transform(string inputUri, XsltArgumentList arguments, Stream results) { CheckArguments(inputUri, results); - using (XmlReader reader = XmlReader.Create(inputUri, s_readerSettings)) + using (XmlReader reader = XmlReader.Create(inputUri)) using (XmlWriter writer = XmlWriter.Create(results, OutputSettings)) { Transform(reader, arguments, writer, CreateDefaultResolver()); @@ -412,7 +409,7 @@ namespace System.Xml.Xsl throw new ArgumentNullException(nameof(resultsFile)); // SQLBUDT 276415: Prevent wiping out the content of the input file if the output file is the same - using (XmlReader reader = XmlReader.Create(inputUri, s_readerSettings)) + using (XmlReader reader = XmlReader.Create(inputUri)) using (XmlWriter writer = XmlWriter.Create(resultsFile, OutputSettings)) { Transform(reader, (XsltArgumentList)null, writer, CreateDefaultResolver());