From 2fb90738db156d073f1eb635d229fb4520e77e88 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 21 Dec 2024 19:09:07 +0100 Subject: [PATCH] Escape resource names in the treeview and decompiler (fixes #387) --- .../TreeView/Resources/ResourceElementNode.cs | 3 +- .../TreeView/Resources/ResourceNode.cs | 5 ++- .../Text/ITextColorWriterExtensions.cs | 33 +++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceElementNode.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceElementNode.cs index 3f45a5bd72..0528d28623 100644 --- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceElementNode.cs +++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceElementNode.cs @@ -141,8 +141,7 @@ protected ResourceElementNode(ITreeNodeGroup treeNodeGroup, ResourceElement reso public virtual void WriteShort(IDecompilerOutput output, IDecompiler decompiler, bool showOffset) { decompiler.WriteCommentBegin(output, true); output.WriteOffsetComment(this, showOffset); - const string LTR = "\u200E"; - output.Write(NameUtilities.CleanName(Name) + LTR, this, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, BoxedTextColor.Comment); + output.Write(IdentifierEscaper.Escape(Name), this, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, BoxedTextColor.Comment); output.Write($" = {ValueString}", BoxedTextColor.Comment); decompiler.WriteCommentEnd(output, true); output.WriteLine(); diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceNode.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceNode.cs index c1ffeee831..ecab03626b 100644 --- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceNode.cs +++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceNode.cs @@ -46,7 +46,7 @@ public abstract class ResourceNode : DocumentTreeNodeData, IResourceNode { /// protected sealed override void WriteCore(ITextColorWriter output, IDecompiler decompiler, DocumentNodeWriteOptions options) { - output.WriteFilename(Resource.Name); + output.WriteFilenameIdentifier(Resource.Name); if ((options & DocumentNodeWriteOptions.ToolTip) != 0) { output.WriteLine(); WriteFilename(output); @@ -149,8 +149,7 @@ protected void Save() => public virtual void WriteShort(IDecompilerOutput output, IDecompiler decompiler, bool showOffset) { decompiler.WriteCommentBegin(output, true); output.WriteOffsetComment(this, showOffset); - const string LTR = "\u200E"; - output.Write(NameUtilities.CleanName(Name) + LTR, this, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, BoxedTextColor.Comment); + output.Write(IdentifierEscaper.Escape(Name), this, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, BoxedTextColor.Comment); string? extra = null; switch (Resource.ResourceType) { case ResourceType.AssemblyLinked: diff --git a/dnSpy/dnSpy.Contracts.Logic/Text/ITextColorWriterExtensions.cs b/dnSpy/dnSpy.Contracts.Logic/Text/ITextColorWriterExtensions.cs index 3e3c11e11c..a0ae606a18 100644 --- a/dnSpy/dnSpy.Contracts.Logic/Text/ITextColorWriterExtensions.cs +++ b/dnSpy/dnSpy.Contracts.Logic/Text/ITextColorWriterExtensions.cs @@ -208,5 +208,38 @@ public static T WriteFilename(this T output, string? filename) where T : ITex } return output; } + + /// + /// Writes a filename, escaping the filename and directory parts using + /// + /// Writer type + /// Output + /// Filename + /// + public static T WriteFilenameIdentifier(this T output, string? filename) where T : ITextColorWriter { + if (filename is null) + return output; + var s = filename.Replace('\\', '/'); + var parts = s.Split('/'); + int slashIndex = 0; + for (int i = 0; i < parts.Length - 1; i++) { + output.Write(BoxedTextColor.DirectoryPart, IdentifierEscaper.Escape(parts[i])); + slashIndex += parts[i].Length; + output.Write(BoxedTextColor.Text, filename[slashIndex].ToString()); + slashIndex++; + } + var fn = parts[parts.Length - 1]; + int index = fn.LastIndexOf('.'); + if (index < 0) + output.Write(BoxedTextColor.FileNameNoExtension, IdentifierEscaper.Escape(fn)); + else { + string ext = fn.Substring(index + 1); + fn = fn.Substring(0, index); + output.Write(BoxedTextColor.FileNameNoExtension, IdentifierEscaper.Escape(fn)); + output.Write(BoxedTextColor.Text, "."); + output.Write(BoxedTextColor.FileExtension, ext); + } + return output; + } } }