private bool IsAssignmentToConcreteType(StackAnalysisResult stackAnalysis)
        {
            TypeReference assignmentTargetType;

            if (InstrumentationUtil.IsCallInstruction(stackAnalysis.Consumer))
            {
                assignmentTargetType = stackAnalysis.AssignedParameter().ParameterType;
            }
            else
            {
                FieldReference assignmentTarget = stackAnalysis.Consumer.Operand as FieldReference;
                if (assignmentTarget != null)
                {
                    assignmentTargetType = assignmentTarget.FieldType;
                }
                else
                {
                    VariableReference variableDefinition = stackAnalysis.Consumer.Operand as VariableReference;
                    if (variableDefinition != null)
                    {
                        assignmentTargetType = variableDefinition.VariableType;
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                }
            }
            return(HasReplacement(assignmentTargetType.GetElementType().FullName));
        }
Пример #2
0
        public void TestStackAnalysisResult()
        {
            AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(GetType().Module.Assembly.Location);

            Type testsDeclaringType = typeof(StackAnalysisResultScenarios);

            StringBuilder sb = new StringBuilder();

            foreach (MethodInfo testMethod in testsDeclaringType.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
            {
                try
                {
                    MethodDefinition methodDefinition             = MethodReferenceFor(testMethod, assembly).Resolve();
                    ExpectedStackAnalysisResultAttribute expected = ExpectedStackAnalysisResultFor(testMethod);
                    StackAnalysisResult actual = StackAnalyzer.IsConsumedBy(IsMethodCallOnList, FindCastOrNewObj(methodDefinition), methodDefinition.DeclaringType.Module);

                    Assert.AreEqual(expected.OpCode, actual.Consumer.OpCode.ToString());
                    Assert.AreEqual(expected.Offset, actual.Offset);
                    Assert.AreEqual(expected.StackHeight, actual.StackHeight);
                    Assert.AreEqual(expected.Match, true);
                }
                catch (Exception ex)
                {
                    sb.AppendFormat("Exception while processing method {0}\r\n{1}", testMethod, ex);
                }
            }

            if (sb.Length > 0)
            {
                Assert.Fail(sb.ToString());
            }
        }
Пример #3
0
        private bool IsAssignmentToConcreteType(StackAnalysisResult analysisResult)
        {
            TypeReference assignmentTargetType;

            if (analysisResult.Consumer.IsNewObj() || analysisResult.Consumer.IsCall())
            {
                assignmentTargetType = analysisResult.AssignedParameter().ParameterType;
            }
            else
            {
                var assignmentTarget = analysisResult.Consumer.Operand as FieldReference;
                if (assignmentTarget != null)
                {
                    assignmentTargetType = assignmentTarget.FieldType;
                }
                else
                {
                    var variableDefinition = analysisResult.Consumer.Operand as VariableReference;
                    if (variableDefinition != null)
                    {
                        assignmentTargetType = variableDefinition.VariableType;
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                }
            }
            return(HasReplacement(assignmentTargetType.GetElementType().FullName));
        }
        private void InstrumentConcreteCollectionCasts(MethodDefinition methodDefinition)
        {
            foreach (Instruction cast in CastsToSupportedCollections(methodDefinition.Body))
            {
                StackAnalysisResult result = StackAnalyzer.IsConsumedBy(MethodCallOnSupportedCollections, cast, methodDefinition.DeclaringType.Module);
                if (!result.Match)
                {
                    throw new InvalidOperationException(string.Format("Error: [{0}] Invalid use of cast result: '{1}'.\r\nCasts to {2} are only allowed for property access/method calls.", methodDefinition, DebugInformation.InstructionInformationFor(result.Consumer, methodDefinition.Body.Instructions), cast.Operand));
                }

                TypeReference castTarget = (TypeReference)cast.Operand;
                ReplaceCastAndCalleeDeclaringType(cast, result.Consumer, _collectionReplacements[castTarget.Resolve().FullName]);
            }
        }
        private void InstrumentCollectionInstantiation(MethodDefinition methodDefinition)
        {
            foreach (Instruction newObj in TAEnabledCollectionInstantiations(methodDefinition.Body))
            {
                StackAnalysisResult stackAnalysis = StackAnalyzer.IsConsumedBy(delegate { return(true); }, newObj, methodDefinition.DeclaringType.Module);
                if (IsAssignmentToConcreteType(stackAnalysis))
                {
                    Context.TraceWarning("[{0}] Assignment to concrete collection {1} ignored (offset: 0x{2:X2}).", methodDefinition, InstantiatedType(newObj), newObj.Next.Offset);
                    continue;
                }

                ReplaceContructorWithConstructorFrom(newObj);
            }
        }
        private void AssertStack(Type testsDeclaringType, bool expectedResult)
        {
            TypeReference typeReference = FindType(testsDeclaringType);

            StringBuilder sb = new StringBuilder();

            foreach (MethodReference testMethod in typeReference.Resolve().Methods)
            {
                MethodDefinition methodDefinition = testMethod.Resolve();
                if (!methodDefinition.IsPublic)
                {
                    continue;
                }
                if (methodDefinition.IsConstructor)
                {
                    continue;
                }

                try
                {
                    StackAnalysisResult stackAnalysis = StackAnalyzer.IsConsumedBy(IsMethodCallOnList, FindCast(methodDefinition), methodDefinition.DeclaringType.Module);
                    if (expectedResult != stackAnalysis.Match)
                    {
                        sb.AppendFormat("Method {0} contains invalid cast operations.\r\n", testMethod);
                    }
                }
                catch (Exception ex)
                {
                    sb.AppendFormat("Exception while processing method {0}\r\n{1}", testMethod, ex);
                }
            }

            if (sb.Length > 0)
            {
                Assert.Fail(sb.ToString());
            }
        }