From b45c0099ef7807a814147e742829c0e98eeec570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20H=C3=B6rnfeldt?= Date: Sat, 1 May 2021 09:04:43 +0200 Subject: [PATCH 1/2] Refactor for readability --- .../Disassembler/DisassemblerHelpers.cs | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs b/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs index b20dfeb75c..58744d44ae 100644 --- a/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs +++ b/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs @@ -52,6 +52,8 @@ public enum ILNameSyntax public static class DisassemblerHelpers { + static readonly char[] _validNonLetterIdentifierCharacter = new char[] { '_', '$', '@', '?', '`', '.' }; + public static string OffsetToString(int offset) { return string.Format("IL_{0:x4}", offset); @@ -104,39 +106,36 @@ static string ToInvariantCultureString(object value) } static bool IsValidIdentifierCharacter(char c) - { - return c == '_' || c == '$' || c == '@' || c == '?' || c == '`'; - } + => char.IsLetterOrDigit(c) || _validNonLetterIdentifierCharacter.IndexOf(c) >= 0; static bool IsValidIdentifier(string identifier) { if (string.IsNullOrEmpty(identifier)) return false; - if (!(char.IsLetter(identifier[0]) || IsValidIdentifierCharacter(identifier[0]))) - { - // As a special case, .ctor and .cctor are valid despite starting with a dot + + if (char.IsDigit(identifier[0])) + return false; + + // As a special case, .ctor and .cctor are valid despite starting with a dot + if (identifier[0] == '.') return identifier == ".ctor" || identifier == ".cctor"; - } - for (int i = 1; i < identifier.Length; i++) - { - if (!(char.IsLetterOrDigit(identifier[i]) || IsValidIdentifierCharacter(identifier[i]) || identifier[i] == '.')) - return false; - } - return true; + + if (Metadata.ILOpCodeExtensions.ILKeywords.Contains(identifier)) + return false; + + return identifier.All(IsValidIdentifierCharacter); } public static string Escape(string identifier) { - if (IsValidIdentifier(identifier) && !Metadata.ILOpCodeExtensions.ILKeywords.Contains(identifier)) + if (IsValidIdentifier(identifier)) { return identifier; } - else - { - // The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence, - // but we follow Microsoft's ILDasm and use \'. - return "'" + EscapeString(identifier).Replace("'", "\\'") + "'"; - } + + // The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence, + // but we follow Microsoft's ILDasm and use \'. + return $"'{EscapeString(identifier).Replace("'", "\\'")}'"; } public static void WriteParameterReference(ITextOutput writer, MetadataReader metadata, MethodDefinitionHandle handle, int sequence) @@ -278,7 +277,7 @@ public static void WriteOperand(ITextOutput writer, string operand) public static string EscapeString(string str) { - StringBuilder sb = new StringBuilder(); + var sb = new StringBuilder(); foreach (char ch in str) { switch (ch) @@ -317,7 +316,7 @@ public static string EscapeString(string str) // print control characters and uncommon white spaces as numbers if (char.IsControl(ch) || char.IsSurrogate(ch) || (char.IsWhiteSpace(ch) && ch != ' ')) { - sb.Append("\\u" + ((int)ch).ToString("x4")); + sb.AppendFormat("\\u{0:x4}", (int)ch); } else { From 9747a2b3595bbdca33fd6281e6a275c65d70903b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20H=C3=B6rnfeldt?= Date: Sat, 1 May 2021 14:44:08 +0200 Subject: [PATCH 2/2] Escape identifiers containing repeating dots --- ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs b/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs index 58744d44ae..29e24ddbad 100644 --- a/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs +++ b/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs @@ -120,6 +120,9 @@ static bool IsValidIdentifier(string identifier) if (identifier[0] == '.') return identifier == ".ctor" || identifier == ".cctor"; + if (identifier.Contains("..")) + return false; + if (Metadata.ILOpCodeExtensions.ILKeywords.Contains(identifier)) return false;