def analyser(self):
        
        mapASTSourceToLineNumbers = MapASTSourceToLineNumbers()
        print("\n<<<<<<<<<< Analyser: Tainted Variables >>>>>>>>>>")
        
        externalFunctions = AnalyseFunctionDefinition.getAllFunctionDefinitionsWithExternalVisibility()
        publicFunctions = AnalyseFunctionDefinition.getAllFunctionDefinitionsWithPublicVisibility()
        taintedFunctions = externalFunctions + publicFunctions

        taintedVariables = defaultdict(list)
        for function in taintedFunctions:
            taintFlow = TaintPropagate.getTaintPropagationForFunction(function)            
            for item in taintFlow:
                _in = MySet()
                _out = []
                if(item["in"] is not None):
                    for var in item["in"]._set:
                        if(AnalyseVariable.getVariableNameForId(var) != "Error"):
                            _in.add(AnalyseVariable.getVariableNameForId(var), item["in"].idToNodeMapping[var].src)
                if(item["out"] is not None):
                    for var in item["out"]._set:
                        if(AnalyseVariable.getVariableNameForId(var) != "Error"):
                            _out.append(AnalyseVariable.getVariableNameForId(var))

                print("At line: " + str(mapASTSourceToLineNumbers.getLine(int(item["src"].split(":",)[0]))))

                for var in _in._set:
                    print(" Incoming tainted variable: " + var + " defined at line:" + str(mapASTSourceToLineNumbers.getLine(int(_in.idToNodeMapping[var].split(":",)[0]))))
                print(" Outgoing tainted variables: " + str(_out))
                self.statsTaintedVariables.append({
                    "line":str(mapASTSourceToLineNumbers.getLine(int(item["src"].split(":",)[0]))),
                    "info":_out,
                })
 def analyser(self):
     mapASTSourceToLineNumbers = MapASTSourceToLineNumbers()
     print("\n<<<<<<<<<< Analyser: Contract Features >>>>>>>>>>")
     
     contracts = AnalyseContract.getAllContracts()
     for contract in contracts:
         self.statsContractDefinitions.append({
             "line":str(mapASTSourceToLineNumbers.getLine(int(contract.src.split(":",)[0]))),
             "info":"contract definition"
         })
         print("\n********** Contract Features **********")
         print("Contract definition: " + contract.name  + " at line:" + str(mapASTSourceToLineNumbers.getLine(int(contract.src.split(":",)[0]))))
     
     functionDefinitions = AnalyseFunctionDefinition.getAllFunctionDefinitions()
     for function in functionDefinitions:
         self.statsFunctionDefinitions.append({
             "line":str(mapASTSourceToLineNumbers.getLine(int(function.src.split(":",)[0]))),
             "info":"function definition"
         })
         print("\n********** Function Features **********")
         print("Function definition: " + function.name  + " at line:" + str(mapASTSourceToLineNumbers.getLine(int(function.src.split(":",)[0]))))
         if (function.isConstructor):
             self.statsConstructors.append({
                 "line":str(mapASTSourceToLineNumbers.getLine(int(function.src.split(":",)[0]))),
                 "info":"constructor definition"
             })
             print("Constructor")
         print("Visibility: " + function.visibility)
         print("State Mutability: " + function.stateMutability)
         if (AnalyseFunctionDefinition.isFallbackFunction(function)):
             self.statsFallbackFunctions.append({
                 "line":str(mapASTSourceToLineNumbers.getLine(int(function.src.split(":",)[0]))),
                 "info":"fallback definition"
             })
             print("Fallback function")
         if (AnalyseFunctionDefinition.isPayableFallbackFunction(function)):
             print("Payable Fallback function")
         modifiers = function.modifiers
         for modifier in modifiers:
             print("Modifier: " + modifier['modifierName']['name'])
                 
     variableDeclarations = AnalyseVariable.getAllVariables()
     for variable in variableDeclarations:
         self.statsVariableDeclarations.append({
             "line":str(mapASTSourceToLineNumbers.getLine(int(variable.src.split(":",)[0]))),
             "info":"variable declaration"
         })
         print("\n********** Variable Features **********")
         print("Variable declaration: " + variable.name  + " at line:" + str(mapASTSourceToLineNumbers.getLine(int(variable.src.split(":",)[0]))))
         if (variable.stateVariable):
             self.statsStateVariables.append({
                 "line":str(mapASTSourceToLineNumbers.getLine(int(variable.src.split(":",)[0]))),
                 "info":"state variable declaration"
             })
             print("State variable")
         else:
             if (variable.parent.nodeType == "FunctionDefinition"):
                 print("Function parameter")
             else:
                 print("Local variable")
 def test_functionFallback(self):
     parseAST = ParseAST()
     astFD = open("./tests/functionFallback.ast", "r")
     parseResults = parseAST.parse(astFD)
     functionFallbackCount = AnalyseFunctionDefinition.hasFallbackFunction()
     payableFunctionFallbackCount = AnalyseFunctionDefinition.hasPayableFallbackFunction(
     )
     self.assertEqual(functionFallbackCount, 1)
     self.assertEqual(payableFunctionFallbackCount, 0)
     astFD.close()
