-Added `additional_fields` field to JSON result + element output

-Added event/struct/enum JSON output functions
-Cleaned up node json output
-Standardized naming-convention detector output
pull/226/head
David Pokora 6 years ago
parent 0fd77f9042
commit 89b0dd417e
No known key found for this signature in database
GPG Key ID: 3CED48D1BB21BDD7
  1. 63
      slither/detectors/abstract_detector.py
  2. 101
      slither/detectors/naming_convention/naming_convention.py
  3. 4
      slither/detectors/shadowing/builtin_symbols.py

@ -140,20 +140,30 @@ class AbstractDetector(metaclass=abc.ABCMeta):
def color(self):
return classification_colors[self.IMPACT]
def generate_json_result(self, info):
def generate_json_result(self, info, additional_fields={}):
d = OrderedDict()
d['check'] = self.ARGUMENT
d['impact'] = classification_txt[self.IMPACT]
d['confidence'] = classification_txt[self.CONFIDENCE]
d['description'] = info
d['elements'] = []
if additional_fields:
d['additional_fields'] = additional_fields
return d
@staticmethod
def add_variable_to_json(variable, d):
d['elements'].append({'type': 'variable',
'name': variable.name,
'source_mapping': variable.source_mapping})
def _create_base_element(type, name, source_mapping, additional_fields={}):
element = {'type': type,
'name': name,
'source_mapping': source_mapping}
if additional_fields:
element['additional_fields'] = additional_fields
return element
@staticmethod
def add_variable_to_json(variable, d, additional_fields={}):
element = AbstractDetector._create_base_element('variable', variable.name, variable.source_mapping, additional_fields)
d['elements'].append(element)
@staticmethod
def add_variables_to_json(variables, d):
@ -161,29 +171,48 @@ class AbstractDetector(metaclass=abc.ABCMeta):
AbstractDetector.add_variable_to_json(variable, d)
@staticmethod
def add_contract_to_json(contract, d):
d['elements'].append({'type': 'contract',
'name': contract.name,
'source_mapping': contract.source_mapping})
def add_contract_to_json(contract, d, additional_fields={}):
element = AbstractDetector._create_base_element('contract', contract.name, contract.source_mapping, additional_fields)
d['elements'].append(element)
@staticmethod
def add_function_to_json(function, d):
def add_function_to_json(function, d, additional_fields={}):
contract = {'elements':[]}
AbstractDetector.add_contract_to_json(function.contract, contract)
d['elements'].append({'type': 'function',
'name': function.name,
'source_mapping': function.source_mapping,
'contract': contract['elements'][0]})
element = AbstractDetector._create_base_element('function', function.name, function.source_mapping, additional_fields)
element['contract'] = contract['elements'][0]
d['elements'].append(element)
@staticmethod
def add_functions_to_json(functions, d):
for function in sorted(functions, key=lambda x: x.name):
AbstractDetector.add_function_to_json(function, d)
@staticmethod
def add_enum_to_json(enum, d, additional_fields={}):
element = AbstractDetector._create_base_element('enum', enum.name, enum.source_mapping, additional_fields)
d['elements'].append(element)
@staticmethod
def add_struct_to_json(struct, d, additional_fields={}):
element = AbstractDetector._create_base_element('struct', struct.name, struct.source_mapping, additional_fields)
d['elements'].append(element)
@staticmethod
def add_event_to_json(event, d, additional_fields={}):
contract = {'elements':[]}
AbstractDetector.add_contract_to_json(event.contract, contract)
element = AbstractDetector._create_base_element('event', event.name, event.source_mapping, additional_fields)
element['contract'] = contract['elements'][0]
d['elements'].append(element)
@staticmethod
def add_node_to_json(node, d, additional_fields={}):
element = AbstractDetector._create_base_element('expression', str(node.expression), node.source_mapping, additional_fields)
d['elements'].append(element)
@staticmethod
def add_nodes_to_json(nodes, d):
for node in sorted(nodes, key=lambda x: x.node_id):
d['elements'].append({'type': 'expression',
'expression': str(node.expression),
'source_mapping': node.source_mapping})
AbstractDetector.add_node_to_json(node, d)

