|
|
@ -10,7 +10,8 @@ from slither.slithir.operations import ( |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_with_explicit_return(slither_from_solidity_source) -> None: |
|
|
|
@pytest.mark.parametrize("legacy", [True, False]) |
|
|
|
|
|
|
|
def test_with_explicit_return(slither_from_solidity_source, legacy) -> None: |
|
|
|
source = """ |
|
|
|
source = """ |
|
|
|
contract Contract { |
|
|
|
contract Contract { |
|
|
|
function foo(int x) public returns (int y) { |
|
|
|
function foo(int x) public returns (int y) { |
|
|
@ -22,31 +23,31 @@ def test_with_explicit_return(slither_from_solidity_source) -> None: |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
""" |
|
|
|
""" |
|
|
|
for legacy in [True, False]: |
|
|
|
with slither_from_solidity_source(source, legacy=legacy) as slither: |
|
|
|
with slither_from_solidity_source(source, legacy=legacy) as slither: |
|
|
|
c: Contract = slither.get_contract_from_name("Contract")[0] |
|
|
|
c: Contract = slither.get_contract_from_name("Contract")[0] |
|
|
|
f: Function = c.functions[0] |
|
|
|
f: Function = c.functions[0] |
|
|
|
node_if: Node = f.nodes[1] |
|
|
|
node_if: Node = f.nodes[1] |
|
|
|
node_true = node_if.son_true |
|
|
|
node_true = node_if.son_true |
|
|
|
node_false = node_if.son_false |
|
|
|
node_false = node_if.son_false |
|
|
|
assert node_true.type == NodeType.RETURN |
|
|
|
assert node_true.type == NodeType.RETURN |
|
|
|
assert isinstance(node_true.irs[0], Return) |
|
|
|
assert isinstance(node_true.irs[0], Return) |
|
|
|
assert node_true.irs[0].values[0] == f.get_local_variable_from_name("x") |
|
|
|
assert node_true.irs[0].values[0] == f.get_local_variable_from_name("x") |
|
|
|
assert len(node_true.sons) == 0 |
|
|
|
assert len(node_true.sons) == 0 |
|
|
|
node_end_if = node_false.sons[0] |
|
|
|
node_end_if = node_false.sons[0] |
|
|
|
assert node_end_if.type == NodeType.ENDIF |
|
|
|
assert node_end_if.type == NodeType.ENDIF |
|
|
|
assert node_end_if.sons[0].type == NodeType.RETURN |
|
|
|
assert node_end_if.sons[0].type == NodeType.RETURN |
|
|
|
node_ret = node_end_if.sons[0] |
|
|
|
node_ret = node_end_if.sons[0] |
|
|
|
assert isinstance(node_ret.irs[0], Return) |
|
|
|
assert isinstance(node_ret.irs[0], Return) |
|
|
|
assert node_ret.irs[0].values[0] == f.get_local_variable_from_name("y") |
|
|
|
assert node_ret.irs[0].values[0] == f.get_local_variable_from_name("y") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_return_multiple_with_struct(slither_from_solidity_source) -> None: |
|
|
|
@pytest.mark.parametrize("legacy", [True, False]) |
|
|
|
|
|
|
|
def test_return_multiple_with_struct(slither_from_solidity_source, legacy) -> None: |
|
|
|
source = """ |
|
|
|
source = """ |
|
|
|
struct St { |
|
|
|
struct St { |
|
|
|
uint256 value; |
|
|
|
uint256 value; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
contract Contract { |
|
|
|
contract Contract { |
|
|
|
function foo(St memory x) public returns (St memory y, uint256 z) { |
|
|
|
function foo(St memory x) public returns (St memory y, uint256 z) { |
|
|
|
z = x.value; |
|
|
|
z = x.value; |
|
|
@ -54,16 +55,15 @@ def test_return_multiple_with_struct(slither_from_solidity_source) -> None: |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
""" |
|
|
|
""" |
|
|
|
for legacy in [True, False]: |
|
|
|
with slither_from_solidity_source(source, legacy=legacy) as slither: |
|
|
|
with slither_from_solidity_source(source, legacy=legacy) as slither: |
|
|
|
c: Contract = slither.get_contract_from_name("Contract")[0] |
|
|
|
c: Contract = slither.get_contract_from_name("Contract")[0] |
|
|
|
f: Function = c.functions[0] |
|
|
|
f: Function = c.functions[0] |
|
|
|
assert len(f.nodes) == 4 |
|
|
|
assert len(f.nodes) == 4 |
|
|
|
node = f.nodes[3] |
|
|
|
node = f.nodes[3] |
|
|
|
assert node.type == NodeType.RETURN |
|
|
|
assert node.type == NodeType.RETURN |
|
|
|
assert isinstance(node.irs[0], Return) |
|
|
|
assert isinstance(node.irs[0], Return) |
|
|
|
assert node.irs[0].values[0] == f.get_local_variable_from_name("y") |
|
|
|
assert node.irs[0].values[0] == f.get_local_variable_from_name("y") |
|
|
|
assert node.irs[0].values[1] == f.get_local_variable_from_name("z") |
|
|
|
assert node.irs[0].values[1] == f.get_local_variable_from_name("z") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_nested_ifs_with_loop_legacy(slither_from_solidity_source) -> None: |
|
|
|
def test_nested_ifs_with_loop_legacy(slither_from_solidity_source) -> None: |
|
|
@ -149,7 +149,8 @@ def test_nested_ifs_with_loop_compact(slither_from_solidity_source) -> None: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.xfail # Explicit returns inside assembly are currently not parsed as return nodes |
|
|
|
@pytest.mark.xfail # Explicit returns inside assembly are currently not parsed as return nodes |
|
|
|
def test_assembly_switch_cases(slither_from_solidity_source): |
|
|
|
@pytest.mark.parametrize("legacy", [True, False]) |
|
|
|
|
|
|
|
def test_assembly_switch_cases(slither_from_solidity_source, legacy): |
|
|
|
source = """ |
|
|
|
source = """ |
|
|
|
contract Contract { |
|
|
|
contract Contract { |
|
|
|
function foo(uint a) public returns (uint x) { |
|
|
|
function foo(uint a) public returns (uint x) { |
|
|
@ -164,28 +165,28 @@ def test_assembly_switch_cases(slither_from_solidity_source): |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
""" |
|
|
|
""" |
|
|
|
for legacy in [True, False]: |
|
|
|
with slither_from_solidity_source(source, solc_version="0.8.0", legacy=legacy) as slither: |
|
|
|
with slither_from_solidity_source(source, solc_version="0.8.0", legacy=legacy) as slither: |
|
|
|
c: Contract = slither.get_contract_from_name("Contract")[0] |
|
|
|
c: Contract = slither.get_contract_from_name("Contract")[0] |
|
|
|
f = c.functions[0] |
|
|
|
f = c.functions[0] |
|
|
|
if legacy: |
|
|
|
if legacy: |
|
|
|
node = f.nodes[2] |
|
|
|
node = f.nodes[2] |
|
|
|
assert node.type == NodeType.RETURN |
|
|
|
assert node.type == NodeType.RETURN |
|
|
|
assert isinstance(node.irs[0], Return) |
|
|
|
assert isinstance(node.irs[0], Return) |
|
|
|
assert node.irs[0].values[0] == f.get_local_variable_from_name("x") |
|
|
|
assert node.irs[0].values[0] == f.get_local_variable_from_name("x") |
|
|
|
else: |
|
|
|
else: |
|
|
|
node_end_if = f.nodes[5] |
|
|
|
node_end_if = f.nodes[5] |
|
|
|
assert node_end_if.sons[0].type == NodeType.RETURN |
|
|
|
assert node_end_if.sons[0].type == NodeType.RETURN |
|
|
|
node_implicit = node_end_if.sons[0] |
|
|
|
node_implicit = node_end_if.sons[0] |
|
|
|
assert isinstance(node_implicit.irs[0], Return) |
|
|
|
assert isinstance(node_implicit.irs[0], Return) |
|
|
|
assert node_implicit.irs[0].values[0] == f.get_local_variable_from_name("x") |
|
|
|
assert node_implicit.irs[0].values[0] == f.get_local_variable_from_name("x") |
|
|
|
# This part will fail until issue #1927 is fixed |
|
|
|
# This part will fail until issue #1927 is fixed |
|
|
|
node_explicit = f.nodes[10] |
|
|
|
node_explicit = f.nodes[10] |
|
|
|
assert node_explicit.type == NodeType.RETURN |
|
|
|
assert node_explicit.type == NodeType.RETURN |
|
|
|
assert len(node_explicit.sons) == 0 |
|
|
|
assert len(node_explicit.sons) == 0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_issue_1846_ternary_in_ternary(slither_from_solidity_source): |
|
|
|
@pytest.mark.parametrize("legacy", [True, False]) |
|
|
|
|
|
|
|
def test_issue_1846_ternary_in_ternary(slither_from_solidity_source, legacy): |
|
|
|
source = """ |
|
|
|
source = """ |
|
|
|
contract Contract { |
|
|
|
contract Contract { |
|
|
|
function foo(uint x) public returns (uint y) { |
|
|
|
function foo(uint x) public returns (uint y) { |
|
|
@ -193,14 +194,13 @@ def test_issue_1846_ternary_in_ternary(slither_from_solidity_source): |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
""" |
|
|
|
""" |
|
|
|
for legacy in [True, False]: |
|
|
|
with slither_from_solidity_source(source, legacy=legacy) as slither: |
|
|
|
with slither_from_solidity_source(source, legacy=legacy) as slither: |
|
|
|
c: Contract = slither.get_contract_from_name("Contract")[0] |
|
|
|
c: Contract = slither.get_contract_from_name("Contract")[0] |
|
|
|
f = c.functions[0] |
|
|
|
f = c.functions[0] |
|
|
|
node_end_if = f.nodes[3] |
|
|
|
node_end_if = f.nodes[3] |
|
|
|
assert node_end_if.type == NodeType.ENDIF |
|
|
|
assert node_end_if.type == NodeType.ENDIF |
|
|
|
assert len(node_end_if.sons) == 1 |
|
|
|
assert len(node_end_if.sons) == 1 |
|
|
|
node_ret = node_end_if.sons[0] |
|
|
|
node_ret = node_end_if.sons[0] |
|
|
|
assert node_ret.type == NodeType.RETURN |
|
|
|
assert node_ret.type == NodeType.RETURN |
|
|
|
assert isinstance(node_ret.irs[0], Return) |
|
|
|
assert isinstance(node_ret.irs[0], Return) |
|
|
|
assert node_ret.irs[0].values[0] == f.get_local_variable_from_name("y") |
|
|
|
assert node_ret.irs[0].values[0] == f.get_local_variable_from_name("y") |
|
|
|
|
|
|
|