Exemple #4
0
 def test_functionDefinition(self):
     parseAST = ParseAST()
     astFD = open("./tests/functionDefinition.ast","r")
     parseResults = parseAST.parse(astFD)
     functionDefinitions = AnalyseFunctionDefinition.getAllFunctionDefinitions()
     for item in functionDefinitions:
         print("Function Definition Name: " + item)
     self.assertEqual(len(functionDefinitions), 2)
     functionDefinitionsPublicVisibility = AnalyseFunctionDefinition.getAllFunctionDefinitionsWithPublicVisibility()
     for item in functionDefinitionsPublicVisibility:
         print("Public Function Definition Name: " + item)
     self.assertEqual(len(functionDefinitionsPublicVisibility), 1)
     astFD.close()
 def test_functionConstructor(self):
     parseAST = ParseAST()
     astFD = open(self.testPath + ".ast", "r")
     parseResults = parseAST.parse(astFD)
     constructors = AnalyseFunctionDefinition.getAllConstructors()
     self.assertEqual(len(constructors), 1)
     astFD.close()
    def analyser(self):
        mapASTSourceToLineNumbers = MapASTSourceToLineNumbers()
        print("\n<<<<<<<<<< Analyser: Default Visibility >>>>>>>>>>")

        functionDefinitions = AnalyseFunctionDefinition.getAllFunctionDefinitions(
        )
        for function in functionDefinitions:
            if (function.visibility == "public"):
                # Determine if "public" visibility was explicitly specified or implicitly inferred
                # Check if "public" keyword is present between input parameters and return parameters
                parametersSrc = function.parameters.get("src")
                returnParametersSrc = function.returnParameters.get("src")
                found = mapASTSourceToLineNumbers.chkStringPresent(
                    "public", parametersSrc, returnParametersSrc)
                if (not found):
                    self.statsDefaultVisibilityForFunction.append({
                        "line":
                        str(
                            mapASTSourceToLineNumbers.getLine(
                                int(function.src.split(":", )[0]))),
                        "info":
                        "default public visibility for function"
                    })
                    print("Default public visibility for Function: " +
                          function.name + " at line:" + str(
                              mapASTSourceToLineNumbers.getLine(
                                  int(function.src.split(":", )[0]))))

        variableDeclarations = AnalyseVariable.getAllVariables()
        for variable in variableDeclarations:
            if (variable.visibility == "internal" and
                (not (variable.parent.nodeType == "FunctionDefinition"))):
                # Determine if "internal" visibility was explicitly specified or implicitly inferred
                # Check if "internal" keyword is present between type and variable name
                variableSrc = variable.src
                typeSrc = variable.typeName.get("src")
                found = mapASTSourceToLineNumbers.chkStringPresentVariableVisibility(
                    "internal", typeSrc, variableSrc)
                if (not found):
                    self.statsDefaultVisibilityForVariable.append({
                        "line":
                        str(
                            mapASTSourceToLineNumbers.getLine(
                                int(variable.src.split(":", )[0]))),
                        "info":
                        "default public visibility for variable"
                    })
                    print("Default internal visibility for Variable: " +
                          variable.name + " at line:" + str(
                              mapASTSourceToLineNumbers.getLine(
                                  int(variable.src.split(":", )[0]))))
    def analyser(self):
        mapASTSourceToLineNumbers = MapASTSourceToLineNumbers()
        print("\n<<<<<<<<<< Analyser: Defs and Uses >>>>>>>>>>")
        
        functionDefinitions = AnalyseFunctionDefinition.getAllFunctionDefinitions()

        for function in functionDefinitions:
            print("\n********** Function Defs/Uses **********")
            print("Function definition: " + function.name  + " at line:" + str(mapASTSourceToLineNumbers.getLine(int(function.src.split(":",)[0]))))
            dataflow = DefUseAnalysis.getDataflowForFunction(function)
            if (self.loggingLevel == "DEBUG"):
                print("Dataflow length: " + str(len(dataflow)))
                for item in dataflow:
                    _gen = []
                    _kill = []
                    _in = MySet()
                    _out = []
                    if(item["gen"] is not None and item["gen"]._set is not None):
                        for var in item["gen"]._set:
                            if(AnalyseVariable.getVariableNameForId(var) != "Error"):
                                _gen.append(AnalyseVariable.getVariableNameForId(var))
                    if(item["kill"] is not None):
                        for var in item["kill"]._set:
                            if(AnalyseVariable.getVariableNameForId(var) != "Error"):
                                _kill.append(AnalyseVariable.getVariableNameForId(var))
                    if(item["in"] is not None):
                        for var in item["in"]._set:
                            if(AnalyseVariable.getVariableNameForId(var) != "Error"):
                                _in.add(AnalyseVariable.getVariableNameForId(var), item["in"].idToNodeMapping[var].src)
                    if(item["out"] is not None):
                        for var in item["out"]._set:
                            if(AnalyseVariable.getVariableNameForId(var) != "Error"):
                                _out.append(AnalyseVariable.getVariableNameForId(var))
                    print("Node Id: " +
                          str(item["id"]) + 
                          " at line:" +
                          str(mapASTSourceToLineNumbers.getLine(int(item["src"].split(":",)[0]))) +
                          " gen: " + str(_gen) +
                          " kill: " + str(_kill)
                    )
                
                for var in _in._set:
                    print("in: " + var + " defined at line:" + str(mapASTSourceToLineNumbers.getLine(int(_in.idToNodeMapping[var].split(":",)[0]))))
                print(" out: " + str(_out))


            defs = []
            defs = DefUseAnalysis.getAllDefsAtNode(function, defs)
            for _def in defs:
                self.statsDefs.append({
                    "line":str(mapASTSourceToLineNumbers.getLine(int(_def["src"].split(":",)[0]))),
                    "info":_def["name"]
                })
                if(self.loggingLevel == "DEBUG"):
                    print("Def: " + _def["name"] + " at line:" + str(mapASTSourceToLineNumbers.getLine(int(_def["src"].split(":",)[0]))))
            
            uses = []
            uses = DefUseAnalysis.getAllUsesAtNode(function, uses)
            for use in uses:
                self.statsUses.append({
                    "line":str(mapASTSourceToLineNumbers.getLine(int(use["src"].split(":",)[0]))),
                    "info":use["name"]
                })
                print("Use: " +
                      use["name"] +
                      " at line:" + str(mapASTSourceToLineNumbers.getLine(int(use["src"].split(":",)[0]))))
                print(" > Using value from definition on line: ",end='')
                line = mapASTSourceToLineNumbers.getLine(int(use["src"].split(":",)[0]))
                varRef = use["referencedDeclaration"]
                found = False
                for item in dataflow:
                    if(mapASTSourceToLineNumbers.getLine(int(item["src"].split(":",)[0])) == line):
                        if(item["in"] and varRef in item["in"]._set):
                            print(mapASTSourceToLineNumbers.getLine(int(item["in"].idToNodeMapping[varRef].src.split(":",)[0])))
                            found = True
                            break
                if(not found):
                    print("Not Found")