Coverage for /pythoncovmergedfiles/medio/medio/src/tomli/fuzzer/fuzz.py: 39%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1###### Coverage stub
2import atexit
3import coverage
4cov = coverage.coverage(data_file='.coverage', cover_pylib=True)
5cov.start()
6# Register an exist handler that will print coverage
7def exit_handler():
8 cov.stop()
9 cov.save()
10atexit.register(exit_handler)
11####### End of coverage stub
12import atheris
14with atheris.instrument_imports():
15 from math import isnan
16 import sys
17 import warnings
19 import tomli_w
21 import tomli
23# Disable any caching used so that the same lines of code run
24# on a given input consistently.
25tomli._re.cached_tz = tomli._re.cached_tz.__wrapped__
27# Suppress all warnings.
28warnings.simplefilter("ignore")
31def test_one_input(input_bytes: bytes) -> None:
32 # We need a Unicode string, not bytes
33 fdp = atheris.FuzzedDataProvider(input_bytes)
34 data = fdp.ConsumeUnicode(sys.maxsize)
36 try:
37 toml_obj = tomli.loads(data)
38 except (tomli.TOMLDecodeError, RecursionError):
39 return
40 except BaseException:
41 print_err(data)
42 raise
44 try:
45 recovered_data = tomli_w.dumps(toml_obj)
46 except RecursionError:
47 return
48 except BaseException:
49 print_err(data)
50 raise
52 roundtripped_obj = tomli.loads(recovered_data)
53 normalize_toml_obj(roundtripped_obj)
54 normalize_toml_obj(toml_obj)
55 if roundtripped_obj != toml_obj:
56 sys.stderr.write(
57 f"Original dict:\n{toml_obj}\nRoundtripped dict:\n{roundtripped_obj}\n"
58 )
59 sys.stderr.flush()
60 print_err(data)
61 raise Exception("Dicts not equal after roundtrip")
64def print_err(data):
65 codepoints = [hex(ord(x)) for x in data]
66 sys.stderr.write(f"Input was {type(data)}:\n{data}\nCodepoints:\n{codepoints}\n")
67 sys.stderr.flush()
70def normalize_toml_obj(toml_obj: dict) -> None:
71 """Make NaNs equal when compared (without using recursion)."""
72 to_process = [toml_obj]
73 while to_process:
74 cont = to_process.pop()
75 for k, v in cont.items() if isinstance(cont, dict) else enumerate(cont):
76 if isinstance(v, float) and isnan(v):
77 cont[k] = "nan"
78 elif isinstance(v, (dict, list)):
79 to_process.append(v)
82def main():
83 # For possible options, see https://llvm.org/docs/LibFuzzer.html#options
84 fuzzer_options = sys.argv
85 atheris.Setup(fuzzer_options, test_one_input)
86 atheris.Fuzz()
89if __name__ == "__main__":
90 main()