@ -61,12 +61,10 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
contract.source_mapping_str)
json = self.generate_json_result(info)
elem = dict()
elem['target'] = 'contract'
elem['convention'] = 'CapWords'
elem['name'] = contract.name
elem['source_mapping'] = contract.source_mapping
json['elements'] = [elem]
self.add_contract_to_json(contract, json, {
"target": "contract",
"convention": "CapWords"
})
results.append(json)
for struct in contract.structures:
@ -78,13 +76,12 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
info = info.format(struct.contract.name, struct.name, struct.source_mapping_str)
json = self.generate_json_result(info)
elem = dict()
elem['target'] = 'structure'
elem['convention'] = 'CapWords'
elem['name'] = struct.name
elem['source_mapping'] = struct.source_mapping
json['elements'] = [elem]
self.add_struct_to_json(struct, json, {
"target": "structure",
"convention": "CapWords"
})
results.append(json)
for event in contract.events:
if event.contract != contract:
continue
@ -94,12 +91,10 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
info = info.format(event.contract.name, event.name, event.source_mapping_str)
json = self.generate_json_result(info)
elem = dict()
elem['target'] = 'event'
elem['convention'] = 'CapWords'
elem['name'] = event.name
elem['source_mapping'] = event.source_mapping
json['elements'] = [elem]
self.add_event_to_json(event, json, {
"target": "event",
"convention": "CapWords"
})
results.append(json)
for func in contract.functions:
@ -111,12 +106,10 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
info = info.format(func.contract.name, func.name, func.source_mapping_str)
json = self.generate_json_result(info)
elem = dict()
elem['target'] = 'function'
elem['convention'] = 'mixedCase'
elem['name'] = func.name
elem['source_mapping'] = func.source_mapping
json['elements'] = [elem]
self.add_function_to_json(func, json, {
"target": "function",
"convention": "mixedCase"
})
results.append(json)
for argument in func.parameters:
@ -132,12 +125,10 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
argument.source_mapping_str)
json = self.generate_json_result(info)
elem = dict()
elem['target'] = 'parameter'
elem['convention'] = 'mixedCase'
elem['name'] = argument.name
elem['source_mapping'] = argument.source_mapping
json['elements'] = [elem]
self.add_variable_to_json(argument, json, {
"target": "parameter",
"convention": "mixedCase"
})
results.append(json)
for var in contract.state_variables:
@ -150,12 +141,10 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
info = info.format(var.contract.name, var.name, var.source_mapping_str)
json = self.generate_json_result(info)
elem = dict()
elem['target'] = 'variable'
elem['convention'] = 'l_O_I_should_not_be_used'
elem['name'] = var.name
elem['source_mapping'] = var.source_mapping
json['elements'] = [elem]
self.add_variable_to_json(var, json, {
"target": "variable",
"convention": "l_O_I_should_not_be_used"
})
results.append(json)
if var.is_constant is True:
@ -168,12 +157,10 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
info = info.format(var.contract.name, var.name, var.source_mapping_str)
json = self.generate_json_result(info)
elem = dict()
elem['target'] = 'variable_constant'
elem['convention'] = 'UPPER_CASE_WITH_UNDERSCORES'
elem['name'] = var.name
elem['source_mapping'] = var.source_mapping
json['elements'] = [elem]
self.add_variable_to_json(var, json, {
"target": "variable_constant",
"convention": "UPPER_CASE_WITH_UNDERSCORES"
})
results.append(json)
else:
@ -186,12 +173,10 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
info = info.format(var.contract.name, var.name, var.source_mapping_str)
json = self.generate_json_result(info)
elem = dict()
elem['target'] = 'variable'
elem['convention'] = 'mixedCase'
elem['name'] = var.name
elem['source_mapping'] = var.source_mapping
json['elements'] = [elem]
self.add_variable_to_json(var, json, {
"target": "variable",
"convention": "mixedCase"
})
results.append(json)
for enum in contract.enums:
@ -203,12 +188,10 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
info = info.format(enum.contract.name, enum.name, enum.source_mapping_str)
json = self.generate_json_result(info)
elem = dict()
elem['target'] = 'enum'
elem['convention'] = 'CapWords'
elem['name'] = enum.name
elem['source_mapping'] = enum.source_mapping
json['elements'] = [elem]
self.add_enum_to_json(enum, json, {
"target": "enum",
"convention": "CapWords"
})
results.append(json)
@ -223,12 +206,10 @@ Solidity defines a [naming convention](https://solidity.readthedocs.io/en/v0.4.2
modifier.source_mapping_str)
json = self.generate_json_result(info)
elem = dict()
elem['target'] = 'modifier'
elem['convention'] = 'mixedCase'
elem['name'] = modifier.name
elem['source_mapping'] = modifier.source_mapping
json['elements'] = [elem]
self.add_function_to_json(modifier, json, {
"target": "modifier",
"convention": "mixedCase"
})
results.append(json)

@ -143,8 +143,10 @@ contract Bug {
# Generate relevant JSON data for this shadowing definition.
json = self.generate_json_result(info)
if shadow_type in [self.SHADOWING_FUNCTION, self.SHADOWING_MODIFIER, self.SHADOWING_EVENT]:
if shadow_type in [self.SHADOWING_FUNCTION, self.SHADOWING_MODIFIER]:
self.add_function_to_json(shadow_object, json)
elif shadow_type == self.SHADOWING_EVENT:
self.add_event_to_json(shadow_object, json)
elif shadow_type in [self.SHADOWING_STATE_VARIABLE, self.SHADOWING_LOCAL_VARIABLE]:
self.add_variable_to_json(shadow_object, json)
results.append(json)

Loading…
Cancel
Save