crosshair-tool 0.0.99__cp312-cp312-macosx_10_13_x86_64.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-312-darwin.so +0 -0
- crosshair/__init__.py +42 -0
- crosshair/__main__.py +8 -0
- crosshair/_mark_stacks.h +790 -0
- crosshair/_preliminaries_test.py +18 -0
- crosshair/_tracers.h +94 -0
- crosshair/_tracers_pycompat.h +522 -0
- crosshair/_tracers_test.py +138 -0
- crosshair/abcstring.py +245 -0
- crosshair/auditwall.py +190 -0
- crosshair/auditwall_test.py +77 -0
- crosshair/codeconfig.py +113 -0
- crosshair/codeconfig_test.py +117 -0
- crosshair/condition_parser.py +1237 -0
- crosshair/condition_parser_test.py +497 -0
- crosshair/conftest.py +30 -0
- crosshair/copyext.py +155 -0
- crosshair/copyext_test.py +84 -0
- crosshair/core.py +1763 -0
- crosshair/core_and_libs.py +149 -0
- crosshair/core_regestered_types_test.py +82 -0
- crosshair/core_test.py +1316 -0
- crosshair/diff_behavior.py +314 -0
- crosshair/diff_behavior_test.py +261 -0
- crosshair/dynamic_typing.py +346 -0
- crosshair/dynamic_typing_test.py +210 -0
- crosshair/enforce.py +282 -0
- crosshair/enforce_test.py +182 -0
- crosshair/examples/PEP316/__init__.py +1 -0
- crosshair/examples/PEP316/bugs_detected/__init__.py +0 -0
- crosshair/examples/PEP316/bugs_detected/getattr_magic.py +16 -0
- crosshair/examples/PEP316/bugs_detected/hash_consistent_with_equals.py +31 -0
- crosshair/examples/PEP316/bugs_detected/shopping_cart.py +24 -0
- crosshair/examples/PEP316/bugs_detected/showcase.py +39 -0
- crosshair/examples/PEP316/correct_code/__init__.py +0 -0
- crosshair/examples/PEP316/correct_code/arith.py +60 -0
- crosshair/examples/PEP316/correct_code/chess.py +77 -0
- crosshair/examples/PEP316/correct_code/nesting_inference.py +17 -0
- crosshair/examples/PEP316/correct_code/numpy_examples.py +132 -0
- crosshair/examples/PEP316/correct_code/rolling_average.py +35 -0
- crosshair/examples/PEP316/correct_code/showcase.py +104 -0
- crosshair/examples/__init__.py +0 -0
- crosshair/examples/check_examples_test.py +146 -0
- crosshair/examples/deal/__init__.py +1 -0
- crosshair/examples/icontract/__init__.py +1 -0
- crosshair/examples/icontract/bugs_detected/__init__.py +0 -0
- crosshair/examples/icontract/bugs_detected/showcase.py +41 -0
- crosshair/examples/icontract/bugs_detected/wrong_sign.py +8 -0
- crosshair/examples/icontract/correct_code/__init__.py +0 -0
- crosshair/examples/icontract/correct_code/arith.py +51 -0
- crosshair/examples/icontract/correct_code/showcase.py +94 -0
- crosshair/fnutil.py +391 -0
- crosshair/fnutil_test.py +75 -0
- crosshair/fuzz_core_test.py +516 -0
- crosshair/libimpl/__init__.py +0 -0
- crosshair/libimpl/arraylib.py +161 -0
- 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 +23 -0
- crosshair/libimpl/builtinslib.py +5228 -0
- crosshair/libimpl/builtinslib_ch_test.py +1191 -0
- crosshair/libimpl/builtinslib_test.py +3735 -0
- crosshair/libimpl/codecslib.py +86 -0
- crosshair/libimpl/codecslib_test.py +86 -0
- crosshair/libimpl/collectionslib.py +264 -0
- crosshair/libimpl/collectionslib_ch_test.py +252 -0
- crosshair/libimpl/collectionslib_test.py +332 -0
- crosshair/libimpl/copylib.py +23 -0
- crosshair/libimpl/copylib_test.py +18 -0
- crosshair/libimpl/datetimelib.py +2559 -0
- crosshair/libimpl/datetimelib_ch_test.py +354 -0
- crosshair/libimpl/datetimelib_test.py +112 -0
- crosshair/libimpl/decimallib.py +5257 -0
- crosshair/libimpl/decimallib_ch_test.py +78 -0
- crosshair/libimpl/decimallib_test.py +76 -0
- crosshair/libimpl/encodings/__init__.py +23 -0
- crosshair/libimpl/encodings/_encutil.py +187 -0
- crosshair/libimpl/encodings/ascii.py +44 -0
- crosshair/libimpl/encodings/latin_1.py +40 -0
- crosshair/libimpl/encodings/utf_8.py +93 -0
- crosshair/libimpl/encodings_ch_test.py +83 -0
- crosshair/libimpl/fractionlib.py +16 -0
- crosshair/libimpl/fractionlib_test.py +80 -0
- crosshair/libimpl/functoolslib.py +34 -0
- crosshair/libimpl/functoolslib_test.py +56 -0
- crosshair/libimpl/hashliblib.py +30 -0
- crosshair/libimpl/hashliblib_test.py +18 -0
- crosshair/libimpl/heapqlib.py +47 -0
- crosshair/libimpl/heapqlib_test.py +21 -0
- crosshair/libimpl/importliblib.py +18 -0
- crosshair/libimpl/importliblib_test.py +38 -0
- crosshair/libimpl/iolib.py +216 -0
- crosshair/libimpl/iolib_ch_test.py +128 -0
- crosshair/libimpl/iolib_test.py +19 -0
- crosshair/libimpl/ipaddresslib.py +8 -0
- crosshair/libimpl/itertoolslib.py +44 -0
- crosshair/libimpl/itertoolslib_test.py +44 -0
- crosshair/libimpl/jsonlib.py +984 -0
- crosshair/libimpl/jsonlib_ch_test.py +42 -0
- crosshair/libimpl/jsonlib_test.py +51 -0
- crosshair/libimpl/mathlib.py +179 -0
- crosshair/libimpl/mathlib_ch_test.py +44 -0
- crosshair/libimpl/mathlib_test.py +67 -0
- crosshair/libimpl/oslib.py +7 -0
- crosshair/libimpl/pathliblib_test.py +10 -0
- crosshair/libimpl/randomlib.py +178 -0
- crosshair/libimpl/randomlib_test.py +120 -0
- crosshair/libimpl/relib.py +846 -0
- crosshair/libimpl/relib_ch_test.py +169 -0
- crosshair/libimpl/relib_test.py +493 -0
- crosshair/libimpl/timelib.py +72 -0
- crosshair/libimpl/timelib_test.py +82 -0
- crosshair/libimpl/typeslib.py +15 -0
- crosshair/libimpl/typeslib_test.py +36 -0
- crosshair/libimpl/unicodedatalib.py +75 -0
- crosshair/libimpl/unicodedatalib_test.py +42 -0
- crosshair/libimpl/urlliblib.py +23 -0
- crosshair/libimpl/urlliblib_test.py +19 -0
- 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 +261 -0
- crosshair/lsp_server_test.py +30 -0
- crosshair/main.py +973 -0
- crosshair/main_test.py +543 -0
- crosshair/objectproxy.py +376 -0
- crosshair/objectproxy_test.py +41 -0
- crosshair/opcode_intercept.py +601 -0
- crosshair/opcode_intercept_test.py +304 -0
- crosshair/options.py +218 -0
- crosshair/options_test.py +10 -0
- crosshair/patch_equivalence_test.py +75 -0
- crosshair/path_cover.py +209 -0
- crosshair/path_cover_test.py +138 -0
- crosshair/path_search.py +161 -0
- crosshair/path_search_test.py +52 -0
- crosshair/pathing_oracle.py +271 -0
- crosshair/pathing_oracle_test.py +21 -0
- crosshair/pure_importer.py +27 -0
- crosshair/pure_importer_test.py +16 -0
- crosshair/py.typed +0 -0
- crosshair/register_contract.py +273 -0
- crosshair/register_contract_test.py +190 -0
- crosshair/simplestructs.py +1165 -0
- crosshair/simplestructs_test.py +283 -0
- crosshair/smtlib.py +24 -0
- crosshair/smtlib_test.py +14 -0
- crosshair/statespace.py +1199 -0
- crosshair/statespace_test.py +108 -0
- crosshair/stubs_parser.py +352 -0
- crosshair/stubs_parser_test.py +43 -0
- crosshair/test_util.py +329 -0
- crosshair/test_util_test.py +26 -0
- crosshair/tools/__init__.py +0 -0
- crosshair/tools/check_help_in_doc.py +264 -0
- crosshair/tools/check_init_and_setup_coincide.py +119 -0
- crosshair/tools/generate_demo_table.py +127 -0
- crosshair/tracers.py +544 -0
- crosshair/tracers_test.py +154 -0
- crosshair/type_repo.py +151 -0
- crosshair/unicode_categories.py +589 -0
- crosshair/unicode_categories_test.py +27 -0
- crosshair/util.py +741 -0
- crosshair/util_test.py +173 -0
- crosshair/watcher.py +307 -0
- crosshair/watcher_test.py +107 -0
- crosshair/z3util.py +76 -0
- crosshair/z3util_test.py +11 -0
- crosshair_tool-0.0.99.dist-info/METADATA +144 -0
- crosshair_tool-0.0.99.dist-info/RECORD +176 -0
- crosshair_tool-0.0.99.dist-info/WHEEL +6 -0
- crosshair_tool-0.0.99.dist-info/entry_points.txt +3 -0
- crosshair_tool-0.0.99.dist-info/licenses/LICENSE +93 -0
- crosshair_tool-0.0.99.dist-info/top_level.txt +2 -0
crosshair/type_repo.py
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import collections
|
|
2
|
+
import inspect
|
|
3
|
+
import sys
|
|
4
|
+
from typing import Dict, List, Optional, Type
|
|
5
|
+
|
|
6
|
+
import z3 # type: ignore
|
|
7
|
+
|
|
8
|
+
from crosshair.tracers import NoTracing
|
|
9
|
+
from crosshair.util import CrossHairInternal, CrossHairValue, is_hashable
|
|
10
|
+
from crosshair.z3util import z3Eq, z3Not
|
|
11
|
+
|
|
12
|
+
_MAP: Optional[Dict[type, List[type]]] = None
|
|
13
|
+
|
|
14
|
+
_IGNORED_MODULE_ROOTS = {
|
|
15
|
+
# CrossHair will get confused if we try to proxy our own types:
|
|
16
|
+
"crosshair",
|
|
17
|
+
"z3",
|
|
18
|
+
# These are disabled for performance or type search effectiveness:
|
|
19
|
+
"hypothesis",
|
|
20
|
+
"pkg_resources",
|
|
21
|
+
"pytest",
|
|
22
|
+
"py", # (part of pytest)
|
|
23
|
+
# Disabled because the import attempt can cause problems:
|
|
24
|
+
"numpy", # importing numpy/testing/_private/utils.py attempts a subprocess call
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _add_class(cls: type) -> None:
|
|
29
|
+
"""Add a class just for testing purposes."""
|
|
30
|
+
global _MAP
|
|
31
|
+
get_subclass_map() # ensure we're initialized
|
|
32
|
+
assert _MAP is not None
|
|
33
|
+
for base in cls.__bases__:
|
|
34
|
+
subs = _MAP[base]
|
|
35
|
+
if cls not in subs:
|
|
36
|
+
subs.append(cls)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
_UNSAFE_MEMBERS = frozenset(
|
|
40
|
+
["__copy___", "__deepcopy__", "__reduce_ex__", "__reduce__"]
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _class_known_to_be_copyable(cls: type) -> bool:
|
|
45
|
+
if _UNSAFE_MEMBERS & cls.__dict__.keys():
|
|
46
|
+
return False
|
|
47
|
+
return True
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_subclass_map() -> Dict[type, List[type]]:
|
|
51
|
+
"""
|
|
52
|
+
Crawl all types presently in memory and makes a map from parent to child classes.
|
|
53
|
+
|
|
54
|
+
Only direct children are included.
|
|
55
|
+
TODO: Does not yet handle "protocol" subclassing (eg "Iterator", "Mapping", etc).
|
|
56
|
+
"""
|
|
57
|
+
global _MAP
|
|
58
|
+
if _MAP is None:
|
|
59
|
+
classes = set()
|
|
60
|
+
for module_name, module in list(sys.modules.items()):
|
|
61
|
+
if module_name.split(".", 1)[0] in _IGNORED_MODULE_ROOTS:
|
|
62
|
+
continue
|
|
63
|
+
if module is None:
|
|
64
|
+
continue
|
|
65
|
+
try:
|
|
66
|
+
module_classes = inspect.getmembers(module, inspect.isclass)
|
|
67
|
+
except ImportError:
|
|
68
|
+
continue
|
|
69
|
+
for _, cls in module_classes:
|
|
70
|
+
if _class_known_to_be_copyable(cls) and is_hashable(cls):
|
|
71
|
+
classes.add(cls)
|
|
72
|
+
subclass = collections.defaultdict(list)
|
|
73
|
+
for cls in classes:
|
|
74
|
+
for base in cls.__bases__:
|
|
75
|
+
if base in classes:
|
|
76
|
+
subclass[base].append(cls)
|
|
77
|
+
_MAP = subclass
|
|
78
|
+
return _MAP
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def rebuild_subclass_map():
|
|
82
|
+
global _MAP
|
|
83
|
+
_MAP = None
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _make_maybe_sort():
|
|
87
|
+
datatype = z3.Datatype("optional_bool")
|
|
88
|
+
datatype.declare("yes")
|
|
89
|
+
datatype.declare("no")
|
|
90
|
+
datatype.declare("exception")
|
|
91
|
+
return datatype.create()
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
MAYBE_SORT = _make_maybe_sort()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _pyissubclass(pytype1: Type, pytype2: Type) -> z3.ExprRef:
|
|
98
|
+
try:
|
|
99
|
+
return MAYBE_SORT.yes if issubclass(pytype1, pytype2) else MAYBE_SORT.no
|
|
100
|
+
except Exception:
|
|
101
|
+
return MAYBE_SORT.exception
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
PYTYPE_SORT = z3.DeclareSort("pytype_sort")
|
|
105
|
+
|
|
106
|
+
SMT_SUBTYPE_FN = z3.Function(
|
|
107
|
+
"pytype_sort_subtype", PYTYPE_SORT, PYTYPE_SORT, MAYBE_SORT
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class SymbolicTypeRepository:
|
|
112
|
+
pytype_to_smt: Dict[Type, z3.ExprRef]
|
|
113
|
+
|
|
114
|
+
def __init__(self, solver: z3.Solver):
|
|
115
|
+
self.pytype_to_smt = {}
|
|
116
|
+
self.solver = solver
|
|
117
|
+
|
|
118
|
+
def smt_can_subclass(self, typ1: z3.ExprRef, typ2: z3.ExprRef) -> z3.ExprRef:
|
|
119
|
+
return SMT_SUBTYPE_FN(typ1, typ2) != MAYBE_SORT.exception
|
|
120
|
+
|
|
121
|
+
def smt_issubclass(self, typ1: z3.ExprRef, typ2: z3.ExprRef) -> z3.ExprRef:
|
|
122
|
+
return SMT_SUBTYPE_FN(typ1, typ2) == MAYBE_SORT.yes
|
|
123
|
+
|
|
124
|
+
def get_type(self, typ: Type) -> z3.ExprRef:
|
|
125
|
+
with NoTracing():
|
|
126
|
+
if issubclass(typ, CrossHairValue):
|
|
127
|
+
raise CrossHairInternal(
|
|
128
|
+
"Type repo should not be queried with a symbolic"
|
|
129
|
+
)
|
|
130
|
+
pytype_to_smt = self.pytype_to_smt
|
|
131
|
+
if typ not in pytype_to_smt:
|
|
132
|
+
stmts = []
|
|
133
|
+
expr = z3.Const(f"typrepo_{typ.__qualname__}_{id(typ):x}", PYTYPE_SORT)
|
|
134
|
+
for other_pytype, other_expr in pytype_to_smt.items():
|
|
135
|
+
stmts.append(z3Not(z3Eq(other_expr, expr)))
|
|
136
|
+
stmts.append(
|
|
137
|
+
z3Eq(
|
|
138
|
+
SMT_SUBTYPE_FN(expr, other_expr),
|
|
139
|
+
_pyissubclass(typ, other_pytype),
|
|
140
|
+
)
|
|
141
|
+
)
|
|
142
|
+
stmts.append(
|
|
143
|
+
z3Eq(
|
|
144
|
+
SMT_SUBTYPE_FN(other_expr, expr),
|
|
145
|
+
_pyissubclass(other_pytype, typ),
|
|
146
|
+
)
|
|
147
|
+
)
|
|
148
|
+
stmts.append(z3Eq(SMT_SUBTYPE_FN(expr, expr), _pyissubclass(typ, typ)))
|
|
149
|
+
self.solver.add(stmts)
|
|
150
|
+
pytype_to_smt[typ] = expr
|
|
151
|
+
return pytype_to_smt[typ]
|