Coverage for /pythoncovmergedfiles/medio/medio/src/python-multipart/fuzz/fuzz_form.py: 57%
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 io
13import logging
14import sys
16logging.disable(logging.CRITICAL)
18import atheris
19from helpers import EnhancedDataProvider
21with atheris.instrument_imports():
22 from python_multipart.exceptions import FormParserError
23 from python_multipart.multipart import parse_form
26def _on_field(field) -> None:
27 pass
30def _on_file(file) -> None:
31 pass
34def parse_octet_stream(fdp: EnhancedDataProvider) -> None:
35 header = {"Content-Type": "application/octet-stream"}
36 parse_form(header, io.BytesIO(fdp.ConsumeRandomBytes()), _on_field, _on_file)
39def parse_url_encoded(fdp: EnhancedDataProvider) -> None:
40 ct = fdp.PickValueInList(["application/x-url-encoded", "application/x-www-form-urlencoded"])
41 header = {"Content-Type": ct}
42 parse_form(header, io.BytesIO(fdp.ConsumeRandomBytes()), _on_field, _on_file)
45def parse_multipart_raw(fdp: EnhancedDataProvider) -> None:
46 # Boundary: 1-70 bytes, no CR/LF (RFC 2046 constraint kept to avoid ValueError).
47 boundary_len = fdp.ConsumeIntInRange(1, max(1, min(70, fdp.remaining_bytes() // 2)))
48 boundary = fdp.ConsumeBytes(boundary_len)
49 boundary = boundary.replace(b"\r", b"-").replace(b"\n", b"-").rstrip(b" \t") or b"B"
50 header = {"Content-Type": "multipart/form-data; boundary=" + boundary.decode("latin-1")}
51 body = fdp.ConsumeRandomBytes()
52 parse_form(header, io.BytesIO(body), _on_field, _on_file)
55def parse_multipart_with_content_length(fdp: EnhancedDataProvider) -> None:
56 boundary = b"boundary"
57 content_length = fdp.ConsumeIntInRange(0, 1024)
58 header = {
59 "Content-Type": "multipart/form-data; boundary=boundary",
60 "Content-Length": str(content_length),
61 }
62 body = fdp.ConsumeRandomBytes()
63 parse_form(header, io.BytesIO(body), _on_field, _on_file)
66def parse_form_urlencoded_chunked(fdp: EnhancedDataProvider) -> None:
67 from python_multipart.multipart import create_form_parser
69 num_chunks = fdp.ConsumeIntInRange(1, 8)
70 header = {"Content-Type": "application/x-www-form-urlencoded"}
71 parser = create_form_parser(header, _on_field, _on_file)
72 body = fdp.ConsumeRandomBytes()
73 chunk_size = max(1, (len(body) + num_chunks - 1) // num_chunks)
74 for i in range(0, len(body), chunk_size):
75 parser.write(body[i : i + chunk_size])
76 parser.finalize()
78def TestOneInput(data: bytes) -> None:
79 fdp = EnhancedDataProvider(data)
80 targets = [
81 parse_octet_stream,
82 parse_url_encoded,
83 parse_multipart_raw,
84 parse_multipart_with_content_length,
85 parse_form_urlencoded_chunked,
86 ]
87 target = fdp.PickValueInList(targets)
89 try:
90 target(fdp)
91 except FormParserError:
92 return
95def main():
96 atheris.Setup(sys.argv, TestOneInput)
97 atheris.Fuzz()
100if __name__ == "__main__":
101 main()