Skip to content

Commit

Permalink
Improved escaping of invalid characters in decompiled XAML
Browse files Browse the repository at this point in the history
  • Loading branch information
ElektroKill committed Sep 19, 2023
1 parent cac9f42 commit 48cb130
Showing 3 changed files with 21 additions and 10 deletions.
26 changes: 17 additions & 9 deletions Extensions/dnSpy.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using dnlib.DotNet;
using dnSpy.BamlDecompiler.Baml;
@@ -126,7 +127,7 @@ struct FieldAssignment {
public void Callback(XamlContext ctx, XElement elem) {
var xName = ctx.GetKnownNamespace("Name", XamlContext.KnownNamespace_Xaml, elem);
if (elem.Attribute("Name") is null && elem.Attribute(xName) is null)
elem.Add(new XAttribute(xName, FieldName));
elem.Add(new XAttribute(xName, IdentifierEscaper.Escape(FieldName)));
}
}

@@ -138,20 +139,27 @@ struct EventAttachment {
public void Callback(XamlContext ctx, XElement elem) {
var type = elem.Annotation<XamlType>();
if (type is not null && type.TypeNamespace == "System.Windows" && type.TypeName == "Style") {
elem.Add(new XElement(type.Namespace + "EventSetter", new XAttribute("Event", EventName), new XAttribute("Handler", MethodName)));
elem.Add(new XElement(type.Namespace + "EventSetter",
new XAttribute("Event", IdentifierEscaper.Escape(EventName)),
new XAttribute("Handler", IdentifierEscaper.Escape(MethodName))));
return;
}

string encodedEventName = XmlConvert.EncodeName(EventName);
XName name;
if (AttachedType is not null) {
var clrNs = AttachedType.ReflectionNamespace;
var xmlNs = ctx.XmlNs.LookupXmlns(AttachedType.DefinitionAssembly, clrNs);
name = ctx.GetXmlNamespace(xmlNs)?.GetName(EventName) ?? AttachedType.Name + "." + EventName;
var xmlNamespace = ctx.GetXmlNamespace(xmlNs);
if (xmlNamespace is not null)
name = xmlNamespace.GetName(encodedEventName);
else
name = $"{XmlConvert.EncodeName(AttachedType.Name)}.{encodedEventName}";
}
else
name = EventName;
name = encodedEventName;

elem.Add(new XAttribute(name, MethodName));
elem.Add(new XAttribute(name, IdentifierEscaper.Escape(MethodName)));
}
}

@@ -190,7 +198,7 @@ Dictionary<int, Action<XamlContext, XElement>> ExtractConnectionId(XamlContext c
switch (expr.Code) {
case ILCode.Stfld:
cb += new FieldAssignment {
FieldName = IdentifierEscaper.Escape(((IField)expr.Operand).Name)
FieldName = ((IField)expr.Operand).Name
}.Callback;
break;

@@ -218,7 +226,7 @@ Dictionary<int, Action<XamlContext, XElement>> ExtractConnectionId(XamlContext c
cb += new EventAttachment {
AttachedType = reField.DeclaringType.ResolveTypeDef() ?? reField.DeclaringType,
EventName = evName,
MethodName = IdentifierEscaper.Escape(handler.Name)
MethodName = handler.Name
}.Callback;
}
else {
@@ -243,7 +251,7 @@ Dictionary<int, Action<XamlContext, XElement>> ExtractConnectionId(XamlContext c

cb += new EventAttachment {
EventName = eventName,
MethodName = IdentifierEscaper.Escape(handler.Name)
MethodName = handler.Name
}.Callback;
}
break;
@@ -312,7 +320,7 @@ static bool MatchEventSetterCreation(List<ILNode> body, ref int i, out EventAtt

i += 3;

@event = new EventAttachment { EventName = evName, MethodName = IdentifierEscaper.Escape(handlerMethod.Name) };
@event = new EventAttachment { EventName = evName, MethodName = handlerMethod.Name };
return true;
}

3 changes: 2 additions & 1 deletion Extensions/dnSpy.BamlDecompiler/Rewrite/XClassRewritePass.cs
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ THE SOFTWARE.
using System.Xml.Linq;
using dnlib.DotNet;
using dnSpy.BamlDecompiler.Xaml;
using dnSpy.Contracts.Decompiler;

namespace dnSpy.BamlDecompiler.Rewrite {
sealed class XClassRewritePass : IRewritePass {
@@ -56,7 +57,7 @@ void RewriteClass(XamlContext ctx, XElement elem) {
var classModifierName = ctx.GetKnownNamespace("ClassModifier", XamlContext.KnownNamespace_Xaml, elem);
attrs.Insert(0, new XAttribute(classModifierName, ctx.BamlDecompilerOptions.InternalClassModifier));
}
attrs.Insert(0, new XAttribute(attrName, type.ResolvedType.ReflectionFullName));
attrs.Insert(0, new XAttribute(attrName, IdentifierEscaper.Escape(type.ResolvedType.ReflectionFullName)));
elem.ReplaceAttributes(attrs);
}
}
2 changes: 2 additions & 0 deletions Extensions/dnSpy.BamlDecompiler/XamlContext.cs
Original file line number Diff line number Diff line change
@@ -162,6 +162,8 @@ public XNamespace GetXmlNamespace(string xmlns) {
if (xmlns is null)
return null;

xmlns = IdentifierEscaper.Escape(xmlns);

if (!xmlnsMap.TryGetValue(xmlns, out var ns))
xmlnsMap[xmlns] = ns = XNamespace.Get(xmlns);
return ns;

0 comments on commit 48cb130

Please sign in to comment.