def _parse_contracts_from_json(self, json_data): first = json_data.find('{') if first != -1: last = json_data.rfind('}') + 1 filename = json_data[0:first] json_data = json_data[first:last] data_loaded = json.loads(json_data) if data_loaded['name'] == 'root': self._solc_version = '0.3' logger.error('solc <0.4 is not supported') exit(-1) elif data_loaded['name'] == 'SourceUnit': self._solc_version = '0.4' self._parse_source_unit(data_loaded, filename) else: logger.error('solc version is not supported') exit(-1) for contract_data in data_loaded['children']: # if self.solc_version == '0.3': # assert contract_data['name'] == 'Contract' # contract = ContractSolc03(self, contract_data) if self.solc_version == '0.4': assert contract_data['name'] in [ 'ContractDefinition', 'PragmaDirective', 'ImportDirective' ] if contract_data['name'] == 'ContractDefinition': contract = ContractSolc04(self, contract_data) if 'src' in contract_data: contract.set_offset(contract_data['src'], self) self._contractsNotParsed.append(contract) elif contract_data['name'] == 'PragmaDirective': pragma = Pragma( contract_data['attributes']["literals"]) pragma.set_offset(contract_data['src'], self) self._pragma_directives.append(pragma) elif contract_data['name'] == 'ImportDirective': import_directive = Import( contract_data['attributes']["absolutePath"]) import_directive.set_offset(contract_data['src'], self) self._import_directives.append(import_directive) return True return False
def _parse_contracts_from_loaded_json(self, data_loaded, filename): if 'nodeType' in data_loaded: self._is_compact_ast = True if 'sourcePaths' in data_loaded: for sourcePath in data_loaded['sourcePaths']: if os.path.isfile(sourcePath): with open(sourcePath, encoding='utf8') as f: source_code = f.read() self.source_code[sourcePath] = source_code if data_loaded[self.get_key()] == 'root': self._solc_version = '0.3' logger.error('solc <0.4 is not supported') return elif data_loaded[self.get_key()] == 'SourceUnit': self._solc_version = '0.4' self._parse_source_unit(data_loaded, filename) else: logger.error('solc version is not supported') return for contract_data in data_loaded[self.get_children()]: # if self.solc_version == '0.3': # assert contract_data[self.get_key()] == 'Contract' # contract = ContractSolc03(self, contract_data) if self.solc_version == '0.4': assert contract_data[self.get_key()] in [ 'ContractDefinition', 'PragmaDirective', 'ImportDirective' ] if contract_data[self.get_key()] == 'ContractDefinition': contract = ContractSolc04(self, contract_data) if 'src' in contract_data: contract.set_offset(contract_data['src'], self) self._contractsNotParsed.append(contract) elif contract_data[self.get_key()] == 'PragmaDirective': if self._is_compact_ast: pragma = Pragma(contract_data['literals']) else: pragma = Pragma( contract_data['attributes']["literals"]) pragma.set_offset(contract_data['src'], self) self._pragma_directives.append(pragma) elif contract_data[self.get_key()] == 'ImportDirective': if self.is_compact_ast: import_directive = Import( contract_data["absolutePath"]) else: import_directive = Import( contract_data['attributes']["absolutePath"]) import_directive.set_offset(contract_data['src'], self) self._import_directives.append(import_directive)
def parse_contracts_from_loaded_json( self, data_loaded: Dict, filename: str ): # pylint: disable=too-many-branches if "nodeType" in data_loaded: self._is_compact_ast = True if "sourcePaths" in data_loaded: for sourcePath in data_loaded["sourcePaths"]: if os.path.isfile(sourcePath): self._core.add_source_code(sourcePath) if data_loaded[self.get_key()] == "root": self._core.solc_version = "0.3" logger.error("solc <0.4 is not supported") return if data_loaded[self.get_key()] == "SourceUnit": self._core.solc_version = "0.4" self._parse_source_unit(data_loaded, filename) else: logger.error("solc version is not supported") return for contract_data in data_loaded[self.get_children()]: assert contract_data[self.get_key()] in [ "ContractDefinition", "PragmaDirective", "ImportDirective", "StructDefinition", "EnumDefinition", ] if contract_data[self.get_key()] == "ContractDefinition": contract = Contract() contract_parser = ContractSolc(self, contract, contract_data) if "src" in contract_data: contract.set_offset(contract_data["src"], self._core) self._underlying_contract_to_parser[contract] = contract_parser elif contract_data[self.get_key()] == "PragmaDirective": if self._is_compact_ast: pragma = Pragma(contract_data["literals"]) else: pragma = Pragma(contract_data["attributes"]["literals"]) pragma.set_offset(contract_data["src"], self._core) self._core.pragma_directives.append(pragma) elif contract_data[self.get_key()] == "ImportDirective": if self.is_compact_ast: import_directive = Import(contract_data["absolutePath"]) else: import_directive = Import(contract_data["attributes"].get("absolutePath", "")) import_directive.set_offset(contract_data["src"], self._core) self._core.import_directives.append(import_directive) elif contract_data[self.get_key()] in [ "StructDefinition", "EnumDefinition", ]: # This can only happen for top-level structure and enum # They were introduced with 0.6.5 assert self._is_compact_ast # Do not support top level definition for legacy AST fake_contract_data = { "name": f"SlitherInternalTopLevelContract{self._top_level_contracts_counter}", "id": -1000 + self._top_level_contracts_counter, # TODO: determine if collission possible "linearizedBaseContracts": [], "fullyImplemented": True, "contractKind": "SLitherInternal", } self._top_level_contracts_counter += 1 contract = Contract() top_level_contract = ContractSolc(self, contract, fake_contract_data) contract.is_top_level = True contract.set_offset(contract_data["src"], self._core) if contract_data[self.get_key()] == "StructDefinition": top_level_contract.structures_not_parsed.append( contract_data ) # Todo add proper setters else: top_level_contract.enums_not_parsed.append( contract_data ) # Todo add proper setters self._underlying_contract_to_parser[contract] = top_level_contract
def parse_top_level_from_loaded_json( self, data_loaded: Dict, filename: str ): # pylint: disable=too-many-branches,too-many-statements if "nodeType" in data_loaded: self._is_compact_ast = True if "sourcePaths" in data_loaded: for sourcePath in data_loaded["sourcePaths"]: if os.path.isfile(sourcePath): self._compilation_unit.core.add_source_code(sourcePath) if data_loaded[self.get_key()] == "root": logger.error("solc <0.4 is not supported") return if data_loaded[self.get_key()] == "SourceUnit": self._parse_source_unit(data_loaded, filename) else: logger.error("solc version is not supported") return for top_level_data in data_loaded[self.get_children()]: if top_level_data[self.get_key()] == "ContractDefinition": contract = Contract(self._compilation_unit) contract_parser = ContractSolc(self, contract, top_level_data) if "src" in top_level_data: contract.set_offset(top_level_data["src"], self._compilation_unit) self._underlying_contract_to_parser[contract] = contract_parser elif top_level_data[self.get_key()] == "PragmaDirective": if self._is_compact_ast: pragma = Pragma(top_level_data["literals"]) else: pragma = Pragma(top_level_data["attributes"]["literals"]) pragma.set_offset(top_level_data["src"], self._compilation_unit) self._compilation_unit.pragma_directives.append(pragma) elif top_level_data[self.get_key()] == "ImportDirective": if self.is_compact_ast: import_directive = Import(top_level_data["absolutePath"]) # TODO investigate unitAlias in version < 0.7 and legacy ast if "unitAlias" in top_level_data: import_directive.alias = top_level_data["unitAlias"] else: import_directive = Import(top_level_data["attributes"].get("absolutePath", "")) import_directive.set_offset(top_level_data["src"], self._compilation_unit) self._compilation_unit.import_directives.append(import_directive) elif top_level_data[self.get_key()] == "StructDefinition": st = StructureTopLevel() st.set_offset(top_level_data["src"], self._compilation_unit) st_parser = StructureTopLevelSolc(st, top_level_data, self) self._compilation_unit.structures_top_level.append(st) self._structures_top_level_parser.append(st_parser) elif top_level_data[self.get_key()] == "EnumDefinition": # Note enum don't need a complex parser, so everything is directly done self._parse_enum(top_level_data) elif top_level_data[self.get_key()] == "VariableDeclaration": var = TopLevelVariable() var_parser = TopLevelVariableSolc(var, top_level_data) var.set_offset(top_level_data["src"], self._compilation_unit) self._compilation_unit.variables_top_level.append(var) self._variables_top_level_parser.append(var_parser) elif top_level_data[self.get_key()] == "FunctionDefinition": func = FunctionTopLevel(self._compilation_unit) func_parser = FunctionSolc(func, top_level_data, None, self) self._compilation_unit.functions_top_level.append(func) self._functions_top_level_parser.append(func_parser) self.add_function_or_modifier_parser(func_parser) else: raise SlitherException(f"Top level {top_level_data[self.get_key()]} not supported")
def parse_top_level_from_loaded_json(self, data_loaded: Dict, filename: str): # pylint: disable=too-many-branches,too-many-statements,too-many-locals if "nodeType" in data_loaded: self._is_compact_ast = True if "sourcePaths" in data_loaded: for sourcePath in data_loaded["sourcePaths"]: if os.path.isfile(sourcePath): self._compilation_unit.core.add_source_code(sourcePath) if data_loaded[self.get_key()] == "root": logger.error("solc <0.4 is not supported") return if data_loaded[self.get_key()] == "SourceUnit": self._parse_source_unit(data_loaded, filename) else: logger.error("solc version is not supported") return if self.get_children() not in data_loaded: return scope = self.compilation_unit.get_scope(filename) for top_level_data in data_loaded[self.get_children()]: if top_level_data[self.get_key()] == "ContractDefinition": contract = Contract(self._compilation_unit, scope) contract_parser = ContractSolc(self, contract, top_level_data) scope.contracts[contract.name] = contract if "src" in top_level_data: contract.set_offset(top_level_data["src"], self._compilation_unit) self._underlying_contract_to_parser[contract] = contract_parser elif top_level_data[self.get_key()] == "PragmaDirective": if self._is_compact_ast: pragma = Pragma(top_level_data["literals"], scope) scope.pragmas.add(pragma) else: pragma = Pragma(top_level_data["attributes"]["literals"], scope) scope.pragmas.add(pragma) pragma.set_offset(top_level_data["src"], self._compilation_unit) self._compilation_unit.pragma_directives.append(pragma) elif top_level_data[self.get_key()] == "ImportDirective": if self.is_compact_ast: import_directive = Import( Path(top_level_data["absolutePath"], ), scope, ) scope.imports.add(import_directive) # TODO investigate unitAlias in version < 0.7 and legacy ast if "unitAlias" in top_level_data: import_directive.alias = top_level_data["unitAlias"] if "symbolAliases" in top_level_data: symbol_aliases = top_level_data["symbolAliases"] _handle_import_aliases(symbol_aliases, import_directive, scope) else: import_directive = Import( Path( top_level_data["attributes"].get( "absolutePath", ""), ), scope, ) scope.imports.add(import_directive) # TODO investigate unitAlias in version < 0.7 and legacy ast if ("attributes" in top_level_data and "unitAlias" in top_level_data["attributes"]): import_directive.alias = top_level_data["attributes"][ "unitAlias"] import_directive.set_offset(top_level_data["src"], self._compilation_unit) self._compilation_unit.import_directives.append( import_directive) get_imported_scope = self.compilation_unit.get_scope( import_directive.filename) scope.accessible_scopes.append(get_imported_scope) elif top_level_data[self.get_key()] == "StructDefinition": scope = self.compilation_unit.get_scope(filename) st = StructureTopLevel(self.compilation_unit, scope) st.set_offset(top_level_data["src"], self._compilation_unit) st_parser = StructureTopLevelSolc(st, top_level_data, self) scope.structures[st.name] = st self._compilation_unit.structures_top_level.append(st) self._structures_top_level_parser.append(st_parser) elif top_level_data[self.get_key()] == "EnumDefinition": # Note enum don't need a complex parser, so everything is directly done self._parse_enum(top_level_data, filename) elif top_level_data[self.get_key()] == "VariableDeclaration": var = TopLevelVariable(scope) var_parser = TopLevelVariableSolc(var, top_level_data, self) var.set_offset(top_level_data["src"], self._compilation_unit) self._compilation_unit.variables_top_level.append(var) self._variables_top_level_parser.append(var_parser) scope.variables[var.name] = var elif top_level_data[self.get_key()] == "FunctionDefinition": scope = self.compilation_unit.get_scope(filename) func = FunctionTopLevel(self._compilation_unit, scope) scope.functions.add(func) func.set_offset(top_level_data["src"], self._compilation_unit) func_parser = FunctionSolc(func, top_level_data, None, self) self._compilation_unit.functions_top_level.append(func) self._functions_top_level_parser.append(func_parser) self.add_function_or_modifier_parser(func_parser) elif top_level_data[self.get_key()] == "ErrorDefinition": scope = self.compilation_unit.get_scope(filename) custom_error = CustomErrorTopLevel(self._compilation_unit, scope) custom_error.set_offset(top_level_data["src"], self._compilation_unit) custom_error_parser = CustomErrorSolc(custom_error, top_level_data, self) scope.custom_errors.add(custom_error) self._compilation_unit.custom_errors.append(custom_error) self._custom_error_parser.append(custom_error_parser) elif top_level_data[ self.get_key()] == "UserDefinedValueTypeDefinition": assert "name" in top_level_data alias = top_level_data["name"] assert "underlyingType" in top_level_data underlying_type = top_level_data["underlyingType"] assert ("nodeType" in underlying_type and underlying_type["nodeType"] == "ElementaryTypeName") assert "name" in underlying_type original_type = ElementaryType(underlying_type["name"]) user_defined_type = TypeAliasTopLevel(original_type, alias, scope) user_defined_type.set_offset(top_level_data["src"], self._compilation_unit) scope.user_defined_types[alias] = user_defined_type else: raise SlitherException( f"Top level {top_level_data[self.get_key()]} not supported" )
def _parse_contracts_from_loaded_json(self, data_loaded, filename): if 'nodeType' in data_loaded: self._is_compact_ast = True if 'sourcePaths' in data_loaded: for sourcePath in data_loaded['sourcePaths']: if os.path.isfile(sourcePath): self._add_source_code(sourcePath) if data_loaded[self.get_key()] == 'root': self._solc_version = '0.3' logger.error('solc <0.4 is not supported') return elif data_loaded[self.get_key()] == 'SourceUnit': self._solc_version = '0.4' self._parse_source_unit(data_loaded, filename) else: logger.error('solc version is not supported') return for contract_data in data_loaded[self.get_children()]: assert contract_data[self.get_key()] in [ 'ContractDefinition', 'PragmaDirective', 'ImportDirective', 'StructDefinition', 'EnumDefinition' ] if contract_data[self.get_key()] == 'ContractDefinition': contract = ContractSolc04(self, contract_data) if 'src' in contract_data: contract.set_offset(contract_data['src'], self) self._contractsNotParsed.append(contract) elif contract_data[self.get_key()] == 'PragmaDirective': if self._is_compact_ast: pragma = Pragma(contract_data['literals']) else: pragma = Pragma(contract_data['attributes']["literals"]) pragma.set_offset(contract_data['src'], self) self._pragma_directives.append(pragma) elif contract_data[self.get_key()] == 'ImportDirective': if self.is_compact_ast: import_directive = Import(contract_data["absolutePath"]) else: import_directive = Import( contract_data['attributes']["absolutePath"]) import_directive.set_offset(contract_data['src'], self) self._import_directives.append(import_directive) elif contract_data[self.get_key()] in [ 'StructDefinition', 'EnumDefinition' ]: # This can only happen for top-level structure and enum # They were introduced with 0.6.5 assert self._is_compact_ast # Do not support top level definition for legacy AST fake_contract_data = { 'name': f'SlitherInternalTopLevelContract{self._top_level_contracts_counter}', 'id': -1000, # TODO: determine if collission possible 'linearizedBaseContracts': [], 'fullyImplemented': True, 'contractKind': 'SLitherInternal' } self._top_level_contracts_counter += 1 top_level_contract = ContractSolc04(self, fake_contract_data) top_level_contract.is_top_level = True top_level_contract.set_offset(contract_data['src'], self) if contract_data[self.get_key()] == 'StructDefinition': top_level_contract._structuresNotParsed.append( contract_data) # Todo add proper setters else: top_level_contract._enumsNotParsed.append( contract_data) # Todo add proper setters self._contractsNotParsed.append(top_level_contract)