crosshair-tool 0.0.96__cp311-cp311-macosx_10_9_x86_64.whl → 0.0.97__cp311-cp311-macosx_10_9_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.
Potentially problematic release.
This version of crosshair-tool might be problematic. Click here for more details.
- _crosshair_tracers.cpython-311-darwin.so +0 -0
- crosshair/__init__.py +1 -1
- crosshair/_tracers_test.py +5 -5
- crosshair/codeconfig.py +3 -2
- crosshair/condition_parser.py +1 -0
- crosshair/core.py +6 -8
- crosshair/dynamic_typing.py +3 -3
- crosshair/enforce.py +1 -0
- crosshair/examples/check_examples_test.py +1 -0
- crosshair/fnutil.py +2 -3
- crosshair/fnutil_test.py +1 -4
- crosshair/fuzz_core_test.py +9 -1
- crosshair/libimpl/arraylib.py +1 -1
- crosshair/libimpl/builtinslib.py +12 -8
- crosshair/libimpl/builtinslib_ch_test.py +3 -3
- crosshair/libimpl/builtinslib_test.py +2 -1
- crosshair/libimpl/datetimelib.py +1 -3
- crosshair/libimpl/datetimelib_ch_test.py +5 -5
- crosshair/libimpl/encodings/_encutil.py +11 -6
- crosshair/libimpl/relib.py +1 -1
- crosshair/libimpl/unicodedatalib_test.py +3 -3
- crosshair/main.py +5 -3
- crosshair/opcode_intercept.py +37 -1
- crosshair/pathing_oracle.py +1 -1
- crosshair/pathing_oracle_test.py +1 -1
- crosshair/register_contract.py +1 -0
- crosshair/register_contract_test.py +2 -4
- crosshair/simplestructs.py +10 -8
- crosshair/statespace.py +1 -1
- crosshair/tools/generate_demo_table.py +2 -2
- crosshair/tracers.py +8 -6
- crosshair/util.py +6 -6
- {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/METADATA +4 -5
- {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/RECORD +38 -38
- {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/WHEEL +0 -0
- {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/entry_points.txt +0 -0
- {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/licenses/LICENSE +0 -0
- {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/top_level.txt +0 -0
|
Binary file
|
crosshair/__init__.py
CHANGED
|
@@ -15,7 +15,7 @@ from crosshair.statespace import StateSpace
|
|
|
15
15
|
from crosshair.tracers import NoTracing, ResumedTracing
|
|
16
16
|
from crosshair.util import IgnoreAttempt, debug
|
|
17
17
|
|
|
18
|
-
__version__ = "0.0.
|
|
18
|
+
__version__ = "0.0.97" # Do not forget to update in setup.py!
|
|
19
19
|
__author__ = "Phillip Schanely"
|
|
20
20
|
__license__ = "MIT"
|
|
21
21
|
__status__ = "Alpha"
|
crosshair/_tracers_test.py
CHANGED
|
@@ -19,19 +19,19 @@ class ExampleModule:
|
|
|
19
19
|
|
|
20
20
|
def test_CTracer_module_refcounts_dont_leak():
|
|
21
21
|
mod = ExampleModule()
|
|
22
|
-
|
|
22
|
+
base_count = sys.getrefcount(mod)
|
|
23
23
|
tracer = CTracer()
|
|
24
24
|
tracer.push_module(mod)
|
|
25
|
-
assert sys.getrefcount(mod) ==
|
|
25
|
+
assert sys.getrefcount(mod) == base_count + 1
|
|
26
26
|
tracer.push_module(mod)
|
|
27
27
|
tracer.start()
|
|
28
28
|
tracer.stop()
|
|
29
|
-
assert sys.getrefcount(mod) ==
|
|
29
|
+
assert sys.getrefcount(mod) == base_count + 2
|
|
30
30
|
tracer.pop_module(mod)
|
|
31
|
-
assert sys.getrefcount(mod) ==
|
|
31
|
+
assert sys.getrefcount(mod) == base_count + 1
|
|
32
32
|
del tracer
|
|
33
33
|
gc.collect()
|
|
34
|
-
assert sys.getrefcount(mod) ==
|
|
34
|
+
assert sys.getrefcount(mod) == base_count
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
def _get_depths(fn):
|
crosshair/codeconfig.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Configure analysis options at different levels."""
|
|
2
|
+
|
|
2
3
|
import importlib.resources
|
|
3
4
|
import inspect
|
|
4
5
|
import re
|
|
@@ -25,7 +26,7 @@ def get_directives(source_text: str) -> Iterable[Tuple[int, int, str]]:
|
|
|
25
26
|
ret = []
|
|
26
27
|
tokens = tokenize.generate_tokens(StringIO(source_text).readline)
|
|
27
28
|
# TODO catch tokenize.TokenError ... just in case?
|
|
28
|
-
for
|
|
29
|
+
for toktyp, tokval, begin, _, _ in tokens:
|
|
29
30
|
linenum, colnum = begin
|
|
30
31
|
if toktyp == tokenize.COMMENT:
|
|
31
32
|
directive = _COMMENT_TOKEN_RE.sub(r"\1", tokval)
|
|
@@ -39,7 +40,7 @@ class InvalidDirective(Exception):
|
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
def parse_directives(
|
|
42
|
-
directive_lines: Iterable[Tuple[int, int, str]]
|
|
43
|
+
directive_lines: Iterable[Tuple[int, int, str]],
|
|
43
44
|
) -> AnalysisOptionSet:
|
|
44
45
|
"""
|
|
45
46
|
Parse options from directives in comments.
|
crosshair/condition_parser.py
CHANGED
|
@@ -520,6 +520,7 @@ class ConcreteConditionParser(ConditionParser):
|
|
|
520
520
|
"__delattr__",
|
|
521
521
|
"__replace__", # Will raise an exception with most arbitrary **kwargs.
|
|
522
522
|
"__annotate__", # a staticmethod, but not isinstance(staticmethod)
|
|
523
|
+
"__annotate_func__",
|
|
523
524
|
):
|
|
524
525
|
pass
|
|
525
526
|
elif method_name == "__del__":
|
crosshair/core.py
CHANGED
|
@@ -563,12 +563,12 @@ class SymbolicFactory:
|
|
|
563
563
|
@overload
|
|
564
564
|
def __call__(
|
|
565
565
|
self, typ: Callable[..., _T], suffix: str = "", allow_subtypes: bool = True
|
|
566
|
-
) -> _T:
|
|
567
|
-
...
|
|
566
|
+
) -> _T: ...
|
|
568
567
|
|
|
569
568
|
@overload
|
|
570
|
-
def __call__(
|
|
571
|
-
|
|
569
|
+
def __call__(
|
|
570
|
+
self, typ: Any, suffix: str = "", allow_subtypes: bool = True
|
|
571
|
+
) -> Any: ...
|
|
572
572
|
|
|
573
573
|
def __call__(self, typ, suffix: str = "", allow_subtypes: bool = True):
|
|
574
574
|
"""
|
|
@@ -653,8 +653,7 @@ def proxy_for_type(
|
|
|
653
653
|
typ: Callable[..., _T],
|
|
654
654
|
varname: str,
|
|
655
655
|
allow_subtypes: bool = False,
|
|
656
|
-
) -> _T:
|
|
657
|
-
...
|
|
656
|
+
) -> _T: ...
|
|
658
657
|
|
|
659
658
|
|
|
660
659
|
@overload
|
|
@@ -662,8 +661,7 @@ def proxy_for_type(
|
|
|
662
661
|
typ: Any,
|
|
663
662
|
varname: str,
|
|
664
663
|
allow_subtypes: bool = False,
|
|
665
|
-
) -> Any:
|
|
666
|
-
...
|
|
664
|
+
) -> Any: ...
|
|
667
665
|
|
|
668
666
|
|
|
669
667
|
def proxy_for_type(
|
crosshair/dynamic_typing.py
CHANGED
|
@@ -59,7 +59,7 @@ def unify_callable_args(
|
|
|
59
59
|
return True
|
|
60
60
|
if len(value_types) != len(recv_types):
|
|
61
61
|
return False
|
|
62
|
-
for
|
|
62
|
+
for varg, rarg in zip(value_types, recv_types):
|
|
63
63
|
# note reversal here: Callable is contravariant in argument types
|
|
64
64
|
if not unify(rarg, varg, bindings):
|
|
65
65
|
return False
|
|
@@ -206,7 +206,7 @@ def unify(
|
|
|
206
206
|
vargs = [object for _ in rargs]
|
|
207
207
|
else:
|
|
208
208
|
return False
|
|
209
|
-
for
|
|
209
|
+
for varg, targ in zip(vargs, rargs):
|
|
210
210
|
if not unify(varg, targ, bindings):
|
|
211
211
|
return False
|
|
212
212
|
return True
|
|
@@ -302,7 +302,7 @@ def intersect_signatures(
|
|
|
302
302
|
is_squishy1 = var_pos1 is not None or var_key1 is not None
|
|
303
303
|
is_squishy2 = var_pos2 is not None or var_key2 is not None
|
|
304
304
|
out_params: Dict[str, Parameter] = {}
|
|
305
|
-
for
|
|
305
|
+
for p1, p2 in zip_longest(pos1, pos2):
|
|
306
306
|
if p1 is None:
|
|
307
307
|
if is_squishy1:
|
|
308
308
|
out_params[p2.name] = p2
|
crosshair/enforce.py
CHANGED
|
@@ -36,6 +36,7 @@ def WithEnforcement(fn: Callable) -> Callable:
|
|
|
36
36
|
Enforcement is normally disabled when calling from some internal files, for
|
|
37
37
|
performance reasons. Use WithEnforcement to ensure it is enabled anywhere.
|
|
38
38
|
"""
|
|
39
|
+
|
|
39
40
|
# This local function has a special name that we look for while tracing
|
|
40
41
|
# (see the wants_codeobj method below):
|
|
41
42
|
def _crosshair_with_enforcement(*a, **kw):
|
crosshair/fnutil.py
CHANGED
|
@@ -41,8 +41,7 @@ if sys.version_info >= (3, 8):
|
|
|
41
41
|
from typing import Protocol
|
|
42
42
|
|
|
43
43
|
class Descriptor(Protocol):
|
|
44
|
-
def __get__(self, instance: object, cls: type) -> Any:
|
|
45
|
-
...
|
|
44
|
+
def __get__(self, instance: object, cls: type) -> Any: ...
|
|
46
45
|
|
|
47
46
|
else:
|
|
48
47
|
Descriptor = Any
|
|
@@ -344,7 +343,7 @@ def walk_paths(paths: Iterable[Path], ignore_missing=False) -> Iterable[Path]:
|
|
|
344
343
|
else:
|
|
345
344
|
raise FileNotFoundError(str(path))
|
|
346
345
|
if path.is_dir():
|
|
347
|
-
for
|
|
346
|
+
for dirpath, _dirs, files in os.walk(str(path)):
|
|
348
347
|
for curfile in files:
|
|
349
348
|
if analyzable_filename(curfile):
|
|
350
349
|
yield Path(dirpath) / curfile
|
crosshair/fnutil_test.py
CHANGED
|
@@ -26,10 +26,7 @@ def test_fn_globals_on_builtin() -> None:
|
|
|
26
26
|
|
|
27
27
|
def test_resolve_signature_invalid_annotations() -> None:
|
|
28
28
|
sig = resolve_signature(with_invalid_type_annotation)
|
|
29
|
-
|
|
30
|
-
assert sig == "TypeThatIsNotDefined"
|
|
31
|
-
else:
|
|
32
|
-
assert sig == "name 'TypeThatIsNotDefined' is not defined"
|
|
29
|
+
assert sig == "name 'TypeThatIsNotDefined' is not defined"
|
|
33
30
|
|
|
34
31
|
|
|
35
32
|
@pytest.mark.skipif(
|
crosshair/fuzz_core_test.py
CHANGED
|
@@ -47,7 +47,7 @@ from crosshair.statespace import (
|
|
|
47
47
|
from crosshair.stubs_parser import signature_from_stubs
|
|
48
48
|
from crosshair.test_util import flexible_equal
|
|
49
49
|
from crosshair.tracers import COMPOSITE_TRACER, NoTracing, ResumedTracing
|
|
50
|
-
from crosshair.util import CrosshairUnsupported, debug, type_args_of
|
|
50
|
+
from crosshair.util import CrosshairUnsupported, debug, is_iterable, type_args_of
|
|
51
51
|
|
|
52
52
|
FUZZ_SEED = 1348
|
|
53
53
|
|
|
@@ -267,6 +267,14 @@ class FuzzTester:
|
|
|
267
267
|
) -> object:
|
|
268
268
|
for name in typed_args.keys():
|
|
269
269
|
literal, symbolic = literal_args[name], symbolic_args[name]
|
|
270
|
+
with NoTracing():
|
|
271
|
+
# TODO: transition into general purpose SMT expr extractor
|
|
272
|
+
# for equality with constant
|
|
273
|
+
if hasattr(symbolic, "_smt_promote_literal"):
|
|
274
|
+
symbolic.var = symbolic._smt_promote_literal(literal) # type: ignore
|
|
275
|
+
elif is_iterable(literal) and is_iterable(symbolic):
|
|
276
|
+
with ResumedTracing():
|
|
277
|
+
space.add(len(literal) == len(symbolic)) # type: ignore
|
|
270
278
|
if literal != symbolic:
|
|
271
279
|
raise IgnoreAttempt(
|
|
272
280
|
f'symbolic "{name}" not equal to literal "{name}"'
|
crosshair/libimpl/arraylib.py
CHANGED
|
@@ -32,7 +32,7 @@ INT_TYPE_SIZE = {c: array(c).itemsize for c in INT_TYPE_BOUNDS.keys()}
|
|
|
32
32
|
|
|
33
33
|
def pick_code(space: StateSpace) -> Tuple[str, int, int]:
|
|
34
34
|
last_idx = len(INT_TYPE_BOUNDS) - 1
|
|
35
|
-
for
|
|
35
|
+
for idx, (code, rng) in enumerate(INT_TYPE_BOUNDS.items()):
|
|
36
36
|
if idx < last_idx:
|
|
37
37
|
if space.smt_fork(desc=f"not_{code}_array"):
|
|
38
38
|
continue
|
crosshair/libimpl/builtinslib.py
CHANGED
|
@@ -189,6 +189,7 @@ def smt_not(x: object) -> Union[bool, "SymbolicBool"]:
|
|
|
189
189
|
|
|
190
190
|
_NONHEAP_PYTYPES = set([int, float, bool, NoneType, complex])
|
|
191
191
|
|
|
192
|
+
|
|
192
193
|
# TODO: isn't this pretty close to isinstance(typ, AtomicSymbolicValue)?
|
|
193
194
|
def pytype_uses_heap(typ: Type) -> bool:
|
|
194
195
|
return not (typ in _NONHEAP_PYTYPES)
|
|
@@ -900,6 +901,7 @@ def setup_binops():
|
|
|
900
901
|
if isinstance(a, FiniteFloat)
|
|
901
902
|
else a.var
|
|
902
903
|
)
|
|
904
|
+
assert smt_a is not None
|
|
903
905
|
if isinstance(b, NonFiniteFloat):
|
|
904
906
|
if isnan(b.val):
|
|
905
907
|
return (nan, nan)
|
|
@@ -912,6 +914,7 @@ def setup_binops():
|
|
|
912
914
|
return (-1.0, b.val)
|
|
913
915
|
else:
|
|
914
916
|
return (0.0, a.val if isinstance(a, FiniteFloat) else a)
|
|
917
|
+
assert smt_b is not None
|
|
915
918
|
|
|
916
919
|
remainder = z3.Real(f"remainder{space.uniq()}")
|
|
917
920
|
modproduct = z3.Int(f"modproduct{space.uniq()}")
|
|
@@ -1591,6 +1594,7 @@ class RealBasedSymbolicFloat(SymbolicFloat):
|
|
|
1591
1594
|
denominator = SymbolicInt("denominator" + space.uniq())
|
|
1592
1595
|
space.add(denominator.var > 0)
|
|
1593
1596
|
space.add(numerator.var == denominator.var * self.var)
|
|
1597
|
+
|
|
1594
1598
|
# There are many valid integer ratios to return. Experimentally, both
|
|
1595
1599
|
# z3 and CPython tend to pick the same ones. But verify this, while
|
|
1596
1600
|
# deferring materialization:
|
|
@@ -2330,7 +2334,7 @@ class SymbolicRange:
|
|
|
2330
2334
|
return False
|
|
2331
2335
|
if len(self) != len(other):
|
|
2332
2336
|
return False
|
|
2333
|
-
for
|
|
2337
|
+
for v1, v2 in zip(self, other):
|
|
2334
2338
|
if v1 != v2:
|
|
2335
2339
|
return False
|
|
2336
2340
|
return True
|
|
@@ -2783,7 +2787,7 @@ class SymbolicBoundedIntTuple(collections.abc.Sequence):
|
|
|
2783
2787
|
with NoTracing():
|
|
2784
2788
|
self._create_up_to(realize(otherlen))
|
|
2785
2789
|
constraints = []
|
|
2786
|
-
for
|
|
2790
|
+
for int1, int2 in zip(self._created_vars, tracing_iter(other)):
|
|
2787
2791
|
smtint2 = force_to_smt_sort(int2, SymbolicInt)
|
|
2788
2792
|
constraints.append(int1.var == smtint2)
|
|
2789
2793
|
return SymbolicBool(z3.And(*constraints))
|
|
@@ -2910,7 +2914,7 @@ class AnySymbolicStr(AbcString):
|
|
|
2910
2914
|
raise TypeError
|
|
2911
2915
|
if self == other:
|
|
2912
2916
|
return True if op in (ops.le, ops.ge) else False
|
|
2913
|
-
for
|
|
2917
|
+
for mych, otherch in zip_longest(iter(self), iter(other)):
|
|
2914
2918
|
if mych == otherch:
|
|
2915
2919
|
continue
|
|
2916
2920
|
if mych is None:
|
|
@@ -3172,7 +3176,7 @@ class AnySymbolicStr(AbcString):
|
|
|
3172
3176
|
|
|
3173
3177
|
else:
|
|
3174
3178
|
raise TypeError
|
|
3175
|
-
for
|
|
3179
|
+
for idx, ch in enumerate(self):
|
|
3176
3180
|
if not filter(ch):
|
|
3177
3181
|
return self[idx:]
|
|
3178
3182
|
return ""
|
|
@@ -3184,7 +3188,7 @@ class AnySymbolicStr(AbcString):
|
|
|
3184
3188
|
mylen = self.__len__()
|
|
3185
3189
|
if mylen == 0:
|
|
3186
3190
|
return []
|
|
3187
|
-
for
|
|
3191
|
+
for idx, ch in enumerate(self):
|
|
3188
3192
|
codepoint = ord(ch)
|
|
3189
3193
|
with NoTracing():
|
|
3190
3194
|
space = context_statespace()
|
|
@@ -4008,7 +4012,7 @@ class SymbolicByteArray(BytesLike, ShellMutableSequence): # type: ignore
|
|
|
4008
4012
|
|
|
4009
4013
|
|
|
4010
4014
|
class SymbolicMemoryView(BytesLike):
|
|
4011
|
-
format = "B"
|
|
4015
|
+
format = "B" # type: ignore
|
|
4012
4016
|
itemsize = 1
|
|
4013
4017
|
ndim = 1
|
|
4014
4018
|
strides = (1,)
|
|
@@ -4817,11 +4821,11 @@ def _str_percent_format(self, other):
|
|
|
4817
4821
|
return self.__mod__(deep_realize(other))
|
|
4818
4822
|
|
|
4819
4823
|
|
|
4820
|
-
def _bytes_join(self, itr) ->
|
|
4824
|
+
def _bytes_join(self, itr) -> bytes:
|
|
4821
4825
|
return _join(self, itr, self_type=bytes, item_type=Buffer)
|
|
4822
4826
|
|
|
4823
4827
|
|
|
4824
|
-
def _bytearray_join(self, itr) ->
|
|
4828
|
+
def _bytearray_join(self, itr) -> bytes:
|
|
4825
4829
|
return _join(self, itr, self_type=bytearray, item_type=Buffer)
|
|
4826
4830
|
|
|
4827
4831
|
|
|
@@ -178,7 +178,7 @@ def check_iter(obj: Union[str, List[int], Dict[int, int]]) -> ResultComparison:
|
|
|
178
178
|
|
|
179
179
|
|
|
180
180
|
def check_len(
|
|
181
|
-
s: Union[Dict[int, int], Tuple[int, ...], str, List[int], Set[int]]
|
|
181
|
+
s: Union[Dict[int, int], Tuple[int, ...], str, List[int], Set[int]],
|
|
182
182
|
) -> ResultComparison:
|
|
183
183
|
"""post: _"""
|
|
184
184
|
return compare_results(len, s)
|
|
@@ -984,7 +984,7 @@ def check_bytes___init__(source: Union[int, List[int], bytes, bytearray, memoryv
|
|
|
984
984
|
|
|
985
985
|
|
|
986
986
|
def check_bytearray___init__(
|
|
987
|
-
source: Union[int, List[int], bytes, bytearray, memoryview]
|
|
987
|
+
source: Union[int, List[int], bytes, bytearray, memoryview],
|
|
988
988
|
):
|
|
989
989
|
"""
|
|
990
990
|
post: _
|
|
@@ -994,7 +994,7 @@ def check_bytearray___init__(
|
|
|
994
994
|
|
|
995
995
|
|
|
996
996
|
def check_memoryview___init__(
|
|
997
|
-
source: Union[int, List[int], bytes, bytearray, memoryview]
|
|
997
|
+
source: Union[int, List[int], bytes, bytearray, memoryview],
|
|
998
998
|
):
|
|
999
999
|
"""
|
|
1000
1000
|
post: _
|
|
@@ -1450,7 +1450,7 @@ def test_str_lower():
|
|
|
1450
1450
|
|
|
1451
1451
|
|
|
1452
1452
|
def test_str_title():
|
|
1453
|
-
chr_lj = "\
|
|
1453
|
+
chr_lj = "\u01c9" # "lj"
|
|
1454
1454
|
chr_Lj = "\u01c8" # "Lj" (different from "LJ", "\u01c7")
|
|
1455
1455
|
with standalone_statespace:
|
|
1456
1456
|
with NoTracing():
|
|
@@ -2649,6 +2649,7 @@ if sys.version_info >= (3, 9):
|
|
|
2649
2649
|
def test_set_basic_fail() -> None:
|
|
2650
2650
|
def f(a: Set[int], k: int) -> None:
|
|
2651
2651
|
"""
|
|
2652
|
+
pre: len(a) <= 2
|
|
2652
2653
|
post[a]: k+1 in a
|
|
2653
2654
|
"""
|
|
2654
2655
|
a.add(k)
|
crosshair/libimpl/datetimelib.py
CHANGED
|
@@ -627,9 +627,7 @@ class timedelta:
|
|
|
627
627
|
|
|
628
628
|
def total_seconds(self):
|
|
629
629
|
"""Total seconds in the duration."""
|
|
630
|
-
return (
|
|
631
|
-
(self.days * 86400 + self.seconds) * 10**6 + self.microseconds
|
|
632
|
-
) / 10**6
|
|
630
|
+
return ((self.days * 86400 + self.seconds) * 10**6 + self.microseconds) / 10**6
|
|
633
631
|
|
|
634
632
|
# Read-only field accessors
|
|
635
633
|
@property
|
|
@@ -29,7 +29,7 @@ def check_datetimelib_lt(
|
|
|
29
29
|
Tuple[timedelta, timedelta],
|
|
30
30
|
Tuple[date, datetime],
|
|
31
31
|
Tuple[datetime, datetime],
|
|
32
|
-
]
|
|
32
|
+
],
|
|
33
33
|
) -> ResultComparison:
|
|
34
34
|
"""post: _"""
|
|
35
35
|
return compare_results(operator.lt, *p)
|
|
@@ -40,7 +40,7 @@ def check_datetimelib_add(
|
|
|
40
40
|
Tuple[timedelta, timedelta],
|
|
41
41
|
Tuple[date, timedelta],
|
|
42
42
|
Tuple[timedelta, datetime],
|
|
43
|
-
]
|
|
43
|
+
],
|
|
44
44
|
) -> ResultComparison:
|
|
45
45
|
"""post: _"""
|
|
46
46
|
return compare_results(operator.add, *p)
|
|
@@ -52,14 +52,14 @@ def check_datetimelib_subtract(
|
|
|
52
52
|
Tuple[date, timedelta],
|
|
53
53
|
Tuple[datetime, timedelta],
|
|
54
54
|
Tuple[datetime, datetime],
|
|
55
|
-
]
|
|
55
|
+
],
|
|
56
56
|
) -> ResultComparison:
|
|
57
57
|
"""post: _"""
|
|
58
58
|
return compare_results(operator.sub, *p)
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
def check_datetimelib_str(
|
|
62
|
-
obj: Union[timedelta, timezone, date, time, datetime]
|
|
62
|
+
obj: Union[timedelta, timezone, date, time, datetime],
|
|
63
63
|
) -> ResultComparison:
|
|
64
64
|
"""post: _"""
|
|
65
65
|
return compare_results(_invoker("__str__"), obj)
|
|
@@ -67,7 +67,7 @@ def check_datetimelib_str(
|
|
|
67
67
|
|
|
68
68
|
def check_datetimelib_repr(
|
|
69
69
|
# TODO: re-enable time, datetime repr checking after fixing in Python 3.11
|
|
70
|
-
obj: Union[timedelta, timezone, date]
|
|
70
|
+
obj: Union[timedelta, timezone, date],
|
|
71
71
|
) -> ResultComparison:
|
|
72
72
|
"""post: _"""
|
|
73
73
|
return compare_results(_invoker("__repr__"), obj)
|
|
@@ -25,6 +25,7 @@ class UnexpectedEndError(ChunkError):
|
|
|
25
25
|
@dataclass
|
|
26
26
|
class MidChunkError(ChunkError):
|
|
27
27
|
_reason: str
|
|
28
|
+
|
|
28
29
|
# _errlen: int = 1
|
|
29
30
|
def reason(self) -> str:
|
|
30
31
|
return self._reason
|
|
@@ -112,7 +113,7 @@ class StemEncoder:
|
|
|
112
113
|
continue
|
|
113
114
|
if errors == "replace":
|
|
114
115
|
idx += 1
|
|
115
|
-
parts.append("\
|
|
116
|
+
parts.append("\ufffd")
|
|
116
117
|
continue
|
|
117
118
|
|
|
118
119
|
# 2. Then fall back to native implementations if necessary:
|
|
@@ -132,24 +133,28 @@ class StemEncoder:
|
|
|
132
133
|
|
|
133
134
|
def _getregentry(stem_encoder: Type[StemEncoder]):
|
|
134
135
|
class StemIncrementalEncoder(codecs.BufferedIncrementalEncoder):
|
|
135
|
-
def _buffer_encode(
|
|
136
|
+
def _buffer_encode(
|
|
137
|
+
self, input: str, errors: str, final: bool
|
|
138
|
+
) -> Tuple[bytes, int]:
|
|
136
139
|
enc_name = stem_encoder.encoding_name
|
|
137
140
|
out, idx, err = stem_encoder._encode_chunk(input, 0)
|
|
138
141
|
assert isinstance(out, bytes)
|
|
139
142
|
if not err:
|
|
140
|
-
return out
|
|
143
|
+
return (out, idx)
|
|
141
144
|
if isinstance(err, UnexpectedEndError) or not final:
|
|
142
|
-
return out
|
|
145
|
+
return (out, idx)
|
|
143
146
|
exc = UnicodeEncodeError(enc_name, input, idx, idx + 1, err.reason())
|
|
144
147
|
replacement, idx = codecs.lookup_error(errors)(exc)
|
|
145
148
|
if isinstance(replacement, str):
|
|
146
149
|
replacement = codecs.encode(replacement, enc_name)
|
|
147
|
-
return out + replacement
|
|
150
|
+
return (out + replacement, idx)
|
|
148
151
|
|
|
149
152
|
class StemIncrementalDecoder(codecs.BufferedIncrementalDecoder):
|
|
150
153
|
def _buffer_decode(
|
|
151
|
-
self, input:
|
|
154
|
+
self, input: Buffer, errors: str, final: bool
|
|
152
155
|
) -> Tuple[str, int]:
|
|
156
|
+
if not isinstance(input, bytes):
|
|
157
|
+
input = memoryview(input).tobytes()
|
|
153
158
|
enc_name = stem_encoder.encoding_name
|
|
154
159
|
out, idx, err = stem_encoder._decode_chunk(input, 0)
|
|
155
160
|
assert isinstance(out, str)
|
crosshair/libimpl/relib.py
CHANGED
|
@@ -7,7 +7,7 @@ from unicodedata import category
|
|
|
7
7
|
if sys.version_info < (3, 11):
|
|
8
8
|
import sre_parse as re_parser
|
|
9
9
|
else:
|
|
10
|
-
import re._parser as re_parser
|
|
10
|
+
import re._parser as re_parser # type: ignore
|
|
11
11
|
|
|
12
12
|
from sys import maxunicode
|
|
13
13
|
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union, cast
|
|
@@ -11,7 +11,7 @@ def test_numeric():
|
|
|
11
11
|
with standalone_statespace as space:
|
|
12
12
|
with NoTracing():
|
|
13
13
|
fourstr = LazyIntSymbolicStr(list(map(ord, "4")))
|
|
14
|
-
halfstr = LazyIntSymbolicStr(list(map(ord, "\
|
|
14
|
+
halfstr = LazyIntSymbolicStr(list(map(ord, "\u00bd"))) # (1/2 character)
|
|
15
15
|
four = unicodedata.numeric(fourstr)
|
|
16
16
|
half = unicodedata.numeric(halfstr)
|
|
17
17
|
assert type(four) is float
|
|
@@ -22,7 +22,7 @@ def test_numeric():
|
|
|
22
22
|
def test_decimal():
|
|
23
23
|
with standalone_statespace as space:
|
|
24
24
|
with NoTracing():
|
|
25
|
-
thai4 = LazyIntSymbolicStr(list(map(ord, "\
|
|
25
|
+
thai4 = LazyIntSymbolicStr(list(map(ord, "\u0e54"))) # (Thai numerial 4)
|
|
26
26
|
super4 = LazyIntSymbolicStr(list(map(ord, "\u2074"))) # (superscript 4)
|
|
27
27
|
four = unicodedata.decimal(thai4)
|
|
28
28
|
assert type(four) is int
|
|
@@ -34,7 +34,7 @@ def test_decimal():
|
|
|
34
34
|
def test_digit():
|
|
35
35
|
with standalone_statespace as space:
|
|
36
36
|
with NoTracing():
|
|
37
|
-
thai4 = LazyIntSymbolicStr(list(map(ord, "\
|
|
37
|
+
thai4 = LazyIntSymbolicStr(list(map(ord, "\u0e54"))) # (Thai numerial 4)
|
|
38
38
|
super4 = LazyIntSymbolicStr(list(map(ord, "\u2074"))) # (superscript 4)
|
|
39
39
|
four = unicodedata.digit(thai4)
|
|
40
40
|
assert type(four) is int
|
crosshair/main.py
CHANGED
|
@@ -774,9 +774,11 @@ def cover(
|
|
|
774
774
|
ctxfn,
|
|
775
775
|
options,
|
|
776
776
|
args.coverage_type,
|
|
777
|
-
arg_formatter=
|
|
778
|
-
|
|
779
|
-
|
|
777
|
+
arg_formatter=(
|
|
778
|
+
format_boundargs_as_dictionary
|
|
779
|
+
if example_output_format == ExampleOutputFormat.ARG_DICTIONARY
|
|
780
|
+
else format_boundargs
|
|
781
|
+
),
|
|
780
782
|
)
|
|
781
783
|
except NotDeterministic:
|
|
782
784
|
print(
|
crosshair/opcode_intercept.py
CHANGED
|
@@ -7,7 +7,7 @@ from sys import version_info
|
|
|
7
7
|
from types import CodeType, FrameType
|
|
8
8
|
from typing import Any, Callable, Iterable, List, Mapping, Tuple, Union
|
|
9
9
|
|
|
10
|
-
from z3 import ExprRef
|
|
10
|
+
from z3 import ExprRef # type: ignore
|
|
11
11
|
|
|
12
12
|
from crosshair.core import (
|
|
13
13
|
ATOMIC_IMMUTABLE_TYPES,
|
|
@@ -55,6 +55,7 @@ TO_BOOL = dis.opmap.get("TO_BOOL", 256)
|
|
|
55
55
|
IS_OP = dis.opmap.get("IS_OP", 256)
|
|
56
56
|
BINARY_MODULO = dis.opmap.get("BINARY_MODULO", 256)
|
|
57
57
|
BINARY_OP = dis.opmap.get("BINARY_OP", 256)
|
|
58
|
+
LOAD_COMMON_CONSTANT = dis.opmap.get("LOAD_COMMON_CONSTANT", 256)
|
|
58
59
|
|
|
59
60
|
|
|
60
61
|
def frame_op_arg(frame):
|
|
@@ -152,6 +153,39 @@ class MultiSubscriptableContainer:
|
|
|
152
153
|
raise IndexError # (f"Index {key} out of range for list/tuple of length {len(container)}")
|
|
153
154
|
|
|
154
155
|
|
|
156
|
+
class LoadCommonConstantInterceptor(TracingModule):
|
|
157
|
+
"""
|
|
158
|
+
As of 3.14, the bytecode generation process generates optimizations
|
|
159
|
+
for builtins.any/all when invoked on a generator expression.
|
|
160
|
+
It essentially "inlines" the logic as bytecode.
|
|
161
|
+
We need to avoid this.
|
|
162
|
+
Before entering the optimized code path, it will check that the any/all
|
|
163
|
+
function is identity-equal to the original builtin, which is loaded using
|
|
164
|
+
the LOAD_COMMON_CONSTANT opcode.
|
|
165
|
+
|
|
166
|
+
This interceptor replaces that function with a proxy that functions
|
|
167
|
+
identically but is not identity-equal (so that we avoid the optimized
|
|
168
|
+
path),
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
opcodes_wanted = frozenset([LOAD_COMMON_CONSTANT])
|
|
172
|
+
|
|
173
|
+
def trace_op(self, frame, codeobj, codenum):
|
|
174
|
+
CONSTANT_BUILTIN_ALL = 3
|
|
175
|
+
CONSTANT_BUILTIN_ANY = 4
|
|
176
|
+
index = frame_op_arg(frame)
|
|
177
|
+
|
|
178
|
+
def post_op():
|
|
179
|
+
expected_fn = all if index == CONSTANT_BUILTIN_ALL else any
|
|
180
|
+
if CROSSHAIR_EXTRA_ASSERTS:
|
|
181
|
+
if frame_stack_read(frame, -1) is not expected_fn:
|
|
182
|
+
raise CrossHairInternal
|
|
183
|
+
frame_stack_write(frame, -1, lambda *a: expected_fn(*a))
|
|
184
|
+
|
|
185
|
+
if index == CONSTANT_BUILTIN_ALL or index == CONSTANT_BUILTIN_ANY:
|
|
186
|
+
COMPOSITE_TRACER.set_postop_callback(post_op, frame)
|
|
187
|
+
|
|
188
|
+
|
|
155
189
|
class SymbolicSubscriptInterceptor(TracingModule):
|
|
156
190
|
opcodes_wanted = frozenset([BINARY_SUBSCR, BINARY_OP])
|
|
157
191
|
|
|
@@ -554,6 +588,8 @@ def make_registrations():
|
|
|
554
588
|
register_opcode_patch(SymbolicSliceInterceptor())
|
|
555
589
|
if sys.version_info < (3, 9):
|
|
556
590
|
register_opcode_patch(ComparisonInterceptForwarder())
|
|
591
|
+
if sys.version_info >= (3, 14):
|
|
592
|
+
register_opcode_patch(LoadCommonConstantInterceptor())
|
|
557
593
|
register_opcode_patch(ContainmentInterceptor())
|
|
558
594
|
register_opcode_patch(BuildStringInterceptor())
|
|
559
595
|
register_opcode_patch(FormatValueInterceptor())
|
crosshair/pathing_oracle.py
CHANGED
crosshair/pathing_oracle_test.py
CHANGED
crosshair/register_contract.py
CHANGED
|
@@ -99,12 +99,10 @@ def test_register_numpy_randint():
|
|
|
99
99
|
|
|
100
100
|
def test_register_overload():
|
|
101
101
|
@overload
|
|
102
|
-
def overld(a: int) -> int:
|
|
103
|
-
...
|
|
102
|
+
def overld(a: int) -> int: ...
|
|
104
103
|
|
|
105
104
|
@overload
|
|
106
|
-
def overld(a: str) -> str:
|
|
107
|
-
...
|
|
105
|
+
def overld(a: str) -> str: ...
|
|
108
106
|
|
|
109
107
|
def overld(a: Union[int, str]) -> Union[int, str]:
|
|
110
108
|
if isinstance(a, int):
|
crosshair/simplestructs.py
CHANGED
|
@@ -38,10 +38,10 @@ class MapBase(collections.abc.MutableMapping):
|
|
|
38
38
|
return NotImplemented
|
|
39
39
|
if len(self) != len(other):
|
|
40
40
|
return False
|
|
41
|
-
for
|
|
41
|
+
for k, self_value in self.items():
|
|
42
42
|
found = False
|
|
43
43
|
# We do a slow nested loop search because we don't want to hash the key.
|
|
44
|
-
for
|
|
44
|
+
for other_key, other_value in other.items():
|
|
45
45
|
if other_key != k:
|
|
46
46
|
continue
|
|
47
47
|
if self_value == other_value:
|
|
@@ -122,7 +122,7 @@ class SimpleDict(MapBase):
|
|
|
122
122
|
def __getitem__(self, key, default=_MISSING):
|
|
123
123
|
if not is_hashable(key):
|
|
124
124
|
raise TypeError("unhashable type")
|
|
125
|
-
for
|
|
125
|
+
for k, v in self.contents_:
|
|
126
126
|
# Note that the identity check below is not just an optimization;
|
|
127
127
|
# it is required to implement the semantics of NaN dict keys
|
|
128
128
|
if k is key or k == key:
|
|
@@ -134,7 +134,7 @@ class SimpleDict(MapBase):
|
|
|
134
134
|
def __setitem__(self, key, value):
|
|
135
135
|
if not is_hashable(key):
|
|
136
136
|
raise TypeError("unhashable type")
|
|
137
|
-
for
|
|
137
|
+
for i, (k, v) in enumerate(self.contents_):
|
|
138
138
|
if k == key:
|
|
139
139
|
self.contents_[i] = (k, value)
|
|
140
140
|
return
|
|
@@ -143,7 +143,7 @@ class SimpleDict(MapBase):
|
|
|
143
143
|
def __delitem__(self, key):
|
|
144
144
|
if not is_hashable(key):
|
|
145
145
|
raise TypeError("unhashable type")
|
|
146
|
-
for
|
|
146
|
+
for i, (k, v) in enumerate(self.contents_):
|
|
147
147
|
if k == key:
|
|
148
148
|
del self.contents_[i]
|
|
149
149
|
return
|
|
@@ -493,9 +493,11 @@ class SequenceConcatenation(collections.abc.Sequence, SeqBase):
|
|
|
493
493
|
return second.__getitem__(
|
|
494
494
|
slice(
|
|
495
495
|
i.start - firstlen,
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
496
|
+
(
|
|
497
|
+
i.stop
|
|
498
|
+
if i.stop is None or i.stop < 0
|
|
499
|
+
else i.stop - firstlen
|
|
500
|
+
),
|
|
499
501
|
i.step,
|
|
500
502
|
)
|
|
501
503
|
)
|
crosshair/statespace.py
CHANGED
|
@@ -1018,7 +1018,7 @@ class StateSpace:
|
|
|
1018
1018
|
) -> object:
|
|
1019
1019
|
with NoTracing():
|
|
1020
1020
|
# TODO: needs more testing
|
|
1021
|
-
for
|
|
1021
|
+
for curref, curtyp, curval in self.heaps[snapshot]:
|
|
1022
1022
|
|
|
1023
1023
|
# TODO: using unify() is almost certainly wrong; just because the types
|
|
1024
1024
|
# have some instances in common does not mean that `curval` actually
|
|
@@ -107,7 +107,7 @@ def divide_stdlib_module(
|
|
|
107
107
|
modulename: str, items: list[tuple[str, str, str]]
|
|
108
108
|
) -> dict[str, list[tuple[str, str, str]]]:
|
|
109
109
|
ret = defaultdict(list)
|
|
110
|
-
for
|
|
110
|
+
for name, color, src in items:
|
|
111
111
|
if name.endswith("_method"):
|
|
112
112
|
name = name.removesuffix("_method")
|
|
113
113
|
(classname, methodname) = name.split("_", 1)
|
|
@@ -120,7 +120,7 @@ def divide_stdlib_module(
|
|
|
120
120
|
|
|
121
121
|
|
|
122
122
|
stdlib = {}
|
|
123
|
-
for
|
|
123
|
+
for modulename, items in stdlib_demos().items():
|
|
124
124
|
stdlib[modulename] = divide_stdlib_module(modulename, items)
|
|
125
125
|
|
|
126
126
|
|
crosshair/tracers.py
CHANGED
|
@@ -156,12 +156,14 @@ _CALL_HANDLERS: Dict[int, Callable[[object], CallStackInfo]] = {
|
|
|
156
156
|
CALL_KW: handle_call_kw,
|
|
157
157
|
CALL_FUNCTION: handle_call_function,
|
|
158
158
|
CALL_FUNCTION_KW: handle_call_function_kw,
|
|
159
|
-
CALL_FUNCTION_EX:
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
159
|
+
CALL_FUNCTION_EX: (
|
|
160
|
+
handle_call_function_ex_3_14
|
|
161
|
+
if sys.version_info >= (3, 14)
|
|
162
|
+
else (
|
|
163
|
+
handle_call_function_ex_3_13
|
|
164
|
+
if sys.version_info >= (3, 13)
|
|
165
|
+
else handle_call_function_ex_3_6
|
|
166
|
+
)
|
|
165
167
|
),
|
|
166
168
|
CALL_METHOD: handle_call_method,
|
|
167
169
|
}
|
crosshair/util.py
CHANGED
|
@@ -368,7 +368,7 @@ def format_boundargs_as_dictionary(bound_args: BoundArguments) -> str:
|
|
|
368
368
|
|
|
369
369
|
def format_boundargs(bound_args: BoundArguments) -> str:
|
|
370
370
|
arg_strings: List[str] = []
|
|
371
|
-
for
|
|
371
|
+
for name, param in bound_args.signature.parameters.items():
|
|
372
372
|
param_kind = param.kind
|
|
373
373
|
vals = bound_args.arguments.get(name, param.default)
|
|
374
374
|
if param_kind == Parameter.VAR_POSITIONAL:
|
|
@@ -503,9 +503,9 @@ class EvalFriendlyReprContext:
|
|
|
503
503
|
oid = id(obj)
|
|
504
504
|
typ = type(obj)
|
|
505
505
|
if obj in instance_overrides:
|
|
506
|
-
repr_fn: Callable[
|
|
507
|
-
[
|
|
508
|
-
|
|
506
|
+
repr_fn: Callable[[Any], Union[str, ReferencedIdentifier]] = (
|
|
507
|
+
instance_overrides[obj]
|
|
508
|
+
)
|
|
509
509
|
elif typ == float:
|
|
510
510
|
if math.isfinite(obj):
|
|
511
511
|
repr_fn = repr
|
|
@@ -543,7 +543,7 @@ class EvalFriendlyReprContext:
|
|
|
543
543
|
counts = collections.Counter(re.compile(r"\b_ch_efr_\d+_\b").findall(output))
|
|
544
544
|
assignment_remaps = {}
|
|
545
545
|
nextvarnum = 1
|
|
546
|
-
for
|
|
546
|
+
for varname, count in counts.items():
|
|
547
547
|
if count > 1:
|
|
548
548
|
assignment_remaps[varname + ":="] = f"v{nextvarnum}:="
|
|
549
549
|
assignment_remaps[varname] = f"v{nextvarnum}"
|
|
@@ -625,7 +625,7 @@ class DynamicScopeVar(Generic[_T]):
|
|
|
625
625
|
|
|
626
626
|
class AttributeHolder:
|
|
627
627
|
def __init__(self, attrs: Mapping[str, object]):
|
|
628
|
-
for
|
|
628
|
+
for k, v in attrs.items():
|
|
629
629
|
self.__dict__[k] = v
|
|
630
630
|
|
|
631
631
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crosshair-tool
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.97
|
|
4
4
|
Summary: Analyze Python code for correctness using symbolic execution.
|
|
5
5
|
Home-page: https://github.com/pschanely/CrossHair
|
|
6
6
|
Author: Phillip Schanely
|
|
@@ -8,7 +8,6 @@ Author-email: pschanely+vE7F@gmail.com
|
|
|
8
8
|
License: MIT
|
|
9
9
|
Classifier: Development Status :: 3 - Alpha
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
12
11
|
Classifier: Operating System :: OS Independent
|
|
13
12
|
Classifier: Programming Language :: Python :: 3
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.8
|
|
@@ -32,14 +31,14 @@ Requires-Dist: pygls>=1.0.0
|
|
|
32
31
|
Requires-Dist: typeshed-client>=2.0.5
|
|
33
32
|
Provides-Extra: dev
|
|
34
33
|
Requires-Dist: autodocsumm<1,>=0.2.2; extra == "dev"
|
|
35
|
-
Requires-Dist: black==
|
|
34
|
+
Requires-Dist: black==25.9.0; extra == "dev"
|
|
36
35
|
Requires-Dist: deal>=4.13.0; extra == "dev"
|
|
37
36
|
Requires-Dist: icontract>=2.4.0; extra == "dev"
|
|
38
37
|
Requires-Dist: isort==5.11.5; extra == "dev"
|
|
39
|
-
Requires-Dist: mypy==
|
|
38
|
+
Requires-Dist: mypy==1.18.1; extra == "dev"
|
|
40
39
|
Requires-Dist: numpy==1.23.4; python_version < "3.12" and extra == "dev"
|
|
41
40
|
Requires-Dist: numpy==1.26.0; (python_version >= "3.12" and python_version < "3.13") and extra == "dev"
|
|
42
|
-
Requires-Dist: numpy==2.
|
|
41
|
+
Requires-Dist: numpy==2.3.3; python_version >= "3.13" and extra == "dev"
|
|
43
42
|
Requires-Dist: pre-commit~=2.20; extra == "dev"
|
|
44
43
|
Requires-Dist: pytest; extra == "dev"
|
|
45
44
|
Requires-Dist: pytest-xdist; extra == "dev"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
_crosshair_tracers.cpython-311-darwin.so,sha256=
|
|
1
|
+
_crosshair_tracers.cpython-311-darwin.so,sha256=RwciJyliUt3D5fge8gI2ZdZR58IIBFtBlZTfH2fh7p8,23696
|
|
2
2
|
crosshair/_tracers_pycompat.h,sha256=6IYnbQxrYkhBsLDAHSX25DPOwo1oYHCZUVWZ8c7YCnQ,14356
|
|
3
3
|
crosshair/pure_importer.py,sha256=-t4eowrZOQmfqK1N2tjI5POoaxRGavytwMmbRivelFg,878
|
|
4
4
|
crosshair/options.py,sha256=htQNgnrpoRjSNq6rfLBAF8nos-NNIwmP6tQYyI8ugsM,6775
|
|
@@ -6,31 +6,31 @@ crosshair/lsp_server_test.py,sha256=7LO1Qqxkper3Xt2krgOlGqF1O_uDObo76o4FZbIqykY,
|
|
|
6
6
|
crosshair/conftest.py,sha256=BkLszApkdy6FrvzaHO7xh8_BJrG9AfytFTse-HuQVvg,653
|
|
7
7
|
crosshair/copyext_test.py,sha256=uJzdC9m2FqMjqQ-ITFoP0MZg3OCiO8paU-d533KocD8,2108
|
|
8
8
|
crosshair/objectproxy.py,sha256=1cO_ApA0AKPfCRu6MIsxUOKUUEGn0b1U4IHxTC4nDGI,9790
|
|
9
|
-
crosshair/pathing_oracle_test.py,sha256
|
|
9
|
+
crosshair/pathing_oracle_test.py,sha256=6k9-8kAbTFUvxhEKSE5NPntEW2qMWkQi4zac_U1kYxY,725
|
|
10
10
|
crosshair/objectproxy_test.py,sha256=UJuO_jUt8_OEUtgQWyhlekPOdvtM8IQ5M9I_1AqXPWM,1081
|
|
11
11
|
crosshair/stubs_parser.py,sha256=rlBTQus5BlZ3Ygg6Xzk5dbQbDtRpv6w9i2HQmGrPVmc,14240
|
|
12
12
|
crosshair/_preliminaries_test.py,sha256=r2PohNNMfIkDqsnvI6gKlJTbwBaZA9NQJueQfJMN2Eo,504
|
|
13
13
|
crosshair/dynamic_typing_test.py,sha256=8p4NOJ6i9q9mozgCYlZP3VCs-TFMDaE_7W-TyNEse4o,5907
|
|
14
|
-
crosshair/enforce.py,sha256=
|
|
14
|
+
crosshair/enforce.py,sha256=YVze7uYfR_bM1jUvDlU-8cF4cphRRfe78exNZ1xXtuI,10011
|
|
15
15
|
crosshair/path_search_test.py,sha256=7cqzAMXUYAtA00mq9XR5AaZChqeQyXyCfuuv53_51pk,1692
|
|
16
|
-
crosshair/condition_parser.py,sha256=
|
|
17
|
-
crosshair/util.py,sha256=
|
|
18
|
-
crosshair/dynamic_typing.py,sha256=
|
|
19
|
-
crosshair/register_contract.py,sha256=
|
|
20
|
-
crosshair/tracers.py,sha256=
|
|
16
|
+
crosshair/condition_parser.py,sha256=C7S_IogPTDSB-NPGRgJ_CzuWF9YCzGsm6mc37VBo6lY,42684
|
|
17
|
+
crosshair/util.py,sha256=pfBTBNhqMuaoUvAaFZal4LqVEMzWlzmcobHTxp_ZrlE,22214
|
|
18
|
+
crosshair/dynamic_typing.py,sha256=JMcEX5HMMm9u0_lLtZI1jrAw9HGZqXyq8IYGQP4KYSc,12752
|
|
19
|
+
crosshair/register_contract.py,sha256=4p99KAUhu1k-OctIT6WX2YFbVaMCV6BDEULNvQFONGE,10387
|
|
20
|
+
crosshair/tracers.py,sha256=UX-JKKjggQ0_EDh0AGNf4b_2ku9SD9pWgRyFcJDAVpc,17179
|
|
21
21
|
crosshair/_tracers.h,sha256=QFBklLqMWmIpUzBIn_A4SKdpjwHs-N7ttx-F5jtWWCQ,2174
|
|
22
22
|
crosshair/type_repo.py,sha256=x_eK-YlcHv_dxDKy6m7ty0zNO6y058o3r6QJ55RcG3s,4664
|
|
23
|
-
crosshair/fnutil.py,sha256=
|
|
23
|
+
crosshair/fnutil.py,sha256=Xs0xJPcQm0z3tWQDjd_I-ainWHTxcT61dv8A3CY3--8,13109
|
|
24
24
|
crosshair/unicode_categories.py,sha256=g4pnUPanx8KkpwI06ZUGx8GR8Myruf_EpTjyti_V4z8,333519
|
|
25
25
|
crosshair/copyext.py,sha256=GBGQP9YAHoezLXwb_M59Hh1VXSou5EQt4ZmmUA0T_og,4899
|
|
26
|
-
crosshair/_tracers_test.py,sha256=
|
|
27
|
-
crosshair/__init__.py,sha256=
|
|
28
|
-
crosshair/core.py,sha256=
|
|
26
|
+
crosshair/_tracers_test.py,sha256=7rrK0djASmRAlWcH4SiJqrWN7hk3oB_rYwhUG4gjxm4,3645
|
|
27
|
+
crosshair/__init__.py,sha256=7ph2S2-0_w1V5foTkyDqlkF63lSBFZ_QR10iQNgoKH0,936
|
|
28
|
+
crosshair/core.py,sha256=HqelePQQYES9SS36qR9mGEEeKcvEFrIHGg-8OG5i-Kg,64252
|
|
29
29
|
crosshair/path_cover.py,sha256=TCofZ9D5q7hpEIOnifp53BvY_YyPpZZC-heZw_NuTOQ,6838
|
|
30
30
|
crosshair/enforce_test.py,sha256=C6CQ4P1FjkdIJeJg3aJynp1iLDCE6BFCEVtSqXbvmQk,4665
|
|
31
31
|
crosshair/test_util.py,sha256=D9-f-DdzJemfAUkQL0cwKxPL8RZ-5gkVmghyRcKlBJI,10367
|
|
32
32
|
crosshair/core_test.py,sha256=P-r-qzHPZ2yLmSBZByYPccJZfxYi2ZCwn9o1mEfzRe8,33019
|
|
33
|
-
crosshair/codeconfig.py,sha256=
|
|
33
|
+
crosshair/codeconfig.py,sha256=TaIdOKxykpk6YeTtO_Xwsa3IDBTP6g3UGkFBt0PTDR4,3959
|
|
34
34
|
crosshair/util_test.py,sha256=_KTQ0O4cLhF1pAeB8Y8Cyqbd0UyZf5KxJUaiA-ew-tE,4676
|
|
35
35
|
crosshair/watcher_test.py,sha256=Ef1YSwy68wWPR5nPjwvEKPqxltI9pE9lTbnesmDy3Bk,2764
|
|
36
36
|
crosshair/auditwall.py,sha256=sqOmfXQLgmGfWS7b8SmVv66eFM2owaGn-4Ppq453VLI,5138
|
|
@@ -39,13 +39,13 @@ crosshair/z3util_test.py,sha256=CZovn4S9mYcG_yQegcxm80VHrvUdvNei0gvGTF9TOrk,173
|
|
|
39
39
|
crosshair/diff_behavior.py,sha256=_5X_pTN0_-rSPrh8dfpODJG_phFMn7fWc-_zLgO3UTk,11253
|
|
40
40
|
crosshair/condition_parser_test.py,sha256=UcgxzqrBLUMScif_RrgHvrhjzWx1KUPgAQOEmfJw7lc,15500
|
|
41
41
|
crosshair/pure_importer_test.py,sha256=Xjtlwn1mj7g-6VA87lrvzfUADCjlmn1wgHtbrnc0uuY,421
|
|
42
|
-
crosshair/fnutil_test.py,sha256=
|
|
42
|
+
crosshair/fnutil_test.py,sha256=cLHJ9uhQf797sTxuh4BGgQ0Fo5rcQFStkiPbzQPhIXA,2091
|
|
43
43
|
crosshair/stubs_parser_test.py,sha256=0itTT0Udul_51RJXNv6KB97z44gYze6NZfKJL7yIDzA,1228
|
|
44
44
|
crosshair/options_test.py,sha256=lzA-XtwEwQPa4wV1wwhCRKhyLOvIhThU9WK5QRaRbxQ,379
|
|
45
45
|
crosshair/patch_equivalence_test.py,sha256=eoLaGRvrR9nGUO_ybZ9XsWhs5ejC4IEPd0k-ihG3Nsg,2580
|
|
46
46
|
crosshair/abcstring.py,sha256=ROU8LzS7kfEU2L_D3QfhVxIjrYr1VctwUWfylC7KlCc,6549
|
|
47
47
|
crosshair/_mark_stacks.h,sha256=j86qubOUvVhoR19d74iQ084RrTEq8M6oT4wJsGQUySY,28678
|
|
48
|
-
crosshair/fuzz_core_test.py,sha256=
|
|
48
|
+
crosshair/fuzz_core_test.py,sha256=bLzdHBROzX3P3cfBeDTY9bJbfhe-CCoeLOF4Mt31wm0,17443
|
|
49
49
|
crosshair/unicode_categories_test.py,sha256=ZAU37IDGm9PDvwy_CGFcrF9Waa8JuUNdI4aq74wkB6c,739
|
|
50
50
|
crosshair/statespace_test.py,sha256=Eq7LNpjradHyCoCKU91Fxmo9DUpK2Mk4PyxxiAEp-Yk,3211
|
|
51
51
|
crosshair/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -53,31 +53,31 @@ crosshair/lsp_server.py,sha256=j7SX4pdVwa2MrtkNIjajLilzl5CZTY6PrBQsa26cdNo,8670
|
|
|
53
53
|
crosshair/path_search.py,sha256=wwZjp-3E4dENnJa6BlnSq8FARkIx0PyUYc7kvH32A2k,5588
|
|
54
54
|
crosshair/auditwall_test.py,sha256=VPcw_OW3nl3BkOZY4wEEtVDyTamdgqD4IjRccI2p5vI,2030
|
|
55
55
|
crosshair/smtlib_test.py,sha256=edzEn19u2YYHxSzG9RrMiu2HTiEexAuehC3IlG9LuJM,511
|
|
56
|
-
crosshair/register_contract_test.py,sha256=
|
|
57
|
-
crosshair/statespace.py,sha256=
|
|
56
|
+
crosshair/register_contract_test.py,sha256=9AWv9psiAredvcOlK2_pBpsgwIgBbecWyKEEvWiWBSI,4954
|
|
57
|
+
crosshair/statespace.py,sha256=D0Bptt3KMPG8RDzq_numy51sK1Pu_6QqcGKGfXC37s8,43440
|
|
58
58
|
crosshair/opcode_intercept_test.py,sha256=Si3rJQR5cs5d4uB8uwE2K8MjP8rE1a4yHkjXzhfS10A,9241
|
|
59
59
|
crosshair/main_test.py,sha256=2xpgNqog__XcYffGcwPeEEmr0Vy4EgVZE8GCAjQnE8U,14834
|
|
60
60
|
crosshair/codeconfig_test.py,sha256=RnC-RnNpr6If4eHmOepDZ33MCmfyhup08dzHKCm5xWA,3350
|
|
61
61
|
crosshair/watcher.py,sha256=kCCMlLe2KhW5MbEbMmixNRjRAvu5CypIAGd1V_YZ9QM,10048
|
|
62
62
|
crosshair/test_util_test.py,sha256=_r8DtAI5b1Yn1ruv9o51FWHmARII3-WDkWWnnY1iaAw,943
|
|
63
|
-
crosshair/opcode_intercept.py,sha256=
|
|
64
|
-
crosshair/simplestructs.py,sha256=
|
|
63
|
+
crosshair/opcode_intercept.py,sha256=atmnEDG9oDP0zlkGjJRAsYhD0Aw_PORf4coZZz2JgWw,23060
|
|
64
|
+
crosshair/simplestructs.py,sha256=O236XDO0dWGM59jktMUp5RG9xYY5iqZV219DknKAXgc,34283
|
|
65
65
|
crosshair/tracers_test.py,sha256=EBK_ZCy2MsxqmEaGjo0uw9zAztW9O6fhCW_0PJxyTS8,3270
|
|
66
66
|
crosshair/smtlib.py,sha256=hh-P32KHoH9BCq3oDYGp2PfOeOb8CwDj8tTkgqroLD8,689
|
|
67
|
-
crosshair/main.py,sha256=
|
|
67
|
+
crosshair/main.py,sha256=CY3PBcis302n0KvqoyDDoqtthNL4XASXHssO1I7DkJM,34707
|
|
68
68
|
crosshair/path_cover_test.py,sha256=U46zw4-m7yAXhu8-3Xnhvf-_9Ov5ivfCAm5euGwpRFA,4089
|
|
69
69
|
crosshair/__main__.py,sha256=zw9Ylf8v2fGocE57o4FqvD0lc7U4Ld2GbeCGxRWrpqo,252
|
|
70
|
-
crosshair/pathing_oracle.py,sha256=
|
|
70
|
+
crosshair/pathing_oracle.py,sha256=qa-_OlyuCHpNHkK5xN8OvxRgOEOA56VpGf0jUIR8L-M,10513
|
|
71
71
|
crosshair/diff_behavior_test.py,sha256=nCpzOjrw0qsYgVhD2iCvKiNAt82SrfUWxWS5mPSE73w,7215
|
|
72
72
|
crosshair/core_and_libs.py,sha256=8FGL62GnyX6WHOqKh0rqJ0aJ_He5pwZm_zwPXTaPqhI,3963
|
|
73
73
|
crosshair/core_regestered_types_test.py,sha256=er3ianvu-l0RS-WrS46jmOWr4Jq06Cec9htAXGXJSNg,2099
|
|
74
74
|
crosshair/z3util.py,sha256=AkslxCSfzgSni6oWXUckWihWn3LuceQycR0X3D3ZhD8,1759
|
|
75
|
-
crosshair/tools/generate_demo_table.py,sha256=
|
|
75
|
+
crosshair/tools/generate_demo_table.py,sha256=Z8gPUPQM8G_szPTgagBYzvsQeWDEEhGoZCU0z5FAS3E,3827
|
|
76
76
|
crosshair/tools/check_help_in_doc.py,sha256=P21AH3mYrTVuBgWD6v65YXqBqmqpQDUTQeoZ10rB6TU,8235
|
|
77
77
|
crosshair/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
78
78
|
crosshair/tools/check_init_and_setup_coincide.py,sha256=kv61bXqKSKF_5J-kLNEhCrCPyszg7iZQWDu_Scnec98,3502
|
|
79
79
|
crosshair/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
|
-
crosshair/examples/check_examples_test.py,sha256=
|
|
80
|
+
crosshair/examples/check_examples_test.py,sha256=ieB2KBBPReQBOr5-AZCgrVyhN1YXGYyQMjHyQBQ4zTI,4063
|
|
81
81
|
crosshair/examples/deal/__init__.py,sha256=Jp9ZnHBCuRzkgP8OIgEWWOzQiC0jLIYPd-rCqF5Xyrg,32
|
|
82
82
|
crosshair/examples/PEP316/__init__.py,sha256=LdmvJx2cbzC3iip3NwtT0Ds2v99l3KXl1q9Kc0TmCWE,34
|
|
83
83
|
crosshair/examples/PEP316/correct_code/chess.py,sha256=w29qVe-1oKMaHgZYhqyp2vQghXm2oohruFENljoVBCY,2081
|
|
@@ -109,19 +109,19 @@ crosshair/libimpl/binascii_test.py,sha256=LOBqLAJ77Kx8vorjVTaT3X0Z93zw4P5BvwUapM
|
|
|
109
109
|
crosshair/libimpl/collectionslib_test.py,sha256=0qmCRQbxfX8vMZLaok1GS68NIocR--RyTVVDqbtHalU,9185
|
|
110
110
|
crosshair/libimpl/timelib.py,sha256=MXEFOZjFGa1-yLvmB3l3DFTLF9PSluOlmRK-ZJaA_oI,2409
|
|
111
111
|
crosshair/libimpl/jsonlib_test.py,sha256=U40WJf-69dtflz75sIsl5zA3IV5R6Ltc4Z9jv_Fh-Fw,1382
|
|
112
|
-
crosshair/libimpl/builtinslib.py,sha256=
|
|
112
|
+
crosshair/libimpl/builtinslib.py,sha256=R6w3t-i1uJ3U8R-qHtrktZRTFm_K4SD0LjfeWBZbBDw,173362
|
|
113
113
|
crosshair/libimpl/mathlib_test.py,sha256=QShLCXHdv3tx5PQxcSoR0MHeZ1huaiV6d3u7C2mGOn4,1861
|
|
114
114
|
crosshair/libimpl/fractionlib.py,sha256=qdbiAHHC480YdKq3wYK_piZ3UD7oT64YfuNclypMUfQ,458
|
|
115
115
|
crosshair/libimpl/binascii_ch_test.py,sha256=hFqSfF1Q8jl2LNBIWaQ6vBJIIshPOmSwrR0T1Ko4Leo,1009
|
|
116
116
|
crosshair/libimpl/jsonlib.py,sha256=xFTvqGKzQcCgPme1WIpNMjBPfNHVZBMNuNx0uKMYXj0,28805
|
|
117
117
|
crosshair/libimpl/typeslib_test.py,sha256=qCeUU_c-zmuvfwHEsaYqic9wdGzs9XbDZNr6bF2Xp58,1129
|
|
118
|
-
crosshair/libimpl/builtinslib_test.py,sha256=
|
|
118
|
+
crosshair/libimpl/builtinslib_test.py,sha256=LYjvmVx0ndUK7YNMzNUaH39YesY_yrvIWb5XOwdnkDM,92255
|
|
119
119
|
crosshair/libimpl/zliblib.py,sha256=XymJTKYbplpYJZ-P7GKVSY3V_8HPy5lqRFsCH1zezIk,357
|
|
120
120
|
crosshair/libimpl/decimallib.py,sha256=zBKDrDZcg45oCKUkf6SIDuVpjA1Web7tD1MEQo5cjxI,177348
|
|
121
121
|
crosshair/libimpl/relib_ch_test.py,sha256=zvSBF82mNQR5yEOMwwcaBOh8OpJkQeiVl85pgYVvJRA,5235
|
|
122
122
|
crosshair/libimpl/functoolslib.py,sha256=YD0g9UnC4v_wZXR3ekQa2gLrKJnr6dHdYtT9qIMUIGM,1009
|
|
123
123
|
crosshair/libimpl/collectionslib_ch_test.py,sha256=PYitnmXXEZfm25FzBodEX1hOpwqnDspbqt5aqzeVar0,5855
|
|
124
|
-
crosshair/libimpl/builtinslib_ch_test.py,sha256=
|
|
124
|
+
crosshair/libimpl/builtinslib_ch_test.py,sha256=UasixDc_qZHOEkmMkh_2r9l2NgItQBzwHpvs7dRfgvk,30857
|
|
125
125
|
crosshair/libimpl/randomlib_test.py,sha256=KuEgrih9JvstsFDwrgAuHZrlVjIvaNUxS8ftiGPrwHI,3322
|
|
126
126
|
crosshair/libimpl/weakreflib_test.py,sha256=CdGJhW32qJoxedn8QzPcMcKKmfl9Nv4FPDYebblIKmY,1812
|
|
127
127
|
crosshair/libimpl/mathlib.py,sha256=ci_byDulWf1VOitpD3C-TwToL6CRYKkJUVMxjAYzUH8,4256
|
|
@@ -131,7 +131,7 @@ crosshair/libimpl/timelib_test.py,sha256=Ercmhw1Yc96CYnWhqIW7eu31R95uTGVZcgzxSiZ
|
|
|
131
131
|
crosshair/libimpl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
132
132
|
crosshair/libimpl/importliblib_test.py,sha256=DM8wWvPYbDTsdKVlS-JMrZ2cQpWSy4yXjZGPMQwF7Ss,1020
|
|
133
133
|
crosshair/libimpl/relib_test.py,sha256=3raQ0JoU4vu8_NKfrjk7TkUIqVuuhR8mGCRPJPb0RI0,16085
|
|
134
|
-
crosshair/libimpl/arraylib.py,sha256=
|
|
134
|
+
crosshair/libimpl/arraylib.py,sha256=QL6QH9iHHsmKA2zzW9DKPB6AbaxRiZbD3ikSGQVgqxU,4875
|
|
135
135
|
crosshair/libimpl/urlliblib.py,sha256=EaC-nWdi-IFG3ewZrzgCqbKc9Sf9wlUN0wvGjTU5TOM,614
|
|
136
136
|
crosshair/libimpl/bisectlib_test.py,sha256=ZQtYmBYD0Pb1IiFelsgdvqyeUMKaqaDb1BRb87LTSbI,753
|
|
137
137
|
crosshair/libimpl/itertoolslib.py,sha256=1bwV8voMV2j18KjXYMKkuNSC8p4VE_ZvY-74rAbWjB4,1245
|
|
@@ -143,18 +143,18 @@ crosshair/libimpl/codecslib_test.py,sha256=8K64njhxnTe7qLh-_onARNsm_qSG7BWM5dXgA
|
|
|
143
143
|
crosshair/libimpl/jsonlib_ch_test.py,sha256=lLGnFq6Ti7l6aV_jDz-HEzKaPy5TIj_JA0sSnfI0Psc,1267
|
|
144
144
|
crosshair/libimpl/iolib_test.py,sha256=VJRSQ3nnROfXvtqdy3yLx3eYmIh31qSmeuAiIa7ywKU,667
|
|
145
145
|
crosshair/libimpl/codecslib.py,sha256=lB87T1EYSBh4JXaqzjSpQG9CMfKtgckwA7f6OIR0S-Q,2668
|
|
146
|
-
crosshair/libimpl/datetimelib_ch_test.py,sha256=
|
|
146
|
+
crosshair/libimpl/datetimelib_ch_test.py,sha256=nevP0P8nkJ8DasvoVcD2tHiaZSFz5H8BHozzI-ZElhg,9288
|
|
147
147
|
crosshair/libimpl/itertoolslib_test.py,sha256=MV-zSdfdeQi_UpZJdanKzHm2GRqrC7BMUoCd95ldMPw,1183
|
|
148
148
|
crosshair/libimpl/copylib.py,sha256=icHJWeFK_tsPSdJhvlS5fVcBwlh0uJh0nzXsRJCGtzs,527
|
|
149
149
|
crosshair/libimpl/hashliblib_test.py,sha256=HhPdm5CBTAeqrs41NpCxkexWYWyIf1JiA4cls72WQfM,406
|
|
150
150
|
crosshair/libimpl/binasciilib.py,sha256=9w4C37uxRNOmz9EUuhJduHlMKn0f7baY5fwwdvx1uto,5070
|
|
151
151
|
crosshair/libimpl/typeslib.py,sha256=5qWrHZZN8jQZoHPiQtkaFolR8qTYCQtJw3HRWCrCKQI,468
|
|
152
|
-
crosshair/libimpl/datetimelib.py,sha256=
|
|
153
|
-
crosshair/libimpl/relib.py,sha256=
|
|
152
|
+
crosshair/libimpl/datetimelib.py,sha256=3mdouYmzY5wIbByKcx_ehvzLYasiM4LDEn1-BB9edV0,79146
|
|
153
|
+
crosshair/libimpl/relib.py,sha256=ahS9f1_rhbVKZUhvYmuSTv0_ovmvH5NXShxDJu7aUhE,29272
|
|
154
154
|
crosshair/libimpl/iolib.py,sha256=FbvqTfQRPaML5u0hHnrFZLrk3jYC-x4OO6eJujvFJaY,6983
|
|
155
155
|
crosshair/libimpl/urlliblib_test.py,sha256=UcSmwRdJFkzXvkaV-jmrP6G4zhbu7X2NNjM7ePsYxRs,503
|
|
156
156
|
crosshair/libimpl/heapqlib.py,sha256=TWH55dg-Hi5FRz2oZuXHcBU_xJzHjvhe9YQVvw7ZbfI,1311
|
|
157
|
-
crosshair/libimpl/unicodedatalib_test.py,sha256=
|
|
157
|
+
crosshair/libimpl/unicodedatalib_test.py,sha256=b0CHHHqDj5Ej_UEDnz3aUesILObcfLm00eEXQtfsgfM,1442
|
|
158
158
|
crosshair/libimpl/encodings_ch_test.py,sha256=0qLsioOuFUZkOjP4J9Wct4CGBaBY8BnHx9paZHnIofI,2513
|
|
159
159
|
crosshair/libimpl/hashliblib.py,sha256=Ki_cw28OnhZExgKbSoh5GaDbBfNRIOqH7O2aYQJGS3M,1234
|
|
160
160
|
crosshair/libimpl/functoolslib_test.py,sha256=eaT_JWu-C3j8l9ekwDXd2dhPJvuB577T9DuXRohL0fc,1604
|
|
@@ -167,10 +167,10 @@ crosshair/libimpl/encodings/utf_8.py,sha256=BygLLIeI3_F2MpFVgaty8ebiuxp0YWz7IzXe
|
|
|
167
167
|
crosshair/libimpl/encodings/ascii.py,sha256=Cz1xraTkXdQ5aBKDkorX4rAvrmf877_EqzC9hOmbItw,1416
|
|
168
168
|
crosshair/libimpl/encodings/__init__.py,sha256=5LTEj1M-S00eZ4rfQWczAixg57vyh_9vZ5m5EKB5Ksc,680
|
|
169
169
|
crosshair/libimpl/encodings/latin_1.py,sha256=ftUsPjUb9L7UKXKi9P7OAqOl9FkNP98M9jMAvseXBCQ,1242
|
|
170
|
-
crosshair/libimpl/encodings/_encutil.py,sha256=
|
|
171
|
-
crosshair_tool-0.0.
|
|
172
|
-
crosshair_tool-0.0.
|
|
173
|
-
crosshair_tool-0.0.
|
|
174
|
-
crosshair_tool-0.0.
|
|
175
|
-
crosshair_tool-0.0.
|
|
176
|
-
crosshair_tool-0.0.
|
|
170
|
+
crosshair/libimpl/encodings/_encutil.py,sha256=R0tLdyc83fN6C8c_tl5vetDCpayxeYaAT7UWwPQzX10,6982
|
|
171
|
+
crosshair_tool-0.0.97.dist-info/RECORD,,
|
|
172
|
+
crosshair_tool-0.0.97.dist-info/WHEEL,sha256=TY6wS7uh4kKn2hb4-XnLjkub5JFV8id422w1jhyVjcQ,137
|
|
173
|
+
crosshair_tool-0.0.97.dist-info/entry_points.txt,sha256=u5FIPVn1jqn4Kzg5K_iNnbP6L4hQw5FWjQ0UMezG2VE,96
|
|
174
|
+
crosshair_tool-0.0.97.dist-info/top_level.txt,sha256=2jLWtM-BWg_ZYNbNfrcds0HFZD62a6J7ZIbcgcQrRk4,29
|
|
175
|
+
crosshair_tool-0.0.97.dist-info/METADATA,sha256=5ADW4j5TNenYaOjXs10_7udeVLv9eUlaIq9ZztZMXC8,6727
|
|
176
|
+
crosshair_tool-0.0.97.dist-info/licenses/LICENSE,sha256=NVyMvNqn1pH6RSHs6RWRcJyJvORnpgGFBlF73buqYJ0,4459
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|