Skip to content

Commit 2048273

Browse files
Merge pull request #2386 from DarkOoze/master
Fix invalid il from identifiers containing repeating dots
2 parents 584d184 + 9747a2b commit 2048273

1 file changed

Lines changed: 24 additions & 22 deletions

File tree

ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public enum ILNameSyntax
5252

5353
public static class DisassemblerHelpers
5454
{
55+
static readonly char[] _validNonLetterIdentifierCharacter = new char[] { '_', '$', '@', '?', '`', '.' };
56+
5557
public static string OffsetToString(int offset)
5658
{
5759
return string.Format("IL_{0:x4}", offset);
@@ -104,39 +106,39 @@ static string ToInvariantCultureString(object value)
104106
}
105107

106108
static bool IsValidIdentifierCharacter(char c)
107-
{
108-
return c == '_' || c == '$' || c == '@' || c == '?' || c == '`';
109-
}
109+
=> char.IsLetterOrDigit(c) || _validNonLetterIdentifierCharacter.IndexOf(c) >= 0;
110110

111111
static bool IsValidIdentifier(string identifier)
112112
{
113113
if (string.IsNullOrEmpty(identifier))
114114
return false;
115-
if (!(char.IsLetter(identifier[0]) || IsValidIdentifierCharacter(identifier[0])))
116-
{
117-
// As a special case, .ctor and .cctor are valid despite starting with a dot
115+
116+
if (char.IsDigit(identifier[0]))
117+
return false;
118+
119+
// As a special case, .ctor and .cctor are valid despite starting with a dot
120+
if (identifier[0] == '.')
118121
return identifier == ".ctor" || identifier == ".cctor";
119-
}
120-
for (int i = 1; i < identifier.Length; i++)
121-
{
122-
if (!(char.IsLetterOrDigit(identifier[i]) || IsValidIdentifierCharacter(identifier[i]) || identifier[i] == '.'))
123-
return false;
124-
}
125-
return true;
122+
123+
if (identifier.Contains(".."))
124+
return false;
125+
126+
if (Metadata.ILOpCodeExtensions.ILKeywords.Contains(identifier))
127+
return false;
128+
129+
return identifier.All(IsValidIdentifierCharacter);
126130
}
127131

128132
public static string Escape(string identifier)
129133
{
130-
if (IsValidIdentifier(identifier) && !Metadata.ILOpCodeExtensions.ILKeywords.Contains(identifier))
134+
if (IsValidIdentifier(identifier))
131135
{
132136
return identifier;
133137
}
134-
else
135-
{
136-
// The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence,
137-
// but we follow Microsoft's ILDasm and use \'.
138-
return "'" + EscapeString(identifier).Replace("'", "\\'") + "'";
139-
}
138+
139+
// The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence,
140+
// but we follow Microsoft's ILDasm and use \'.
141+
return $"'{EscapeString(identifier).Replace("'", "\\'")}'";
140142
}
141143

142144
public static void WriteParameterReference(ITextOutput writer, MetadataReader metadata, MethodDefinitionHandle handle, int sequence)
@@ -278,7 +280,7 @@ public static void WriteOperand(ITextOutput writer, string operand)
278280

279281
public static string EscapeString(string str)
280282
{
281-
StringBuilder sb = new StringBuilder();
283+
var sb = new StringBuilder();
282284
foreach (char ch in str)
283285
{
284286
switch (ch)
@@ -317,7 +319,7 @@ public static string EscapeString(string str)
317319
// print control characters and uncommon white spaces as numbers
318320
if (char.IsControl(ch) || char.IsSurrogate(ch) || (char.IsWhiteSpace(ch) && ch != ' '))
319321
{
320-
sb.Append("\\u" + ((int)ch).ToString("x4"));
322+
sb.AppendFormat("\\u{0:x4}", (int)ch);
321323
}
322324
else
323325
{

0 commit comments

Comments
 (0)