Browse Source

Fix #2280: Add additional checks to GenerateVariableName

pull/2289/head
Siegfried Pammer 5 years ago
parent
commit
669fe6417e
  1. 5
      ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs
  2. 53
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

5
ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

@ -202,7 +202,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -202,7 +202,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
var v = function.RegisterVariable(
VariableKind.StackSlot,
type,
AssignVariableNames.GenerateVariableName(function, type, stmt.Expression.Annotations.OfType<ILInstruction>().Where(AssignVariableNames.IsSupportedInstruction).FirstOrDefault())
AssignVariableNames.GenerateVariableName(function, type,
stmt.Expression.Annotations.OfType<ILInstruction>()
.Where(AssignVariableNames.IsSupportedInstruction).FirstOrDefault(),
mustResolveConflicts: true)
);
stmt.Expression = new AssignmentExpression(
new IdentifierExpression(v.Name).WithRR(new ILVariableResolveResult(v, v.Type)),

53
ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
};
ILTransformContext context;
string[] currentLowerCaseTypeOrMemberNames;
List<string> currentLowerCaseTypeOrMemberNames;
Dictionary<string, int> reservedVariableNames;
Dictionary<MethodDefinitionHandle, string> localFunctionMapping;
HashSet<ILVariable> loopCounters;
@ -63,7 +63,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -63,7 +63,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
this.context = context;
reservedVariableNames = new Dictionary<string, int>();
currentLowerCaseTypeOrMemberNames = CollectAllLowerCaseTypeOrMemberNames(function.Method.DeclaringTypeDefinition).ToArray();
currentLowerCaseTypeOrMemberNames = new List<string>();
var currentLowerCaseMemberNames = CollectAllLowerCaseMemberNames(function.Method.DeclaringTypeDefinition);
foreach (var name in currentLowerCaseMemberNames)
currentLowerCaseTypeOrMemberNames.Add(name);
var currentLowerCaseTypeNames = CollectAllLowerCaseTypeNames(function.Method.DeclaringTypeDefinition);
foreach (var name in currentLowerCaseTypeNames)
{
currentLowerCaseTypeOrMemberNames.Add(name);
AddExistingName(reservedVariableNames, name);
}
localFunctionMapping = new Dictionary<MethodDefinitionHandle, string>();
loopCounters = CollectLoopCounters(function);
foreach (var f in function.Descendants.OfType<ILFunction>())
@ -147,26 +156,27 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -147,26 +156,27 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
IEnumerable<string> CollectAllLowerCaseTypeOrMemberNames(ITypeDefinition type)
static IEnumerable<string> CollectAllLowerCaseMemberNames(ITypeDefinition type)
{
foreach (var item in type.GetMembers(m => IsLowerCase(m.Name)))
yield return item.Name;
}
static IEnumerable<string> CollectAllLowerCaseTypeNames(ITypeDefinition type)
{
foreach (var item in type.ParentModule.TopLevelTypeDefinitions)
{
if (item.Namespace != type.Namespace)
continue;
if (IsLowerCase(item.Name))
{
AddExistingName(reservedVariableNames, item.Name);
yield return item.Name;
}
}
}
static bool IsLowerCase(string name)
{
return name.Length > 0 && char.ToLower(name[0]) == name[0];
}
static bool IsLowerCase(string name)
{
return name.Length > 0 && char.ToLower(name[0]) == name[0];
}
bool IsSetOrEventAccessor(IMethod method)
@ -678,7 +688,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -678,7 +688,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return variableType;
}
static Dictionary<string, int> CollectReservedVariableNames(ILFunction function, ILVariable existingVariable)
static Dictionary<string, int> CollectReservedVariableNames(ILFunction function,
ILVariable existingVariable, bool mustResolveConflicts)
{
var reservedVariableNames = new Dictionary<string, int>();
var rootFunction = function.Ancestors.OfType<ILFunction>().Single(f => f.Parent == null);
@ -694,12 +705,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -694,12 +705,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms
AddExistingName(reservedVariableNames, v.Name);
}
}
foreach (var f in rootFunction.Method.DeclaringTypeDefinition.GetFields().Select(f => f.Name))
AddExistingName(reservedVariableNames, f);
if (mustResolveConflicts)
{
var memberNames = CollectAllLowerCaseMemberNames(function.Method.DeclaringTypeDefinition)
.Concat(CollectAllLowerCaseTypeNames(function.Method.DeclaringTypeDefinition));
foreach (var name in memberNames)
AddExistingName(reservedVariableNames, name);
}
return reservedVariableNames;
}
internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext, ILVariable existingVariable = null)
internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext,
ILVariable existingVariable = null, bool mustResolveConflicts = false)
{
if (function == null)
throw new ArgumentNullException(nameof(function));
@ -707,7 +724,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -707,7 +724,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
return existingVariable.Name;
}
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable);
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts);
string baseName = GetNameFromInstruction(valueContext);
if (string.IsNullOrEmpty(baseName))
@ -756,11 +773,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -756,11 +773,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
internal static string GenerateVariableName(ILFunction function, IType type, ILInstruction valueContext = null, ILVariable existingVariable = null)
internal static string GenerateVariableName(ILFunction function, IType type,
ILInstruction valueContext = null, ILVariable existingVariable = null,
bool mustResolveConflicts = false)
{
if (function == null)
throw new ArgumentNullException(nameof(function));
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable);
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts);
string baseName = valueContext != null ? GetNameFromInstruction(valueContext) ?? GetNameByType(type) : GetNameByType(type);
string proposedName = "obj";

Loading…
Cancel
Save