示例#1
0
        /// <summary>
        /// For arguments passed by reference: it assignes new values, and copies flags form inputValues.
        /// </summary>
        /// <param name="flow">FlowController</param>
        /// <param name="inputValues">Input values into analyzed function</param>
        /// <param name="nativeFunctions">Info about analyzed function</param>
        /// <returns>List of assigned values into aliases</returns>
        public static List <Value> ResolveAliasArguments(FlowController flow, List <Value> inputValues, List <NativeFunction> nativeFunctions)
        {
            List <Value> result        = new List <Value>();
            MemoryEntry  argc          = flow.InSet.ReadVariable(new VariableIdentifier(".argument_count")).ReadMemory(flow.OutSet.Snapshot);
            int          argumentCount = ((IntegerValue)argc.PossibleValues.ElementAt(0)).Value;

            foreach (var nativeFunction in nativeFunctions)
            {
                if (nativeFunction.MinArgumentCount <= argumentCount && nativeFunction.MaxArgumentCount >= argumentCount)
                {
                    int functionArgumentNumber = 0;
                    for (int i = 0; i < argumentCount; i++)
                    {
                        MemoryEntry arg = flow.InSet.ReadVariable(Argument(i)).ReadMemory(flow.InSet.Snapshot);

                        NativeFunctionArgument functionArgument = nativeFunction.Arguments.ElementAt(functionArgumentNumber);
                        if (functionArgument.ByReference == true)
                        {
                            MemoryEntry res = NativeAnalyzerUtils.ResolveReturnValue(functionArgument.Type, flow);
                            res = new MemoryEntry(FlagsHandler.CopyFlags(inputValues, res.PossibleValues));
                            flow.OutSet.GetVariable(Argument(i)).WriteMemory(flow.OutSet.Snapshot, res);
                            result.AddRange(res.PossibleValues);
                        }


                        //incremeneting functionArgumentNumber
                        if (nativeFunction.Arguments.ElementAt(functionArgumentNumber).Dots == false)
                        {
                            functionArgumentNumber++;
                        }
                    }
                }
            }
            return(result);
        }
示例#2
0
        /// <summary>
        /// Checks arguments in functions and generates warning if the arguments don't match.
        /// </summary>
        /// <param name="flow">FlowController</param>
        /// <param name="nativeFunctions">nativeFunctions</param>
        public static void checkArgumentTypes(FlowController flow, List <NativeFunction> nativeFunctions)
        {
            List <List <AnalysisWarning> > warningsList = new List <List <AnalysisWarning> >();
            MemoryEntry argc          = flow.InSet.ReadVariable(new VariableIdentifier(".argument_count")).ReadMemory(flow.OutSet.Snapshot);
            int         argumentCount = ((IntegerValue)argc.PossibleValues.ElementAt(0)).Value;

            foreach (var nativeFunction in nativeFunctions)
            {
                if (nativeFunction.MinArgumentCount <= argumentCount && nativeFunction.MaxArgumentCount >= argumentCount)
                {
                    warningsList.Add(new List <AnalysisWarning>());
                    int functionArgumentNumber = 0;
                    for (int i = 0; i < argumentCount; i++)
                    {
                        MemoryEntry arg = flow.InSet.ReadVariable(Argument(i)).ReadMemory(flow.InSet.Snapshot);

                        NativeFunctionArgument functionArgument = nativeFunction.Arguments.ElementAt(functionArgumentNumber);

                        CheckArgumentTypes(flow, arg, functionArgument, i + 1, nativeFunctions.ElementAt(0).Name.ToString(), warningsList.Last());

                        //incremeneting functionArgumentNumber
                        if (nativeFunction.Arguments.ElementAt(functionArgumentNumber).Dots == false)
                        {
                            functionArgumentNumber++;
                        }
                    }
                }
            }
            int index_min = -1;
            int value_min = int.MaxValue;

            for (int i = 0; i < warningsList.Count; i++)
            {
                if (warningsList[i].Count < value_min)
                {
                    value_min = warningsList[i].Count;
                    index_min = i;
                }
            }
            foreach (AnalysisWarning warning in warningsList[index_min])
            {
                AnalysisWarningHandler.SetWarning(flow.OutSet, warning);
            }
        }
示例#3
0
        /// <summary>
        /// Check type of one argument and reports warnings if they doesn't match.
        /// </summary>
        /// <param name="flow">FlowController</param>
        /// <param name="memoryEntry">Values of argument</param>
        /// <param name="argument">Information about argument</param>
        /// <param name="argumentNumber">Number of argument</param>
        /// <param name="functionName">Name of function</param>
        /// <param name="warnings">List of warnings, for inserting warnings</param>
        private static void CheckArgumentTypes(FlowController flow, MemoryEntry memoryEntry, NativeFunctionArgument argument, int argumentNumber, string functionName, List <AnalysisWarning> warnings)
        {
            bool argumentMatches = true;

            foreach (Value value in memoryEntry.PossibleValues)
            {
                if (value is AnyValue || value is UndefinedValue)
                {
                    continue;
                }

                switch (argument.Type)
                {
                case "mixed":
                    break;

                case "int":
                case "integer":
                    //TODO: workaround: type declarations in .xml files specifies the arguments that should be of type number by type int
                    // fix declarations in xml files!!
                    //if (!(ValueTypeResolver.IsInt(value) || ValueTypeResolver.IsLong(value)))
                    if (!(ValueTypeResolver.IsInt(value) || ValueTypeResolver.IsLong(value) || ValueTypeResolver.IsFloat(value)))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "float":
                case "number":
                    if (!(ValueTypeResolver.IsInt(value) || ValueTypeResolver.IsLong(value) || ValueTypeResolver.IsFloat(value)))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "string":
                case "char":
                    if (!ValueTypeResolver.IsString(value))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "array":
                    if (!ValueTypeResolver.IsArray(value))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "object":
                    if (!ValueTypeResolver.IsObject(value))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "bool":
                case "boolean":
                    if (!ValueTypeResolver.IsBool(value))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "resource":
                case "resouce":
                    if (!(value is AnyResourceValue))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "callable":
                case "callback":
                    if (!ValueTypeResolver.IsString(value) && !(value is FunctionValue))
                    {
                        argumentMatches = false;
                    }
                    break;

                case "void":
                    throw new Exception("Void is not a type of argument");

                default:
                    if (!ValueTypeResolver.IsObject(value))
                    {
                        argumentMatches = false;
                    }
                    break;
                }
            }
            if (argumentMatches == false)
            {
                warnings.Add(new AnalysisWarning(NativeAnalyzerUtils.GetCallerScript(flow.OutSet), "Wrong type of argument number " + argumentNumber + " in function " + functionName + ", expecting " + argument.Type, flow.CurrentPartial, flow.CurrentProgramPoint, AnalysisWarningCause.WRONG_ARGUMENTS_TYPE));
            }
        }