Skip to content

Commit e36baf5

Browse files
Srinivas11789Eric Hennenfent
authored andcommitted
fix 1427 - limit sanity check in SMTlib (#1543)
* add type hints replacing assert isinstances and reformat with black * change annotations to support python 3.6 * address mypy test issues and prefer forward references * address feedback --> remove any and obvious None returns, explicit types * decide to remove Any altogether and test with mypy * correct type hints for some functions
1 parent 1208759 commit e36baf5

File tree

1 file changed

+54
-62
lines changed

1 file changed

+54
-62
lines changed

manticore/core/smtlib/expression.py

Lines changed: 54 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import re
66
import copy
7+
from typing import Union, Type, Optional, Dict, Any
78

89

910
class ExpressionException(SmtlibError):
@@ -17,10 +18,9 @@ class ExpressionException(SmtlibError):
1718
class Expression:
1819
""" Abstract taintable Expression. """
1920

20-
def __init__(self, taint=()):
21+
def __init__(self, taint: Union[tuple, frozenset] = ()):
2122
if self.__class__ is Expression:
2223
raise TypeError
23-
assert isinstance(taint, (tuple, frozenset))
2424
super().__init__()
2525
self._taint = frozenset(taint)
2626

@@ -111,10 +111,10 @@ def taint_with(arg, *taints, value_bits=256, index_bits=256):
111111

112112

113113
class Variable(Expression):
114-
def __init__(self, name, *args, **kwargs):
114+
def __init__(self, name: str, *args, **kwargs):
115115
if self.__class__ is Variable:
116116
raise TypeError
117-
assert isinstance(name, str) and " " not in name
117+
assert " " not in name
118118
super().__init__(*args, **kwargs)
119119
self._name = name
120120

@@ -137,10 +137,9 @@ def __repr__(self):
137137

138138

139139
class Constant(Expression):
140-
def __init__(self, value, *args, **kwargs):
140+
def __init__(self, value: Union[bool, int], *args, **kwargs):
141141
if self.__class__ is Constant:
142142
raise TypeError
143-
assert isinstance(value, (bool, int))
144143
super().__init__(*args, **kwargs)
145144
self._value = value
146145

@@ -174,10 +173,9 @@ class Bool(Expression):
174173
def __init__(self, *operands, **kwargs):
175174
super().__init__(*operands, **kwargs)
176175

177-
def cast(self, value, **kwargs):
176+
def cast(self, value: Union[int, bool], **kwargs) -> Union["BoolConstant", "Bool"]:
178177
if isinstance(value, Bool):
179178
return value
180-
assert isinstance(value, (int, bool))
181179
return BoolConstant(bool(value), **kwargs)
182180

183181
def __cmp__(self, *args):
@@ -227,8 +225,7 @@ def declaration(self):
227225

228226

229227
class BoolConstant(Bool, Constant):
230-
def __init__(self, value, *args, **kwargs):
231-
assert isinstance(value, bool)
228+
def __init__(self, value: bool, *args, **kwargs):
232229
super().__init__(value, *args, **kwargs)
233230

234231
def __bool__(self):
@@ -251,9 +248,7 @@ def __init__(self, a, b, **kwargs):
251248

252249

253250
class BoolOr(BoolOperation):
254-
def __init__(self, a, b, **kwargs):
255-
assert isinstance(a, Bool)
256-
assert isinstance(b, Bool)
251+
def __init__(self, a: "Bool", b: "Bool", **kwargs):
257252
super().__init__(a, b, **kwargs)
258253

259254

@@ -263,10 +258,7 @@ def __init__(self, a, b, **kwargs):
263258

264259

265260
class BoolITE(BoolOperation):
266-
def __init__(self, cond, true, false, **kwargs):
267-
assert isinstance(true, Bool)
268-
assert isinstance(false, Bool)
269-
assert isinstance(cond, Bool)
261+
def __init__(self, cond: "Bool", true: "Bool", false: "Bool", **kwargs):
270262
super().__init__(cond, true, false, **kwargs)
271263

272264

@@ -285,7 +277,9 @@ def mask(self):
285277
def signmask(self):
286278
return 1 << (self.size - 1)
287279

288-
def cast(self, value, **kwargs):
280+
def cast(
281+
self, value: Union["BitVec", str, int, bytes], **kwargs
282+
) -> Union["BitVecConstant", "BitVec"]:
289283
if isinstance(value, BitVec):
290284
assert value.size == self.size
291285
return value
@@ -481,8 +475,7 @@ def declaration(self):
481475

482476

483477
class BitVecConstant(BitVec, Constant):
484-
def __init__(self, size, value, *args, **kwargs):
485-
assert isinstance(value, int)
478+
def __init__(self, size: int, value: int, *args, **kwargs):
486479
super().__init__(size, value, *args, **kwargs)
487480

488481
def __bool__(self):
@@ -568,9 +561,7 @@ def __init__(self, a, b, *args, **kwargs):
568561

569562

570563
class BitVecOr(BitVecOperation):
571-
def __init__(self, a, b, *args, **kwargs):
572-
assert isinstance(a, BitVec)
573-
assert isinstance(b, BitVec)
564+
def __init__(self, a: BitVec, b: BitVec, *args, **kwargs):
574565
assert a.size == b.size
575566
super().__init__(a.size, a, b, *args, **kwargs)
576567

@@ -647,10 +638,11 @@ def __init__(self, a, b, *args, **kwargs):
647638
###############################################################################
648639
# Array BV32 -> BV8 or BV64 -> BV8
649640
class Array(Expression):
650-
def __init__(self, index_bits, index_max, value_bits, *operands, **kwargs):
641+
def __init__(
642+
self, index_bits: int, index_max: Optional[int], value_bits: int, *operands, **kwargs
643+
):
651644
assert index_bits in (32, 64, 256)
652645
assert value_bits in (8, 16, 32, 64, 256)
653-
assert index_max is None or isinstance(index_max, int)
654646
assert index_max is None or index_max >= 0 and index_max < 2 ** index_bits
655647
self._index_bits = index_bits
656648
self._index_max = index_max
@@ -690,21 +682,24 @@ def cast(self, possible_array):
690682
return arr
691683
raise ValueError # cast not implemented
692684

693-
def cast_index(self, index):
685+
def cast_index(self, index: Union[int, "BitVec"]) -> Union["BitVecConstant", "BitVec"]:
694686
if isinstance(index, int):
695687
# assert self.index_max is None or index >= 0 and index < self.index_max
696688
return BitVecConstant(self.index_bits, index)
697-
assert isinstance(index, BitVec) and index.size == self.index_bits
689+
assert index.size == self.index_bits
698690
return index
699691

700-
def cast_value(self, value):
692+
def cast_value(
693+
self, value: Union["BitVec", str, bytes, int]
694+
) -> Union["BitVecConstant", "BitVec"]:
695+
if isinstance(value, BitVec):
696+
assert value.size == self.value_bits
697+
return value
701698
if isinstance(value, (str, bytes)) and len(value) == 1:
702699
value = ord(value)
703-
if isinstance(value, int):
704-
return BitVecConstant(self.value_bits, value)
705-
assert isinstance(value, BitVec)
706-
assert value.size == self.value_bits
707-
return value
700+
if not isinstance(value, int):
701+
value = int(value)
702+
return BitVecConstant(self.value_bits, value)
708703

709704
def __len__(self):
710705
if self.index_max is None:
@@ -875,18 +870,16 @@ def declaration(self):
875870

876871

877872
class ArrayOperation(Array, Operation):
878-
def __init__(self, array, *operands, **kwargs):
879-
assert isinstance(array, Array)
873+
def __init__(self, array: Array, *operands, **kwargs):
880874
super().__init__(
881875
array.index_bits, array.index_max, array.value_bits, array, *operands, **kwargs
882876
)
883877

884878

885879
class ArrayStore(ArrayOperation):
886-
def __init__(self, array, index, value, *args, **kwargs):
887-
assert isinstance(array, Array)
888-
assert isinstance(index, BitVec) and index.size == array.index_bits
889-
assert isinstance(value, BitVec) and value.size == array.value_bits
880+
def __init__(self, array: "Array", index: "BitVec", value: "BitVec", *args, **kwargs):
881+
assert index.size == array.index_bits
882+
assert value.size == array.value_bits
890883
super().__init__(array, index, value, *args, **kwargs)
891884

892885
@property
@@ -907,7 +900,9 @@ def value(self):
907900

908901

909902
class ArraySlice(Array):
910-
def __init__(self, array, offset, size, *args, **kwargs):
903+
def __init__(
904+
self, array: Union["Array", "ArrayProxy"], offset: int, size: int, *args, **kwargs
905+
):
911906
if not isinstance(array, Array):
912907
raise ValueError("Array expected")
913908
if isinstance(array, ArrayProxy):
@@ -954,16 +949,15 @@ def store(self, index, value):
954949

955950

956951
class ArrayProxy(Array):
957-
def __init__(self, array, default=None):
958-
assert isinstance(array, Array)
952+
def __init__(self, array: Array, default: Optional[int] = None):
959953
self._default = default
960-
self._concrete_cache = {}
954+
self._concrete_cache: Dict[int, int] = {}
961955
self._written = None
962956
if isinstance(array, ArrayProxy):
963957
# copy constructor
964958
super().__init__(array.index_bits, array.index_max, array.value_bits)
965-
self._array = array._array
966-
self._name = array._name
959+
self._array: Array = array._array
960+
self._name: str = array._name
967961
if default is None:
968962
self._default = array._default
969963
self._concrete_cache = dict(array._concrete_cache)
@@ -1138,9 +1132,8 @@ def get(self, index, default=None):
11381132

11391133

11401134
class ArraySelect(BitVec, Operation):
1141-
def __init__(self, array, index, *args, **kwargs):
1142-
assert isinstance(array, Array)
1143-
assert isinstance(index, BitVec) and index.size == array.index_bits
1135+
def __init__(self, array: "Array", index: "BitVec", *args, **kwargs):
1136+
assert index.size == array.index_bits
11441137
super().__init__(array.value_bits, array, index, *args, **kwargs)
11451138

11461139
@property
@@ -1156,27 +1149,21 @@ def __repr__(self):
11561149

11571150

11581151
class BitVecSignExtend(BitVecOperation):
1159-
def __init__(self, operand, size_dest, *args, **kwargs):
1160-
assert isinstance(operand, BitVec)
1161-
assert isinstance(size_dest, int)
1152+
def __init__(self, operand: "BitVec", size_dest: int, *args, **kwargs):
11621153
assert size_dest >= operand.size
11631154
super().__init__(size_dest, operand, *args, **kwargs)
11641155
self.extend = size_dest - operand.size
11651156

11661157

11671158
class BitVecZeroExtend(BitVecOperation):
1168-
def __init__(self, size_dest, operand, *args, **kwargs):
1169-
assert isinstance(operand, BitVec)
1170-
assert isinstance(size_dest, int)
1159+
def __init__(self, size_dest: int, operand: "BitVec", *args, **kwargs):
11711160
assert size_dest >= operand.size
11721161
super().__init__(size_dest, operand, *args, **kwargs)
11731162
self.extend = size_dest - operand.size
11741163

11751164

11761165
class BitVecExtract(BitVecOperation):
1177-
def __init__(self, operand, offset, size, *args, **kwargs):
1178-
assert isinstance(offset, int)
1179-
assert isinstance(size, int)
1166+
def __init__(self, operand: "BitVec", offset: int, size: int, *args, **kwargs):
11801167
assert offset >= 0 and offset + size <= operand.size
11811168
super().__init__(size, operand, *args, **kwargs)
11821169
self._begining = offset
@@ -1196,17 +1183,22 @@ def end(self):
11961183

11971184

11981185
class BitVecConcat(BitVecOperation):
1199-
def __init__(self, size_dest, *operands, **kwargs):
1200-
assert isinstance(size_dest, int)
1186+
def __init__(self, size_dest: int, *operands, **kwargs):
12011187
assert all(isinstance(x, BitVec) for x in operands)
12021188
assert size_dest == sum(x.size for x in operands)
12031189
super().__init__(size_dest, *operands, **kwargs)
12041190

12051191

12061192
class BitVecITE(BitVecOperation):
1207-
def __init__(self, size, condition, true_value, false_value, *args, **kwargs):
1208-
assert isinstance(true_value, BitVec)
1209-
assert isinstance(false_value, BitVec)
1193+
def __init__(
1194+
self,
1195+
size: int,
1196+
condition: Union["Bool", bool],
1197+
true_value: "BitVec",
1198+
false_value: "BitVec",
1199+
*args,
1200+
**kwargs,
1201+
):
12101202
assert true_value.size == size
12111203
assert false_value.size == size
12121204
super().__init__(size, condition, true_value, false_value, *args, **kwargs)

0 commit comments

Comments
 (0)