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
textWriter.Write('@'); textWriter.Write('@');
column++; column++;
} }
textWriter.Write(identifier.Name); string name = EscapeIdentifier(identifier.Name);
column += identifier.Name.Length; textWriter.Write(name);
column += name.Length;
isAtStartOfLine = false; isAtStartOfLine = false;
} }
@ -418,6 +419,54 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
return sb.ToString(); 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) public override void WritePrimitiveType(string type)
{ {
textWriter.Write(type); textWriter.Write(type);

15
ICSharpCode.Decompiler/Output/TextTokenWriter.cs

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

22
ILSpy/Languages/Language.cs

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

Loading…
Cancel
Save