</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
- <argument>IL2070</argument>
- <property name="Scope">member</property>
- <property name="Target">M:System.Xml.Xsl.Runtime.EarlyBoundInfo.#ctor(System.String,System.Type)</property>
- </attribute>
- <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
- <argument>ILLink</argument>
- <argument>IL2070</argument>
- <property name="Scope">member</property>
- <property name="Target">M:System.Xml.Xsl.XslCompiledTransform.Load(System.Type)</property>
- </attribute>
- <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
- <argument>ILLink</argument>
<argument>IL2072</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.ReflectionXmlSerializationReader.WriteNullableMethod(System.Xml.Serialization.NullableMapping,System.Boolean,System.String)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
- <argument>IL2072</argument>
- <property name="Scope">member</property>
- <property name="Target">M:System.Xml.Xsl.XsltOld.Processor.#ctor(System.Xml.XPath.XPathNavigator,System.Xml.Xsl.XsltArgumentList,System.Xml.XmlResolver,System.Xml.Xsl.XsltOld.Stylesheet,System.Collections.Generic.List{System.Xml.Xsl.XsltOld.TheQuery},System.Xml.Xsl.XsltOld.RootAction,System.Xml.Xsl.XsltOld.Debugger.IXsltDebugger)</property>
- </attribute>
- <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
- <argument>ILLink</argument>
<argument>IL2075</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.CodeGenerator.GetPropertyMethodFromBaseType(System.Reflection.PropertyInfo,System.Boolean)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
- <argument>IL2075</argument>
- <property name="Scope">member</property>
- <property name="Target">M:System.Xml.Xsl.IlGen.XmlILModule.BakeMethods</property>
- </attribute>
- <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
- <argument>ILLink</argument>
- <argument>IL2075</argument>
- <property name="Scope">member</property>
- <property name="Target">M:System.Xml.Xsl.XsltOld.XsltCompileContext.GetExtentionMethod(System.String,System.String,System.Xml.XPath.XPathResultType[],System.Object@)</property>
- </attribute>
- <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
- <argument>ILLink</argument>
<argument>IL2077</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.SerializableMapping.RetrieveSerializableSchema</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
- <argument>IL2080</argument>
+ <argument>IL2067</argument>
<property name="Scope">member</property>
- <property name="Target">M:System.Xml.Xsl.Runtime.XmlExtensionFunction.Bind</property>
+ <property name="Target">M:System.Xml.Xsl.Runtime.XmlExtensionFunction.#ctor(System.String,System.String,System.Int32,System.Type,System.Reflection.BindingFlags)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
- <argument>IL2080</argument>
+ <argument>IL2067</argument>
<property name="Scope">member</property>
- <property name="Target">M:System.Xml.Xsl.Runtime.XmlExtensionFunction.CanBind</property>
+ <property name="Target">M:System.Xml.Xsl.Runtime.XmlExtensionFunctionTable.Bind(System.String,System.String,System.Int32,System.Type,System.Reflection.BindingFlags)</property>
+ </attribute>
+ <attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
+ <argument>ILLink</argument>
+ <argument>IL2075</argument>
+ <property name="Scope">member</property>
+ <property name="Target">M:System.Xml.Xsl.XsltOld.XsltCompileContext.GetExtentionMethod(System.String,System.String,System.Xml.XPath.XPathResultType[],System.Object@)</property>
</attribute>
</assembly>
</linker>
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Xml.Xsl.Qil;
using System.Xml.Xsl.Runtime;
/// Add early bound information to a list that is used by this query. Return the index of
/// the early bound information in the list.
/// </summary>
- public int DeclareEarlyBound(string namespaceUri, Type ebType)
+ public int DeclareEarlyBound(string namespaceUri, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type ebType)
{
if (_earlyInfo == null)
_earlyInfo = new UniqueList<EarlyBoundInfo>();
private IteratorDescriptor? _iterNested;
private int _indexId;
+ [RequiresUnreferencedCode("Method VisitXsltInvokeEarlyBound will require code that cannot be statically analyzed.")]
+ public XmlILVisitor()
+ { }
//-----------------------------------------------
// Entry
/// <summary>
/// Generate code for QilNodeType.XsltInvokeEarlyBound.
/// </summary>
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072:RequiresUnreferencedCode",
+ Justification = "Supressing warning about not having the RequiresUnreferencedCode attribute since we added " +
+ "the attribute to this subclass' constructor. This allows us to not have to annotate the whole QilNode hirerarchy.")]
protected override QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound ndInvoke)
{
QilName ndName = ndInvoke.Name;
#nullable disable
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
namespace System.Xml.Xsl.Runtime
{
private readonly string _namespaceUri; // Namespace Uri mapped to these early bound functions
private readonly ConstructorInfo _constrInfo; // Constructor for the early bound function object
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
+ private readonly Type _ebType;
- public EarlyBoundInfo(string namespaceUri, Type ebType)
+ public EarlyBoundInfo(string namespaceUri, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type ebType)
{
Debug.Assert(namespaceUri != null && ebType != null);
// Get the default constructor
_namespaceUri = namespaceUri;
+ _ebType = ebType;
_constrInfo = ebType.GetConstructor(Type.EmptyTypes);
Debug.Assert(_constrInfo != null, "The early bound object type " + ebType.FullName + " must have a public default constructor");
}
/// <summary>
/// Return the Clr Type of the early bound object.
/// </summary>
- public Type EarlyBoundType { get { return _constrInfo.DeclaringType; } }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
+ public Type EarlyBoundType
+ {
+ get { return _ebType; }
+ }
/// <summary>
/// Create an instance of the early bound object.
using System.Reflection;
using System.Globalization;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
namespace System.Xml.Xsl.Runtime
{
private string _namespaceUri; // Extension object identifier
private string _name; // Name of this method
private int _numArgs; // Argument count
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
private Type _objectType; // Type of the object which will be searched for matching methods
private BindingFlags _flags; // Modifiers that were used to search for a matching signature
private int _hashCode; // Pre-computed hashcode
/// <summary>
/// Initialize, but do not bind.
/// </summary>
- public void Init(string name, string namespaceUri, int numArgs, Type objectType, BindingFlags flags)
+ public void Init(string name, string namespaceUri, int numArgs, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicMethods)] Type objectType, BindingFlags flags)
{
_name = name;
_namespaceUri = namespaceUri;
#nullable disable
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Xml.Xsl.IlGen;
using System.Xml.Xsl.Qil;
/// <summary>
/// Constructor.
/// </summary>
+ [RequiresUnreferencedCode("This method will create a copy that uses earlybound types which cannot be statically analyzed.")]
public XmlQueryStaticData(XmlWriterSettings defaultWriterSettings, IList<WhitespaceRule> whitespaceRules, StaticDataManager staticData)
{
Debug.Assert(defaultWriterSettings != null && staticData != null);
/// <summary>
/// Deserialize XmlQueryStaticData object from a byte array.
/// </summary>
+ [RequiresUnreferencedCode("This method will create EarlyBoundInfo from passed in ebTypes array which cannot be statically analyzed.")]
public XmlQueryStaticData(byte[] data, Type[] ebTypes)
{
MemoryStream dataStream = new MemoryStream(data, /*writable:*/false);
// SxS Note: The way the trace file names are created (hardcoded) is NOT SxS safe. However the files are
// created only for internal tracing purposes. In addition XmlILTrace class is not compiled into retail
// builds. As a result it is fine to suppress the FxCop SxS warning.
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
+ Justification = "This method will generate the IL methods using RefEmit at runtime, which will then try to call them " +
+ "using methods that are annotated as RequiresUnreferencedCode. In this case, these uses can be suppressed as the " +
+ "trimmer won't be able to trim any IL that gets generated at runtime.")]
public XmlILCommand? Generate(QilExpression query, TypeBuilder? typeBldr)
{
_qil = query;
}
// Create list of all early bound objects
- Dictionary<string, Type?> scriptClasses = compiler.Scripts.ScriptClasses;
+ Scripts.TrimSafeDictionary scriptClasses = compiler.Scripts.ScriptClasses;
List<EarlyBoundInfo> ebTypes = new List<EarlyBoundInfo>(scriptClasses.Count);
- foreach (KeyValuePair<string, Type?> pair in scriptClasses)
+ foreach (string key in scriptClasses.Keys)
{
- if (pair.Value != null)
+ Type? value = scriptClasses[key];
+ if (value != null)
{
- ebTypes.Add(new EarlyBoundInfo(pair.Key, pair.Value));
+ ebTypes.Add(new EarlyBoundInfo(key, value));
}
}
// <spec>http://devdiv/Documents/Whidbey/CLR/CurrentSpecs/BCL/CodeDom%20Activation.doc</spec>
//------------------------------------------------------------------------------
+using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Xml.Xsl.Runtime;
namespace System.Xml.Xsl.Xslt
internal class Scripts
{
private readonly Compiler _compiler;
- private readonly Dictionary<string, Type?> _nsToType = new Dictionary<string, Type?>();
+ private readonly TrimSafeDictionary _nsToType = new TrimSafeDictionary();
private readonly XmlExtensionFunctionTable _extFuncs = new XmlExtensionFunctionTable();
public Scripts(Compiler compiler)
_compiler = compiler;
}
- public Dictionary<string, Type?> ScriptClasses
+ public TrimSafeDictionary ScriptClasses
{
get { return _nsToType; }
}
}
return null;
}
+
+ internal class TrimSafeDictionary
+ {
+ private readonly Dictionary<string, Type?> _backingDictionary = new Dictionary<string, Type?>();
+
+ public Type? this[string key]
+ {
+ [UnconditionalSuppressMessage("TrimAnalysis", "IL2073:MissingDynamicallyAccessedMembers",
+ Justification = "The getter of the dictionary is not annotated to preserve the constructor, but the sources that are adding the items to " +
+ "the dictionary are annotated so we can supress the message as we know the constructor will be preserved.")]
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
+ get => _backingDictionary[key];
+ [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
+ set => _backingDictionary[key] = value;
+ }
+
+ public ICollection<string> Keys => _backingDictionary.Keys;
+
+ public int Count => _backingDictionary.Count;
+
+ public bool ContainsKey(string key) => _backingDictionary.ContainsKey(key);
+
+ public bool TryGetValue(string key, [MaybeNullWhen(false)] out Type? value) => _backingDictionary.TryGetValue(key, out value);
+ }
}
}
_scriptExtensions = new Hashtable(_stylesheet.ScriptObjectTypes.Count);
{
- foreach (DictionaryEntry entry in _stylesheet.ScriptObjectTypes)
+ // Scripts are not supported on stylesheets
+ if (_stylesheet.ScriptObjectTypes.Count > 0)
{
- string namespaceUri = (string)entry.Key;
- if (GetExtensionObject(namespaceUri) != null)
- {
- throw XsltException.Create(SR.Xslt_ScriptDub, namespaceUri);
- }
- _scriptExtensions.Add(namespaceUri, Activator.CreateInstance((Type)entry.Value!,
- BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, null, null));
+ throw new PlatformNotSupportedException(SR.CompilingScriptsNotSupported);
}
}
//------------------------------------------------
// Load compiled stylesheet from a Type
//------------------------------------------------
-
+ [RequiresUnreferencedCode("This method will get fields and types from the assembly of the passed in compiledStylesheet and call their constructors which cannot be statically analyzed")]
public void Load(Type compiledStylesheet)
{
Reset();
throw new ArgumentException(SR.Format(SR.Xslt_NotCompiledStylesheet, compiledStylesheet.FullName), nameof(compiledStylesheet));
}
+ [RequiresUnreferencedCode("This method will call into constructors of the earlyBoundTypes array which cannot be statically analyzed.")]
public void Load(MethodInfo executeMethod, byte[] queryData, Type[]? earlyBoundTypes)
{
Reset();
_output.WriteLine("Did not throw compile exception for stylesheet");
Assert.True(false);
}
+
+ [Fact]
+ public void XslTransformThrowsPNSEWhenUsingScripts()
+ {
+ using StringReader xslFile = new StringReader(
+ @"<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""
+ xmlns:msxsl=""urn:schemas-microsoft-com:xslt""
+ xmlns:user=""urn:my-scripts"">
+ <msxsl:script language=""C#"" implements-prefix=""user"">
+ <![CDATA[
+ public double modifyPrice(double price){
+ price*=0.9;
+ return price;
+ }
+ ]]>
+ </msxsl:script>
+ <xsl:template match=""Root"">
+ <Root xmlns="""">
+ <Price><xsl:value-of select=""user:modifyPrice(Price)""/></Price>
+ </Root>
+ </xsl:template>
+</xsl:stylesheet>");
+
+ using XmlReader reader = XmlReader.Create(xslFile);
+ XslTransform xslt = new XslTransform();
+ XsltCompileException compilationException = Assert.Throws<XsltCompileException>(() => xslt.Load(reader));
+ Assert.True(compilationException.InnerException != null && compilationException.InnerException is PlatformNotSupportedException);
+ }
}
/**************************************************************************/
public XslCompiledTransform() { }
public XslCompiledTransform(bool enableDebug) { }
public System.Xml.XmlWriterSettings? OutputSettings { get { throw null; } }
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This method will call into constructors of the earlyBoundTypes array which cannot be statically analyzed.")]
public void Load(System.Reflection.MethodInfo executeMethod, byte[] queryData, System.Type[]? earlyBoundTypes) { }
public void Load(string stylesheetUri) { }
public void Load(string stylesheetUri, System.Xml.Xsl.XsltSettings? settings, System.Xml.XmlResolver? stylesheetResolver) { }
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This method will get fields and types from the assembly of the passed in compiledStylesheet and call their constructors which cannot be statically analyzed")]
public void Load(System.Type compiledStylesheet) { }
public void Load(System.Xml.XmlReader stylesheet) { }
public void Load(System.Xml.XmlReader stylesheet, System.Xml.Xsl.XsltSettings? settings, System.Xml.XmlResolver? stylesheetResolver) { }