crosshair-tool 0.0.56__cp39-cp39-macosx_11_0_arm64.whl → 0.0.100__cp39-cp39-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- _crosshair_tracers.cpython-39-darwin.so +0 -0
- crosshair/__init__.py +1 -1
- crosshair/_mark_stacks.h +51 -24
- crosshair/_tracers.h +9 -5
- crosshair/_tracers_test.py +19 -9
- crosshair/auditwall.py +9 -8
- crosshair/auditwall_test.py +31 -19
- crosshair/codeconfig.py +3 -2
- crosshair/condition_parser.py +17 -133
- crosshair/condition_parser_test.py +54 -96
- crosshair/conftest.py +1 -1
- crosshair/copyext.py +91 -22
- crosshair/copyext_test.py +33 -0
- crosshair/core.py +259 -203
- crosshair/core_and_libs.py +20 -0
- crosshair/core_regestered_types_test.py +82 -0
- crosshair/core_test.py +693 -664
- crosshair/diff_behavior.py +76 -21
- crosshair/diff_behavior_test.py +132 -23
- crosshair/dynamic_typing.py +128 -18
- crosshair/dynamic_typing_test.py +91 -4
- crosshair/enforce.py +1 -6
- crosshair/enforce_test.py +15 -23
- crosshair/examples/check_examples_test.py +2 -1
- crosshair/fnutil.py +2 -3
- crosshair/fnutil_test.py +0 -7
- crosshair/fuzz_core_test.py +70 -83
- crosshair/libimpl/arraylib.py +10 -7
- crosshair/libimpl/binascii_ch_test.py +30 -0
- crosshair/libimpl/binascii_test.py +67 -0
- crosshair/libimpl/binasciilib.py +150 -0
- crosshair/libimpl/bisectlib_test.py +5 -5
- crosshair/libimpl/builtinslib.py +1002 -682
- crosshair/libimpl/builtinslib_ch_test.py +108 -30
- crosshair/libimpl/builtinslib_test.py +431 -143
- crosshair/libimpl/codecslib.py +22 -2
- crosshair/libimpl/codecslib_test.py +41 -9
- crosshair/libimpl/collectionslib.py +44 -8
- crosshair/libimpl/collectionslib_test.py +108 -20
- crosshair/libimpl/copylib.py +1 -1
- crosshair/libimpl/copylib_test.py +18 -0
- crosshair/libimpl/datetimelib.py +84 -67
- crosshair/libimpl/datetimelib_ch_test.py +12 -7
- crosshair/libimpl/datetimelib_test.py +5 -6
- crosshair/libimpl/decimallib.py +5257 -0
- crosshair/libimpl/decimallib_ch_test.py +78 -0
- crosshair/libimpl/decimallib_test.py +76 -0
- crosshair/libimpl/encodings/_encutil.py +21 -11
- crosshair/libimpl/fractionlib.py +16 -0
- crosshair/libimpl/fractionlib_test.py +80 -0
- crosshair/libimpl/functoolslib.py +19 -7
- crosshair/libimpl/functoolslib_test.py +22 -6
- crosshair/libimpl/hashliblib.py +30 -0
- crosshair/libimpl/hashliblib_test.py +18 -0
- crosshair/libimpl/heapqlib.py +32 -5
- crosshair/libimpl/heapqlib_test.py +15 -12
- crosshair/libimpl/iolib.py +7 -4
- crosshair/libimpl/ipaddresslib.py +8 -0
- crosshair/libimpl/itertoolslib_test.py +1 -1
- crosshair/libimpl/mathlib.py +165 -2
- crosshair/libimpl/mathlib_ch_test.py +44 -0
- crosshair/libimpl/mathlib_test.py +59 -16
- crosshair/libimpl/oslib.py +7 -0
- crosshair/libimpl/pathliblib_test.py +10 -0
- crosshair/libimpl/randomlib.py +1 -0
- crosshair/libimpl/randomlib_test.py +6 -4
- crosshair/libimpl/relib.py +180 -59
- crosshair/libimpl/relib_ch_test.py +26 -2
- crosshair/libimpl/relib_test.py +77 -14
- crosshair/libimpl/timelib.py +35 -13
- crosshair/libimpl/timelib_test.py +13 -3
- crosshair/libimpl/typeslib.py +15 -0
- crosshair/libimpl/typeslib_test.py +36 -0
- crosshair/libimpl/unicodedatalib_test.py +3 -3
- crosshair/libimpl/weakreflib.py +13 -0
- crosshair/libimpl/weakreflib_test.py +69 -0
- crosshair/libimpl/zliblib.py +15 -0
- crosshair/libimpl/zliblib_test.py +13 -0
- crosshair/lsp_server.py +21 -10
- crosshair/main.py +48 -28
- crosshair/main_test.py +59 -14
- crosshair/objectproxy.py +39 -14
- crosshair/objectproxy_test.py +27 -13
- crosshair/opcode_intercept.py +212 -24
- crosshair/opcode_intercept_test.py +172 -18
- crosshair/options.py +0 -1
- crosshair/patch_equivalence_test.py +5 -21
- crosshair/path_cover.py +7 -5
- crosshair/path_search.py +6 -4
- crosshair/path_search_test.py +1 -2
- crosshair/pathing_oracle.py +53 -10
- crosshair/pathing_oracle_test.py +21 -0
- crosshair/pure_importer_test.py +5 -21
- crosshair/register_contract.py +16 -6
- crosshair/register_contract_test.py +2 -14
- crosshair/simplestructs.py +154 -85
- crosshair/simplestructs_test.py +16 -2
- crosshair/smtlib.py +24 -0
- crosshair/smtlib_test.py +14 -0
- crosshair/statespace.py +319 -196
- crosshair/statespace_test.py +45 -0
- crosshair/stubs_parser.py +0 -2
- crosshair/test_util.py +87 -25
- crosshair/test_util_test.py +26 -0
- crosshair/tools/check_init_and_setup_coincide.py +0 -3
- crosshair/tools/generate_demo_table.py +2 -2
- crosshair/tracers.py +141 -49
- crosshair/type_repo.py +11 -4
- crosshair/unicode_categories.py +1 -0
- crosshair/util.py +158 -76
- crosshair/util_test.py +13 -20
- crosshair/watcher.py +4 -4
- crosshair/z3util.py +1 -1
- {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/METADATA +45 -36
- crosshair_tool-0.0.100.dist-info/RECORD +176 -0
- {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/WHEEL +2 -1
- crosshair/examples/hypothesis/__init__.py +0 -2
- crosshair/examples/hypothesis/bugs_detected/simple_strategies.py +0 -74
- crosshair_tool-0.0.56.dist-info/RECORD +0 -152
- /crosshair/{examples/hypothesis/bugs_detected/__init__.py → py.typed} +0 -0
- {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/entry_points.txt +0 -0
- {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info/licenses}/LICENSE +0 -0
- {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import binascii
|
|
2
|
+
from functools import partial
|
|
3
|
+
from typing import Dict, Iterable, Tuple, Union
|
|
4
|
+
|
|
5
|
+
from crosshair.core import register_patch
|
|
6
|
+
from crosshair.libimpl.builtinslib import _ALL_BYTES_TYPES, SymbolicBytes
|
|
7
|
+
from crosshair.util import name_of_type
|
|
8
|
+
|
|
9
|
+
_ORD_OF_NEWLINE = ord("\n")
|
|
10
|
+
_ORD_OF_EQUALS = ord("=")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _bit_chunk_iter(
|
|
14
|
+
seq: Iterable[int], input_bit_size: int, output_bit_size: int
|
|
15
|
+
) -> Iterable[int]:
|
|
16
|
+
"""Turns a sequence of N-bit integers into a sequence of M-bit integers"""
|
|
17
|
+
accumulated = 0
|
|
18
|
+
bits_accumulated = 0
|
|
19
|
+
input_size = 1 << input_bit_size
|
|
20
|
+
for chunk in seq:
|
|
21
|
+
accumulated = accumulated * input_size + chunk
|
|
22
|
+
bits_accumulated += input_bit_size
|
|
23
|
+
while bits_accumulated >= output_bit_size:
|
|
24
|
+
remaining_bits = bits_accumulated - output_bit_size
|
|
25
|
+
if remaining_bits == 0:
|
|
26
|
+
yield accumulated
|
|
27
|
+
accumulated = bits_accumulated = 0
|
|
28
|
+
else:
|
|
29
|
+
top, bottom = divmod(accumulated, 1 << remaining_bits)
|
|
30
|
+
yield top
|
|
31
|
+
accumulated = bottom
|
|
32
|
+
bits_accumulated = remaining_bits
|
|
33
|
+
if bits_accumulated > 0:
|
|
34
|
+
zero_bits = output_bit_size - bits_accumulated
|
|
35
|
+
yield accumulated * (1 << zero_bits)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _remap(
|
|
39
|
+
table: Dict[Tuple[int, int], int],
|
|
40
|
+
input_ints: Iterable[int],
|
|
41
|
+
error_type=None,
|
|
42
|
+
error_message=None,
|
|
43
|
+
):
|
|
44
|
+
output_ints = []
|
|
45
|
+
padding = 0
|
|
46
|
+
for ch in input_ints:
|
|
47
|
+
for (minval, maxval), target_start in table.items():
|
|
48
|
+
if all([minval <= ch, ch <= maxval]):
|
|
49
|
+
if minval != 0:
|
|
50
|
+
ch -= minval
|
|
51
|
+
if target_start != 0:
|
|
52
|
+
ch += target_start
|
|
53
|
+
output_ints.append(ch)
|
|
54
|
+
if padding != 0:
|
|
55
|
+
raise binascii.Error("Discontinuous padding not allowed")
|
|
56
|
+
break
|
|
57
|
+
else:
|
|
58
|
+
if ch == _ORD_OF_EQUALS:
|
|
59
|
+
padding += 1
|
|
60
|
+
elif error_message:
|
|
61
|
+
raise (error_type or binascii.Error)(error_message)
|
|
62
|
+
return output_ints, padding
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _reverse_map(table: Dict[Tuple[int, int], int]):
|
|
66
|
+
ret = {}
|
|
67
|
+
for (minval, maxval), target_start in table.items():
|
|
68
|
+
ret[(target_start, target_start + maxval - minval)] = minval
|
|
69
|
+
return ret
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
_DECODE_BASE64_MAP = {
|
|
73
|
+
(ord("A"), ord("Z")): 0,
|
|
74
|
+
(ord("a"), ord("z")): 26,
|
|
75
|
+
(ord("0"), ord("9")): 52,
|
|
76
|
+
(ord("+"), ord("+")): 62,
|
|
77
|
+
(ord("/"), ord("/")): 63,
|
|
78
|
+
}
|
|
79
|
+
_ENCODE_BASE64_MAP = _reverse_map(_DECODE_BASE64_MAP)
|
|
80
|
+
|
|
81
|
+
_DECODE_MAPPER_BASE64 = partial(_remap, _DECODE_BASE64_MAP)
|
|
82
|
+
_DECODE_MAPPER_BASE64_STRICT = partial(
|
|
83
|
+
_remap,
|
|
84
|
+
_DECODE_BASE64_MAP,
|
|
85
|
+
error_type=binascii.Error,
|
|
86
|
+
error_message="Only base64 data is allowed",
|
|
87
|
+
)
|
|
88
|
+
_ENCODE_MAPPER_BASE64 = partial(_remap, _ENCODE_BASE64_MAP)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def make_bytes(arg: object) -> Union[bytes, bytearray, memoryview]:
|
|
92
|
+
if isinstance(arg, (bytes, bytearray, memoryview)):
|
|
93
|
+
return arg
|
|
94
|
+
if isinstance(arg, str):
|
|
95
|
+
try:
|
|
96
|
+
return arg.encode("ascii")
|
|
97
|
+
except UnicodeEncodeError:
|
|
98
|
+
raise ValueError("string argument should contain only ASCII characters")
|
|
99
|
+
else:
|
|
100
|
+
raise TypeError(
|
|
101
|
+
f"a bytes-like object is required, not '{name_of_type(type(arg))}'"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _b2a_base64(data, /, *, newline=True): # encode
|
|
106
|
+
if not isinstance(data, _ALL_BYTES_TYPES):
|
|
107
|
+
raise TypeError(
|
|
108
|
+
f"a bytes-like object is required, not '{name_of_type(type(data))}'"
|
|
109
|
+
)
|
|
110
|
+
output_ints, _padding_count = _ENCODE_MAPPER_BASE64(
|
|
111
|
+
_bit_chunk_iter(data, input_bit_size=8, output_bit_size=6)
|
|
112
|
+
)
|
|
113
|
+
spillover = len(output_ints) % 4
|
|
114
|
+
if spillover > 0:
|
|
115
|
+
output_ints.extend([_ORD_OF_EQUALS for _ in range(4 - spillover)])
|
|
116
|
+
if newline:
|
|
117
|
+
output_ints.append(_ORD_OF_NEWLINE)
|
|
118
|
+
return SymbolicBytes(output_ints)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _a2b_base64(data, /, *, strict_mode: bool = False):
|
|
122
|
+
data = make_bytes(data)
|
|
123
|
+
input_ints, padding_count = (
|
|
124
|
+
_DECODE_MAPPER_BASE64_STRICT if strict_mode else _DECODE_MAPPER_BASE64
|
|
125
|
+
)(data)
|
|
126
|
+
|
|
127
|
+
data_char_count = len(input_ints)
|
|
128
|
+
uneven = data_char_count % 4 != 0
|
|
129
|
+
if uneven:
|
|
130
|
+
if data_char_count % 4 == 1:
|
|
131
|
+
raise binascii.Error(
|
|
132
|
+
f"Invalid base64-encoded string: number of data characters ({len(input_ints)}) cannot be 1 more than a multiple of 4"
|
|
133
|
+
)
|
|
134
|
+
expected_padding = 4 - (data_char_count % 4)
|
|
135
|
+
if padding_count < expected_padding:
|
|
136
|
+
raise binascii.Error("Incorrect padding")
|
|
137
|
+
elif strict_mode and padding_count > expected_padding:
|
|
138
|
+
raise binascii.Error("Excess data after padding")
|
|
139
|
+
output_ints = [
|
|
140
|
+
byt for byt in _bit_chunk_iter(input_ints, input_bit_size=6, output_bit_size=8)
|
|
141
|
+
]
|
|
142
|
+
if uneven:
|
|
143
|
+
output_ints = output_ints[:-1]
|
|
144
|
+
return SymbolicBytes(output_ints)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def make_registrations():
|
|
148
|
+
# NOTE: these power the base64 module, so we get that for free
|
|
149
|
+
register_patch(binascii.b2a_base64, _b2a_base64)
|
|
150
|
+
register_patch(binascii.a2b_base64, _a2b_base64)
|
|
@@ -12,12 +12,12 @@ def test_bisect_left():
|
|
|
12
12
|
with standalone_statespace as space:
|
|
13
13
|
with NoTracing():
|
|
14
14
|
lst = proxy_for_type(List[int], "lst")
|
|
15
|
-
space.add(lst.__len__().var == 2)
|
|
16
|
-
space.add(lst[0].var < 10)
|
|
17
|
-
space.add(lst[1].var > 20)
|
|
18
15
|
x = proxy_for_type(int, "x")
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
space.add(lst.__len__() == 2)
|
|
17
|
+
space.add(lst[0] < 10)
|
|
18
|
+
space.add(lst[1] > 20)
|
|
19
|
+
space.add(x >= 10)
|
|
20
|
+
space.add(x <= 20)
|
|
21
21
|
assert bisect.bisect_left(lst, x) == 1
|
|
22
22
|
assert bisect.bisect_left([0, 100], x) == 1
|
|
23
23
|
assert bisect.bisect_left(lst, 15) == 1
|