Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pop conversion #374

Merged
merged 1 commit into from
Nov 20, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 69 additions & 2 deletions slither/slithir/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,7 @@ def propagate_type_and_convert_call(result, node):
result.insert(idx, new_ins[0])
result.insert(idx+1, new_ins[1])
idx = idx + 1
else:
assert len(new_ins) == 3
elif len(new_ins) == 3:
new_ins[0].set_node(ins.node)
new_ins[1].set_node(ins.node)
new_ins[2].set_node(ins.node)
Expand All @@ -314,6 +313,23 @@ def propagate_type_and_convert_call(result, node):
result.insert(idx+1, new_ins[1])
result.insert(idx+2, new_ins[2])
idx = idx + 2
else:
# Pop conversion
assert len(new_ins) == 6
new_ins[0].set_node(ins.node)
new_ins[1].set_node(ins.node)
new_ins[2].set_node(ins.node)
new_ins[3].set_node(ins.node)
new_ins[4].set_node(ins.node)
new_ins[5].set_node(ins.node)
del result[idx]
result.insert(idx, new_ins[0])
result.insert(idx + 1, new_ins[1])
result.insert(idx + 2, new_ins[2])
result.insert(idx + 3, new_ins[3])
result.insert(idx + 4, new_ins[4])
result.insert(idx + 5, new_ins[5])
idx = idx + 5
else:
new_ins.set_node(ins.node)
result[idx] = new_ins
Expand Down Expand Up @@ -416,6 +432,8 @@ def propagate_types(ir, node):
if isinstance(t, ArrayType) or (isinstance(t, ElementaryType) and t.type == 'bytes'):
if ir.function_name == 'push' and len(ir.arguments) == 1:
return convert_to_push(ir, node)
if ir.function_name == 'pop' and len(ir.arguments) == 0:
return convert_to_pop(ir, node)

elif isinstance(ir, Index):
if isinstance(ir.variable_left.type, MappingType):
Expand Down Expand Up @@ -727,6 +745,7 @@ def convert_to_push(ir, node):
As a result, the function return may return a list
"""

# TODO remove Push Operator, and change this to existing operators

lvalue = ir.lvalue
if isinstance(ir.arguments[0], list):
Expand Down Expand Up @@ -771,6 +790,54 @@ def convert_to_push(ir, node):

return ir


def convert_to_pop(ir, node):
"""
Convert pop operators
Return a list of 6 operations
"""

ret = []

arr = ir.destination
length = ReferenceVariable(node)
length.set_type(ElementaryType('uint256'))

ir_length = Length(arr, length)
ir_length.set_expression(ir.expression)
ir_length.lvalue.points_to = arr
ret.append(ir_length)

val = TemporaryVariable(node)

ir_sub_1 = Binary(val, length, Constant("1", ElementaryType('uint256')), BinaryType.SUBTRACTION)
ir_sub_1.set_expression(ir.expression)
ret.append(ir_sub_1)

element_to_delete = ReferenceVariable(node)
ir_assign_element_to_delete = Index(element_to_delete, arr, val, ElementaryType('uint256'))
ir_length.lvalue.points_to = arr
element_to_delete.set_type(ElementaryType('uint256'))
ir_assign_element_to_delete.set_expression(ir.expression)
ret.append(ir_assign_element_to_delete)

ir_delete = Delete(element_to_delete, element_to_delete)
ir_delete.set_expression(ir.expression)
ret.append(ir_delete)

length_to_assign = ReferenceVariable(node)
length_to_assign.set_type(ElementaryType('uint256'))
ir_length = Length(arr, length_to_assign)
ir_length.set_expression(ir.expression)
ir_length.lvalue.points_to = arr
ret.append(ir_length)

ir_assign_length = Assignment(length_to_assign, val, ElementaryType('uint256'))
ir_assign_length.set_expression(ir.expression)
ret.append(ir_assign_length)

return ret

def look_for_library(contract, ir, node, using_for, t):
for destination in using_for[t]:
lib_contract = contract.slither.get_contract_from_name(str(destination))
Expand Down