Skip to content

XslCompiledTransform doesn't work when using TrimMode=link #45393

@eerhardt

Description

@eerhardt

See the original report of this issue: #44995 (comment)

Run the following code in a Blazor WASM published app. Or in a console app that is PublishTrimmed=true && TrimMode=link

        public static void UseXsl()
        {
            using (StringReader text = new StringReader(
    @"<?xml version=""1.0"" encoding=""UTF-8""?>
<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
</catalog>"))
            {


                XPathDocument myXPathDoc = new XPathDocument(text);
                XslCompiledTransform myXslTrans = new XslCompiledTransform();
                string xmlStr = @"<?xml version=""1.0""?>
<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
<xsl:template match=""/"">
<html>
<body>
<h2> My CD Collection</h2>
   <table border = ""1"">
      <tr bgcolor = ""#9acd32"">
         <th> Title </th>
         <th> Artist </th>
       </tr>

      <xsl:for-each select = ""catalog/cd"">
          <tr>
            <td><xsl:value-of select = ""title"" /></td>
            <td><xsl:value-of select = ""artist"" /></td>
          </tr>
        </xsl:for-each>
       </table>
     </body>
     </html>
   </xsl:template>
   </xsl:stylesheet>";
                using (StringReader str = new StringReader(xmlStr))
                using (var reader = System.Xml.XmlReader.Create(str))
                {
                    myXslTrans.Load(reader);
                    StringWriter myWriter = new StringWriter();
                    myXslTrans.Transform(myXPathDoc, null, myWriter);
                    Console.WriteLine(myWriter.GetStringBuilder().ToString());

                }
            }

        }

Expected results

The code should work the same way it does in a non-trimmed app.

Actual results

(unknown) Unhandled Exception:
window.console.error
(unknown) System.ArgumentNullException: ArgumentNull_Generic Arg_ParamName_Name, con
window.console.error
(unknown)    at System.Reflection.Emit.CustomAttributeBuilder.Initialize(ConstructorInfo con, Object[] constructorArgs, PropertyInfo[] namedProperties, Object[] propertyValues, FieldInfo[] namedFields, Object[] fieldValues)
window.console.error
(unknown)    at System.Reflection.Emit.CustomAttributeBuilder..ctor(ConstructorInfo con, Object[] constructorArgs)
window.console.error
(unknown)    at System.Xml.Xsl.IlGen.XmlILModule.CreateLREModule()
window.console.error
(unknown)    at System.Xml.Xsl.IlGen.XmlILModule..cctor()
window.console.error
(unknown) crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: TypeInitialization_Type, System.Xml.Xsl.IlGen.XmlILModule
System.TypeInitializationException: TypeInitialization_Type, System.Xml.Xsl.IlGen.XmlILModule
 ---> System.ArgumentNullException: ArgumentNull_Generic Arg_ParamName_Name, con
   at System.Reflection.Emit.CustomAttributeBuilder.Initialize(ConstructorInfo con, Object[] constructorArgs, PropertyInfo[] namedProperties, Object[] propertyValues, FieldInfo[] namedFields, Object[] fieldValues)
   at System.Reflection.Emit.CustomAttributeBuilder..ctor(ConstructorInfo con, Object[] constructorArgs)
   at System.Xml.Xsl.IlGen.XmlILModule.CreateLREModule()
   at System.Xml.Xsl.IlGen.XmlILModule..cctor()
   Exception_EndOfInnerExceptionStack
   at System.Xml.Xsl.XmlILGenerator.Generate(QilExpression query, TypeBuilder typeBldr)
   at System.Xml.Xsl.XslCompiledTransform.CompileQilToMsil(XsltSettings settings)
   at System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver)
   at System.Xml.Xsl.XslCompiledTransform.Load(XmlReader stylesheet)
   at Panasoft.Web.MyData.Client.Pages.Monitor.TraceView.OnParametersSetAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)

It looks like the following code needs to be annotated correctly for the ILLinker to preserve the constructors correctly:

internal static class XmlILConstructors
{
public static readonly ConstructorInfo DecFromParts = GetConstructor(typeof(decimal), typeof(int), typeof(int), typeof(int), typeof(bool), typeof(byte));
public static readonly ConstructorInfo DecFromInt32 = GetConstructor(typeof(decimal), typeof(int));
public static readonly ConstructorInfo DecFromInt64 = GetConstructor(typeof(decimal), typeof(long));
public static readonly ConstructorInfo Debuggable = GetConstructor(typeof(DebuggableAttribute), typeof(DebuggableAttribute.DebuggingModes));
public static readonly ConstructorInfo NonUserCode = GetConstructor(typeof(DebuggerNonUserCodeAttribute));
public static readonly ConstructorInfo QName = GetConstructor(typeof(XmlQualifiedName), typeof(string), typeof(string));
public static readonly ConstructorInfo StepThrough = GetConstructor(typeof(DebuggerStepThroughAttribute));
public static readonly ConstructorInfo Transparent = GetConstructor(typeof(SecurityTransparentAttribute));
private static ConstructorInfo GetConstructor(Type className)
{
ConstructorInfo constrInfo = className.GetConstructor(Type.EmptyTypes)!;
Debug.Assert(constrInfo != null, "Constructor " + className + " cannot be null.");
return constrInfo;
}
private static ConstructorInfo GetConstructor(Type className, params Type[] args)
{
ConstructorInfo constrInfo = className.GetConstructor(args)!;
Debug.Assert(constrInfo != null, "Constructor " + className + " cannot be null.");
return constrInfo;
}
}

Side-note: The ILLink warnings caught this as well:

<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2070</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Xsl.IlGen.XmlILConstructors.GetConstructor(System.Type,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.IlGen.XmlILConstructors.GetConstructor(System.Type)</property>
</attribute>

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Xmllinkable-frameworkIssues associated with delivering a linker friendly frameworkuntriagedNew issue has not been triaged by the area owner

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions