Added test and json artifact for boolean-constant-misuse

pull/721/head
Natalie Chin 4 years ago
parent 7f8ad666bc
commit 82fd8606ea
  1. 53
      slither/detectors/statements/boolean_constant_misuse.py
  2. 46
      tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol
  3. 208
      tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol.0.6.0.BooleanConstantMisuse.json
  4. 2
      tests/test_detectors.py

@ -67,39 +67,35 @@ Other uses (in complex expressions, as conditionals) indicate either an error or
results = [] results = []
# Loop for each function and modifier. # Loop for each function and modifier.
for function in contract.functions_declared: # pylint: disable=too-many-nested-blocks for function in contract.functions_declared:
f_results = set() f_results = set()
# Loop for every node in this function, looking for boolean constants # Loop for every node in this function, looking for boolean constants
for node in function.nodes: for node in function.nodes:
# Do not report "while(true)" # Do not report "while(true)"
if node.type == NodeType.IFLOOP: if node.type == NodeType.IFLOOP and node.irs and len(node.irs) == 1:
if node.irs: ir = node.irs[0]
if len(node.irs) == 1: if isinstance(ir, Condition) and ir.value == Constant(
ir = node.irs[0] "True", ElementaryType("bool")
if isinstance(ir, Condition) and ir.value == Constant( ):
"True", ElementaryType("bool") continue
):
continue
for ir in node.irs: for ir in node.irs:
if isinstance(ir, (Assignment, Call, Return, InitArray)): if isinstance(ir, (Assignment, Call, Return, InitArray)):
# It's ok to use a bare boolean constant in these contexts # It's ok to use a bare boolean constant in these contexts
continue continue
if isinstance(ir, Binary): if isinstance(ir, Binary) and ir.type in [
if ir.type in [
BinaryType.ADDITION, BinaryType.ADDITION,
BinaryType.EQUAL, BinaryType.EQUAL,
BinaryType.NOT_EQUAL, BinaryType.NOT_EQUAL,
]: ]:
# Comparing to a Boolean constant is dubious style, but harmless # Comparing to a Boolean constant is dubious style, but harmless
# Equal is catch by another detector (informational severity) # Equal is catch by another detector (informational severity)
continue continue
for r in ir.read: for r in ir.read:
if isinstance(r, Constant): if isinstance(r, Constant) and isinstance(r.value, bool):
if isinstance(r.value, bool): f_results.add(node)
f_results.add(node)
results.append((function, f_results)) results.append((function, f_results))
# Return the resulting set of nodes with improper uses of Boolean constants # Return the resulting set of nodes with improper uses of Boolean constants
@ -112,17 +108,16 @@ Other uses (in complex expressions, as conditionals) indicate either an error or
results = [] results = []
for contract in self.contracts: for contract in self.contracts:
boolean_constant_misuses = self._detect_boolean_constant_misuses(contract) boolean_constant_misuses = self._detect_boolean_constant_misuses(contract)
if boolean_constant_misuses: for (func, nodes) in boolean_constant_misuses:
for (func, nodes) in boolean_constant_misuses: for node in nodes:
for node in nodes: info = [
info = [ func,
func, " uses a Boolean constant improperly:\n\t-",
" uses a Boolean constant improperly:\n\t-", node,
node, "\n",
"\n", ]
]
res = self.generate_result(info)
res = self.generate_result(info) results.append(res)
results.append(res)
return results return results

@ -0,0 +1,46 @@
contract MyConc {
function bad0(bool foo) public pure returns (bool) {
if (foo) {
return true;
}
return false;
}
function bad1(bool b) public pure returns (bool) {
return (b || true);
}
function bad2(bool x, uint8 y) public pure returns (bool) {
while (x == (y > 0)) {
return true;
}
return false;
}
function bad3(bool a) public pure returns (bool) {
uint256 b = 0;
while (a) {
b++;
}
return true;
}
function bad4() public pure returns (bool) {
uint256 b = 0;
while (true) {
b++;
}
return true;
}
function bad5() public pure returns (bool) {
while (true) {
return true;
}
return false;
}
function good() public pure returns (bool) {
return true;
}
}

@ -0,0 +1,208 @@
[
[
{
"elements": [
{
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 162,
"length": 84,
"filename_used": "/GENERIC_PATH",
"filename_relative": "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol",
"is_dependency": false,
"lines": [
9,
10,
11
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "MyConc",
"source_mapping": {
"start": 0,
"length": 923,
"filename_used": "/GENERIC_PATH",
"filename_relative": "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol",
"is_dependency": false,
"lines": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47
],
"starting_column": 1,
"ending_column": 0
}
},
"signature": "bad1(bool)"
}
},
{
"type": "node",
"name": "(b || true)",
"source_mapping": {
"start": 221,
"length": 18,
"filename_used": "/GENERIC_PATH",
"filename_relative": "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol",
"is_dependency": false,
"lines": [
10
],
"starting_column": 9,
"ending_column": 27
},
"type_specific_fields": {
"parent": {
"type": "function",
"name": "bad1",
"source_mapping": {
"start": 162,
"length": 84,
"filename_used": "/GENERIC_PATH",
"filename_relative": "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol",
"is_dependency": false,
"lines": [
9,
10,
11
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "MyConc",
"source_mapping": {
"start": 0,
"length": 923,
"filename_used": "/GENERIC_PATH",
"filename_relative": "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol",
"is_dependency": false,
"lines": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47
],
"starting_column": 1,
"ending_column": 0
}
},
"signature": "bad1(bool)"
}
}
}
}
],
"description": "MyConc.bad1(bool) (tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol#9-11) uses a Boolean constant improperly:\n\t-(b || true) (tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol#10)\n",
"markdown": "[MyConc.bad1(bool)](tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol#L9-L11) uses a Boolean constant improperly:\n\t-[(b || true)](tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol#L10)\n",
"id": "12517fed0ec8f0a2232b467a6add9fd94a6a84325017e02e8a48794fc9112c6b",
"check": "boolean-cst",
"impact": "Medium",
"confidence": "Medium"
}
]
]

@ -37,6 +37,7 @@ from slither.detectors.shadowing.local import LocalShadowing
from slither.detectors.shadowing.state import StateShadowing from slither.detectors.shadowing.state import StateShadowing
from slither.detectors.source.rtlo import RightToLeftOverride from slither.detectors.source.rtlo import RightToLeftOverride
from slither.detectors.statements.assembly import Assembly from slither.detectors.statements.assembly import Assembly
from slither.detectors.statements.boolean_constant_misuse import BooleanConstantMisuse
from slither.detectors.statements.boolean_constant_equality import BooleanEquality from slither.detectors.statements.boolean_constant_equality import BooleanEquality
from slither.detectors.statements.calls_in_loop import MultipleCallsInLoop from slither.detectors.statements.calls_in_loop import MultipleCallsInLoop
from slither.detectors.statements.controlled_delegatecall import ControlledDelegateCall from slither.detectors.statements.controlled_delegatecall import ControlledDelegateCall
@ -97,6 +98,7 @@ ALL_TESTS = [
"tests/detectors/boolean-constant-equality/boolean-constant-equality.sol", "tests/detectors/boolean-constant-equality/boolean-constant-equality.sol",
"0.4.25", "0.4.25",
), ),
Test(BooleanConstantMisuse, "tests/detectors/boolean-constant-misuse/boolean-constant-misuse.sol", "0.6.0"),
Test(UncheckedLowLevel, "tests/detectors/unchecked-lowlevel/unchecked_lowlevel.sol", "0.4.25"), Test(UncheckedLowLevel, "tests/detectors/unchecked-lowlevel/unchecked_lowlevel.sol", "0.4.25"),
Test( Test(
UncheckedLowLevel, UncheckedLowLevel,

Loading…
Cancel
Save