diff --git a/src/libraries/Common/src/System/LocalAppContextSwitches.Common.cs b/src/libraries/Common/src/System/LocalAppContextSwitches.Common.cs index 555751c6947a4..19806ceee1c79 100644 --- a/src/libraries/Common/src/System/LocalAppContextSwitches.Common.cs +++ b/src/libraries/Common/src/System/LocalAppContextSwitches.Common.cs @@ -55,6 +55,11 @@ private static bool GetSwitchDefaultValue(string switchName) return true; } + if (switchName == "System.Xml.XmlResolver.IsNetworkingEnabledByDefault") + { + return true; + } + return false; } } diff --git a/src/libraries/System.Private.Xml/src/ILLink/ILLink.Substitutions.xml b/src/libraries/System.Private.Xml/src/ILLink/ILLink.Substitutions.xml new file mode 100644 index 0000000000000..52cf62fc63618 --- /dev/null +++ b/src/libraries/System.Private.Xml/src/ILLink/ILLink.Substitutions.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj b/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj index 2bbb69bb379cd..b05a319099867 100644 --- a/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj +++ b/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj @@ -6,6 +6,10 @@ false + + + + @@ -119,7 +123,6 @@ - @@ -130,10 +133,10 @@ + - @@ -759,10 +762,7 @@ - + diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs index 8bc1f54dc8b50..a95f9105051da 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs @@ -2,10 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; +using SwitchesHelpers = System.LocalAppContextSwitches; -namespace System +namespace System.Xml { - internal static partial class LocalAppContextSwitches + internal static class LocalAppContextSwitches { private static int s_dontThrowOnInvalidSurrogatePairs; public static bool DontThrowOnInvalidSurrogatePairs @@ -13,7 +14,7 @@ public static bool DontThrowOnInvalidSurrogatePairs [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return GetCachedSwitchValue("Switch.System.Xml.DontThrowOnInvalidSurrogatePairs", ref s_dontThrowOnInvalidSurrogatePairs); + return SwitchesHelpers.GetCachedSwitchValue("Switch.System.Xml.DontThrowOnInvalidSurrogatePairs", ref s_dontThrowOnInvalidSurrogatePairs); } } @@ -23,7 +24,7 @@ public static bool IgnoreEmptyKeySequences [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return GetCachedSwitchValue("Switch.System.Xml.IgnoreEmptyKeySequencess", ref s_ignoreEmptyKeySequences); + return SwitchesHelpers.GetCachedSwitchValue("Switch.System.Xml.IgnoreEmptyKeySequences", ref s_ignoreEmptyKeySequences); } } @@ -33,7 +34,7 @@ public static bool IgnoreKindInUtcTimeSerialization [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return GetCachedSwitchValue("Switch.System.Xml.IgnoreKindInUtcTimeSerialization", ref s_ignoreKindInUtcTimeSerialization); + return SwitchesHelpers.GetCachedSwitchValue("Switch.System.Xml.IgnoreKindInUtcTimeSerialization", ref s_ignoreKindInUtcTimeSerialization); } } @@ -43,7 +44,7 @@ public static bool LimitXPathComplexity [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return GetCachedSwitchValue("Switch.System.Xml.LimitXPathComplexity", ref s_limitXPathComplexity); + return SwitchesHelpers.GetCachedSwitchValue("Switch.System.Xml.LimitXPathComplexity", ref s_limitXPathComplexity); } } @@ -53,7 +54,17 @@ public static bool AllowDefaultResolver [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return GetCachedSwitchValue("Switch.System.Xml.AllowDefaultResolver", ref s_allowDefaultResolver); + return SwitchesHelpers.GetCachedSwitchValue("Switch.System.Xml.AllowDefaultResolver", ref s_allowDefaultResolver); + } + } + + private static int s_isNetworkingEnabledByDefault; + public static bool IsNetworkingEnabledByDefault + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return SwitchesHelpers.GetCachedSwitchValue("System.Xml.XmlResolver.IsNetworkingEnabledByDefault", ref s_isNetworkingEnabledByDefault); } } } 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 e0f76fe5fad1c..80a1c18372ab7 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 @@ -1612,7 +1612,7 @@ public static XmlReader Create(string 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()); + return new XmlTextReaderImpl(inputUri, XmlReaderSettings.s_defaultReaderSettings, null, XmlReaderSettings.GetDefaultPermissiveResolver()); } // Creates an XmlReader according to the settings for parsing XML from the given Uri. 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 68adf4d128807..f4d873161c1f2 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 @@ -321,7 +321,7 @@ internal XmlReader CreateReader(string inputUri, XmlParserContext? inputContext) ArgumentException.ThrowIfNullOrEmpty(inputUri); // resolve and open the url - XmlResolver tmpResolver = GetXmlResolver() ?? new XmlUrlResolver(); + XmlResolver tmpResolver = GetXmlResolver() ?? GetDefaultPermissiveResolver(); // create text XML reader XmlReader reader = new XmlTextReaderImpl(inputUri, this, inputContext, tmpResolver); @@ -436,7 +436,7 @@ internal XmlReader AddValidation(XmlReader reader) if (resolver == null && !IsXmlResolverSet) { - resolver = new XmlUrlResolver(); + resolver = GetDefaultPermissiveResolver(); } } @@ -623,6 +623,11 @@ private XmlReader AddConformanceWrapper(XmlReader baseReader) return baseReader; } + internal static XmlResolver GetDefaultPermissiveResolver() + { + return LocalAppContextSwitches.IsNetworkingEnabledByDefault ? new XmlUrlResolver() : XmlResolver.FileSystemResolver; + } + [DoesNotReturn] [StackTraceHidden] private static void ThrowArgumentOutOfRangeException(string paramName) 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 4de62beab8966..1c118faafb865 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 @@ -2532,7 +2532,7 @@ private bool IsResolverNull private XmlResolver GetTempResolver() { - return _xmlResolver ?? new XmlUrlResolver(); + return _xmlResolver ?? XmlReaderSettings.GetDefaultPermissiveResolver(); } internal bool DtdParserProxy_PushEntity(IDtdEntityInfo entity, out int entityId) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImpl.cs index bb6d8f8337c9f..f2c8caf707a1c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlValidatingReaderImpl.cs @@ -1082,7 +1082,7 @@ private void SetupValidation(ValidationType valType) if (tempResolver == null && !_coreReaderImpl.IsResolverSet) { // it is safe to return valid resolver as it'll be used in the schema validation - return s_tempResolver ??= new XmlUrlResolver(); + return s_tempResolver ??= XmlReaderSettings.GetDefaultPermissiveResolver(); } return tempResolver; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs index 0012e4a3c0312..f8292c5e70a12 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs @@ -106,7 +106,7 @@ public XmlSchemaSet(XmlNameTable nameTable) if (_readerSettings.GetXmlResolver() == null) { // The created resolver will be used in the schema validation only - _readerSettings.XmlResolver = new XmlUrlResolver(); + _readerSettings.XmlResolver = XmlReaderSettings.GetDefaultPermissiveResolver(); _readerSettings.IsXmlResolverSet = false; } @@ -232,7 +232,7 @@ internal Hashtable SchemaLocations lock (InternalSyncObject) { //Check if schema from url has already been added - XmlResolver tempResolver = _readerSettings.GetXmlResolver() ?? new XmlUrlResolver(); + XmlResolver tempResolver = _readerSettings.GetXmlResolver() ?? XmlReaderSettings.GetDefaultPermissiveResolver(); Uri tempSchemaUri = tempResolver.ResolveUri(null, schemaUri); if (IsSchemaLoaded(tempSchemaUri, targetNamespace, out schema)) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlDownloadManager.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlDownloadManager.cs index 83ebba25199ec..304a346bdaf6f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlDownloadManager.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XmlDownloadManager.cs @@ -1,13 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.IO; using System.Net; +using System.Net.Http; +using System.Threading.Tasks; namespace System.Xml { - internal sealed partial class XmlDownloadManager + internal static class XmlDownloadManager { internal static Stream GetStream(Uri uri, ICredentials? credentials, IWebProxy? proxy) { @@ -22,5 +23,44 @@ internal static Stream GetStream(Uri uri, ICredentials? credentials, IWebProxy? return GetNonFileStreamAsync(uri, credentials, proxy).GetAwaiter().GetResult(); } } + + internal static Task GetStreamAsync(Uri uri, ICredentials? credentials, IWebProxy? proxy) + { + if (uri.Scheme == "file") + { + Uri fileUri = uri; + return Task.FromResult(new FileStream(fileUri.LocalPath, FileMode.Open, FileAccess.Read, FileShare.Read, 1, useAsync: true)); + } + else + { + return GetNonFileStreamAsync(uri, credentials, proxy); + } + } + + private static async Task GetNonFileStreamAsync(Uri uri, ICredentials? credentials, IWebProxy? proxy) + { + var handler = new HttpClientHandler(); + using (var client = new HttpClient(handler)) + { +#pragma warning disable CA1416 // Validate platform compatibility, 'credentials' and 'proxy' will not be set for browser, so safe to suppress + if (credentials != null) + { + handler.Credentials = credentials; + } + if (proxy != null) + { + handler.Proxy = proxy; + } +#pragma warning restore CA1416 + + using (Stream respStream = await client.GetStreamAsync(uri).ConfigureAwait(false)) + { + var result = new MemoryStream(); + respStream.CopyTo(result); + result.Position = 0; + return result; + } + } + } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlDownloadManagerAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlDownloadManagerAsync.cs deleted file mode 100644 index c2d774d0f4006..0000000000000 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlDownloadManagerAsync.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; - -namespace System.Xml -{ - internal sealed partial class XmlDownloadManager - { - internal static Task GetStreamAsync(Uri uri, ICredentials? credentials, IWebProxy? proxy) - { - if (uri.Scheme == "file") - { - Uri fileUri = uri; - return Task.Run(() => new FileStream(fileUri.LocalPath, FileMode.Open, FileAccess.Read, FileShare.Read, 1, useAsync: true)); - } - else - { - return GetNonFileStreamAsync(uri, credentials, proxy); - } - } - - private static async Task GetNonFileStreamAsync(Uri uri, ICredentials? credentials, IWebProxy? proxy) - { - var handler = new HttpClientHandler(); - using (var client = new HttpClient(handler)) - { -#pragma warning disable CA1416 // Validate platform compatibility, 'credentials' and 'proxy' will not be set for browser, so safe to suppress - if (credentials != null) - { - handler.Credentials = credentials; - } - if (proxy != null) - { - handler.Proxy = proxy; - } -#pragma warning restore CA1416 - - using (Stream respStream = await client.GetStreamAsync(uri).ConfigureAwait(false)) - { - var result = new MemoryStream(); - respStream.CopyTo(result); - result.Position = 0; - return result; - } - } - } - } -} diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlResolver.FileSystemResolver.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlResolver.FileSystemResolver.cs new file mode 100644 index 0000000000000..8785d09e9c12c --- /dev/null +++ b/src/libraries/System.Private.Xml/src/System/Xml/XmlResolver.FileSystemResolver.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using System.Threading.Tasks; + +namespace System.Xml +{ + public abstract partial class XmlResolver + { + /// + /// Gets an XML resolver which resolves only file system URIs. + /// + /// An XML resolver which resolves only file system URIs. + /// + /// Calling or on the + /// instance returned by this property will resolve only URIs which scheme is file. + /// + public static XmlResolver FileSystemResolver => XmlFileSystemResolver.s_singleton; + + // An XML resolver that resolves only file system URIs. + private sealed class XmlFileSystemResolver : XmlResolver + { + internal static readonly XmlFileSystemResolver s_singleton = new(); + + // Private constructor ensures existing only one instance of XmlFileSystemResolver + private XmlFileSystemResolver() { } + + public override object? GetEntity(Uri absoluteUri, string? role, Type? ofObjectToReturn) + { + if ((ofObjectToReturn is null || ofObjectToReturn == typeof(Stream) || ofObjectToReturn == typeof(object)) + && absoluteUri.Scheme == "file") + { + return new FileStream(absoluteUri.LocalPath, FileMode.Open, FileAccess.Read, FileShare.Read, 1); + } + + throw new XmlException(SR.Xml_UnsupportedClass, string.Empty); + } + + public override Task GetEntityAsync(Uri absoluteUri, string? role, Type? ofObjectToReturn) + { + if (ofObjectToReturn == null || ofObjectToReturn == typeof(Stream) || ofObjectToReturn == typeof(object)) + { + if (absoluteUri.Scheme == "file") + { + return Task.FromResult(new FileStream(absoluteUri.LocalPath, FileMode.Open, FileAccess.Read, FileShare.Read, 1, useAsync: true)); + } + } + + throw new XmlException(SR.Xml_UnsupportedClass, string.Empty); + } + } + } +} diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlUrlResolver.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlUrlResolver.cs index 558ad2e4b0218..d915266db483b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlUrlResolver.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XmlUrlResolver.cs @@ -5,21 +5,17 @@ using System.Net; using System.Net.Cache; using System.Runtime.Versioning; +using System.Threading.Tasks; +using System.IO; namespace System.Xml { // Resolves external XML resources named by a Uniform Resource Identifier (URI). public partial class XmlUrlResolver : XmlResolver { - private static XmlDownloadManager? s_downloadManager; private ICredentials? _credentials; private IWebProxy? _proxy; - private static XmlDownloadManager DownloadManager => - s_downloadManager ?? - Interlocked.CompareExchange(ref s_downloadManager, new XmlDownloadManager(), null) ?? - s_downloadManager; - public XmlUrlResolver() { } [UnsupportedOSPlatform("browser")] @@ -42,7 +38,7 @@ public RequestCachePolicy CachePolicy // Maps a URI to an Object containing the actual resource. public override object? GetEntity(Uri absoluteUri, string? role, Type? ofObjectToReturn) { - if (ofObjectToReturn is null || ofObjectToReturn == typeof(System.IO.Stream) || ofObjectToReturn == typeof(object)) + if (ofObjectToReturn is null || ofObjectToReturn == typeof(Stream) || ofObjectToReturn == typeof(object)) { return XmlDownloadManager.GetStream(absoluteUri, _credentials, _proxy); } @@ -50,6 +46,17 @@ public RequestCachePolicy CachePolicy throw new XmlException(SR.Xml_UnsupportedClass, string.Empty); } + // Maps a URI to an Object containing the actual resource. + public override async Task GetEntityAsync(Uri absoluteUri, string? role, Type? ofObjectToReturn) + { + if (ofObjectToReturn == null || ofObjectToReturn == typeof(Stream) || ofObjectToReturn == typeof(object)) + { + return await XmlDownloadManager.GetStreamAsync(absoluteUri, _credentials, _proxy).ConfigureAwait(false); + } + + throw new XmlException(SR.Xml_UnsupportedClass, string.Empty); + } + public override Uri ResolveUri(Uri? baseUri, string? relativeUri) => base.ResolveUri(baseUri, relativeUri); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlUrlResolverAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlUrlResolverAsync.cs deleted file mode 100644 index 17ac98df3eb8b..0000000000000 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlUrlResolverAsync.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.Versioning; -using System.Threading.Tasks; - -namespace System.Xml -{ - public partial class XmlUrlResolver : XmlResolver - { - // Maps a URI to an Object containing the actual resource. - public override async Task GetEntityAsync(Uri absoluteUri, string? role, Type? ofObjectToReturn) - { - if (ofObjectToReturn == null || ofObjectToReturn == typeof(System.IO.Stream) || ofObjectToReturn == typeof(object)) - { - return await XmlDownloadManager.GetStreamAsync(absoluteUri, _credentials, _proxy).ConfigureAwait(false); - } - - throw new XmlException(SR.Xml_UnsupportedClass, string.Empty); - } - } -} diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XsltLoader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XsltLoader.cs index 42f7802e23f9e..d2f2e2e707745 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XsltLoader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XsltLoader.cs @@ -71,7 +71,7 @@ public void Load(Compiler compiler, object stylesheet, XmlResolver? xmlResolver, // for reads beyond the initial stylesheet read) will use a throwing resolver as its // default, as shown at the very top of this method. - origResolver ??= new XmlUrlResolver(); + origResolver ??= XmlReaderSettings.GetDefaultPermissiveResolver(); Uri resolvedUri = origResolver.ResolveUri(null, uri); if (resolvedUri == null) { 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 c4990141922ce..7c5ca1d4ca350 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 @@ -406,7 +406,7 @@ private static XmlResolver CreateDefaultResolver() { if (LocalAppContextSwitches.AllowDefaultResolver) { - return new XmlUrlResolver(); + return XmlReaderSettings.GetDefaultPermissiveResolver(); } return XmlResolver.ThrowingResolver; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslTransform.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslTransform.cs index 15826ec1d9c4f..2d5cfeabf0579 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslTransform.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslTransform.cs @@ -260,7 +260,7 @@ private static XmlResolver CreateDefaultResolver() { if (LocalAppContextSwitches.AllowDefaultResolver) { - return new XmlUrlResolver(); + return XmlReaderSettings.GetDefaultPermissiveResolver(); } else { diff --git a/src/libraries/System.Private.Xml/tests/AllowDefaultResolverContext.cs b/src/libraries/System.Private.Xml/tests/AllowDefaultResolverContext.cs index 9d56769158039..24e626e67b135 100644 --- a/src/libraries/System.Private.Xml/tests/AllowDefaultResolverContext.cs +++ b/src/libraries/System.Private.Xml/tests/AllowDefaultResolverContext.cs @@ -32,7 +32,7 @@ private static void ClearCachedSwitch() // the default, or alternatively separate all such tests into a separate test project // where that project contains only those tests that require the switch set. - Type t = typeof(XmlConvert).Assembly.GetType("System.LocalAppContextSwitches"); + Type t = typeof(XmlConvert).Assembly.GetType("System.Xml.LocalAppContextSwitches"); Assert.NotNull(t); FieldInfo fi = t.GetField("s_allowDefaultResolver", BindingFlags.NonPublic | BindingFlags.Static); diff --git a/src/libraries/System.Private.Xml/tests/TrimmingTests/System.Private.Xml.TrimmingTests.proj b/src/libraries/System.Private.Xml/tests/TrimmingTests/System.Private.Xml.TrimmingTests.proj index 181be44826a6a..acb15fc654be9 100644 --- a/src/libraries/System.Private.Xml/tests/TrimmingTests/System.Private.Xml.TrimmingTests.proj +++ b/src/libraries/System.Private.Xml/tests/TrimmingTests/System.Private.Xml.TrimmingTests.proj @@ -8,6 +8,12 @@ ExtraTrimmerArgs="--enable-opt sealer" /> + + System.Xml.XmlResolver.IsNetworkingEnabledByDefault + + + System.Xml.XmlResolver.IsNetworkingEnabledByDefault + diff --git a/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlUrlResolverDefaults.Disabled.IsNetworkingEnabledByDefault.cs b/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlUrlResolverDefaults.Disabled.IsNetworkingEnabledByDefault.cs new file mode 100644 index 0000000000000..683b1d960be37 --- /dev/null +++ b/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlUrlResolverDefaults.Disabled.IsNetworkingEnabledByDefault.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +using System; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.Linq; + +class XmlUrlResolverDefaults +{ + public static int Main() + { + File.WriteAllText("file.xml", """ + + + test-value + + """); + + XDocument doc = XDocument.Load("file.xml"); + + string value = doc.Descendants("some-element").Single().Value; + if (value == "test-value") + { + Type? urlResolver = GetXmlType("System.Xml.XmlUrlResolver"); + if (urlResolver == null) + { + // we should not preserve the type + return 100; + } + + return -1; + } + + return -2; + } + + // The intention of this method is to ensure the trimmer doesn't preserve the Type. + private static Type? GetXmlType(string name) => + typeof(XmlReader).Assembly.GetType(name, throwOnError: false); +} diff --git a/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlUrlResolverDefaults.IsNetworkingEnabledByDefault.cs b/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlUrlResolverDefaults.IsNetworkingEnabledByDefault.cs new file mode 100644 index 0000000000000..6dafb02774e37 --- /dev/null +++ b/src/libraries/System.Private.Xml/tests/TrimmingTests/XmlUrlResolverDefaults.IsNetworkingEnabledByDefault.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +using System; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.Linq; + +class XmlUrlResolverDefaults +{ + public static int Main() + { + File.WriteAllText("file.xml", """ + + + test-value + + """); + + XDocument doc = XDocument.Load("file.xml"); + + string value = doc.Descendants("some-element").Single().Value; + if (value == "test-value") + { + Type? urlResolver = GetXmlType("System.Xml.XmlUrlResolver"); + if (urlResolver != null) + { + // we should preserve the type but we want to avoid doing web requests during the test + return 100; + } + + return -1; + } + + return -2; + } + + // The intention of this method is to ensure the trimmer preserves the Type. + private static Type? GetXmlType(string name) => + typeof(XmlReader).Assembly.GetType(name, throwOnError: false); +} diff --git a/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs b/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs index 68368f91a265e..0c8cb022dc2ca 100644 --- a/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs +++ b/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs @@ -952,6 +952,7 @@ public abstract partial class XmlResolver protected XmlResolver() { } public virtual System.Net.ICredentials Credentials { set { } } public static System.Xml.XmlResolver ThrowingResolver { get { throw null; } } + public static System.Xml.XmlResolver FileSystemResolver { get { throw null; } } public abstract object? GetEntity(System.Uri absoluteUri, string? role, System.Type? ofObjectToReturn); public virtual System.Threading.Tasks.Task GetEntityAsync(System.Uri absoluteUri, string? role, System.Type? ofObjectToReturn) { throw null; } public virtual System.Uri ResolveUri(System.Uri? baseUri, string? relativeUri) { throw null; }