Add pop conversion (fix #359)

pull/374/head
Josselin 5 years ago
parent 0ef908e4f5
commit a15d153879
  1. 71
      slither/slithir/convert.py

@ -304,8 +304,7 @@ def propagate_type_and_convert_call(result, node):
result.insert(idx, new_ins[0]) result.insert(idx, new_ins[0])
result.insert(idx+1, new_ins[1]) result.insert(idx+1, new_ins[1])
idx = idx + 1 idx = idx + 1
else: elif len(new_ins) == 3:
assert len(new_ins) == 3
new_ins[0].set_node(ins.node) new_ins[0].set_node(ins.node)
new_ins[1].set_node(ins.node) new_ins[1].set_node(ins.node)
new_ins[2].set_node(ins.node) new_ins[2].set_node(ins.node)
@ -314,6 +313,23 @@ def propagate_type_and_convert_call(result, node):
result.insert(idx+1, new_ins[1]) result.insert(idx+1, new_ins[1])
result.insert(idx+2, new_ins[2]) result.insert(idx+2, new_ins[2])
idx = idx + 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: else:
new_ins.set_node(ins.node) new_ins.set_node(ins.node)
result[idx] = new_ins result[idx] = new_ins
@ -416,6 +432,8 @@ def propagate_types(ir, node):
if isinstance(t, ArrayType) or (isinstance(t, ElementaryType) and t.type == 'bytes'): if isinstance(t, ArrayType) or (isinstance(t, ElementaryType) and t.type == 'bytes'):
if ir.function_name == 'push' and len(ir.arguments) == 1: if ir.function_name == 'push' and len(ir.arguments) == 1:
return convert_to_push(ir, node) 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): elif isinstance(ir, Index):
if isinstance(ir.variable_left.type, MappingType): if isinstance(ir.variable_left.type, MappingType):
@ -727,6 +745,7 @@ def convert_to_push(ir, node):
As a result, the function return may return a list As a result, the function return may return a list
""" """
# TODO remove Push Operator, and change this to existing operators
lvalue = ir.lvalue lvalue = ir.lvalue
if isinstance(ir.arguments[0], list): if isinstance(ir.arguments[0], list):
@ -771,6 +790,54 @@ def convert_to_push(ir, node):
return ir 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): def look_for_library(contract, ir, node, using_for, t):
for destination in using_for[t]: for destination in using_for[t]:
lib_contract = contract.slither.get_contract_from_name(str(destination)) lib_contract = contract.slither.get_contract_from_name(str(destination))

Loading…
Cancel
Save