Browse Source

Fix #1359: Support obfuscated names in treeview and search.

pull/1423/head
Siegfried Pammer 7 years ago
parent
commit
25765ee600
  1. 53
      ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs
  2. 15
      ICSharpCode.Decompiler/Output/TextTokenWriter.cs
  3. 22
      ILSpy/Languages/Language.cs

53
ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs

@ -63,8 +63,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -63,8 +63,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
textWriter.Write('@');
column++;
}
textWriter.Write(identifier.Name);
column += identifier.Name.Length;
string name = EscapeIdentifier(identifier.Name);
textWriter.Write(name);
column += name.Length;
isAtStartOfLine = false;
}
@ -418,6 +419,54 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -418,6 +419,54 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
return sb.ToString();
}
public static string EscapeIdentifier(string identifier)
{
if (string.IsNullOrEmpty(identifier))
return identifier;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < identifier.Length; i++) {
if (IsPrintableIdentifierChar(identifier, i)) {
if (char.IsSurrogatePair(identifier, i)) {
sb.Append(identifier.Substring(i, 2));
i++;
} else {
sb.Append(identifier[i]);
}
} else {
if (char.IsSurrogatePair(identifier, i)) {
sb.AppendFormat("\\U{0:x8}", char.ConvertToUtf32(identifier, i));
i++;
} else {
sb.AppendFormat("\\u{0:x4}", (int)identifier[i]);
}
}
}
return sb.ToString();
}
static bool IsPrintableIdentifierChar(string identifier, int index)
{
switch (char.GetUnicodeCategory(identifier, index)) {
case UnicodeCategory.ModifierLetter:
case UnicodeCategory.NonSpacingMark:
case UnicodeCategory.SpacingCombiningMark:
case UnicodeCategory.EnclosingMark:
case UnicodeCategory.LineSeparator:
case UnicodeCategory.ParagraphSeparator:
case UnicodeCategory.Control:
case UnicodeCategory.Format:
case UnicodeCategory.Surrogate:
case UnicodeCategory.PrivateUse:
case UnicodeCategory.ConnectorPunctuation:
case UnicodeCategory.ModifierSymbol:
case UnicodeCategory.OtherNotAssigned:
case UnicodeCategory.SpaceSeparator:
return false;
default:
return true;
}
}
public override void WritePrimitiveType(string type)
{
textWriter.Write(type);

15
ICSharpCode.Decompiler/Output/TextTokenWriter.cs

@ -63,34 +63,35 @@ namespace ICSharpCode.Decompiler @@ -63,34 +63,35 @@ namespace ICSharpCode.Decompiler
}
var definition = GetCurrentDefinition();
string name = TextWriterTokenWriter.EscapeIdentifier(identifier.Name);
switch (definition) {
case IType t:
output.WriteReference(t, identifier.Name, true);
output.WriteReference(t, name, true);
return;
case IMember m:
output.WriteReference(m, identifier.Name, true);
output.WriteReference(m, name, true);
return;
}
var member = GetCurrentMemberReference();
switch (member) {
case IType t:
output.WriteReference(t, identifier.Name, false);
output.WriteReference(t, name, false);
return;
case IMember m:
output.WriteReference(m, identifier.Name, false);
output.WriteReference(m, name, false);
return;
}
var localDefinition = GetCurrentLocalDefinition();
if (localDefinition != null) {
output.WriteLocalReference(identifier.Name, localDefinition, isDefinition: true);
output.WriteLocalReference(name, localDefinition, isDefinition: true);
return;
}
var localRef = GetCurrentLocalReference();
if (localRef != null) {
output.WriteLocalReference(identifier.Name, localRef);
output.WriteLocalReference(name, localRef);
return;
}
@ -99,7 +100,7 @@ namespace ICSharpCode.Decompiler @@ -99,7 +100,7 @@ namespace ICSharpCode.Decompiler
firstUsingDeclaration = false;
}
output.Write(identifier.Name);
output.Write(name);
}
ISymbol GetCurrentMemberReference()

22
ILSpy/Languages/Language.cs

@ -407,18 +407,20 @@ namespace ICSharpCode.ILSpy @@ -407,18 +407,20 @@ namespace ICSharpCode.ILSpy
protected string GetDisplayName(IEntity entity, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName)
{
if (includeDeclaringTypeName && entity.DeclaringTypeDefinition != null) {
string name;
if (includeNamespaceOfDeclaringTypeName) {
name = EscapeName(entity.DeclaringTypeDefinition.FullName);
string entityName;
if (entity is ITypeDefinition t && !t.MetadataToken.IsNil) {
MetadataReader metadata = t.ParentModule.PEFile.Metadata;
var typeDef = metadata.GetTypeDefinition((TypeDefinitionHandle)t.MetadataToken);
entityName = EscapeName(metadata.GetString(typeDef.Name));
} else {
name = EscapeName(entity.DeclaringTypeDefinition.Name);
entityName = EscapeName(entity.Name);
}
return name + "." + EscapeName(entity.Name);
if (includeNamespace || includeDeclaringTypeName) {
if (entity.DeclaringTypeDefinition != null)
return TypeToString(entity.DeclaringTypeDefinition, includeNamespaceOfDeclaringTypeName) + "." + entityName;
return EscapeName(entity.Namespace) + "." + entityName;
} else {
if (includeNamespace)
return EscapeName(entity.FullName);
return EscapeName(entity.Name);
return entityName;
}
}
@ -528,7 +530,7 @@ namespace ICSharpCode.ILSpy @@ -528,7 +530,7 @@ namespace ICSharpCode.ILSpy
public static StringBuilder EscapeName(StringBuilder sb, string name)
{
foreach (char ch in name) {
if (char.IsWhiteSpace(ch) || char.IsControl(ch))
if (char.IsWhiteSpace(ch) || char.IsControl(ch) || char.IsSurrogate(ch))
sb.AppendFormat("\\u{0:x4}", (int)ch);
else
sb.Append(ch);

Loading…
Cancel
Save