Metadata-Version: 1.1
Name: pyfuzzer
Version: 0.19.0
Summary: Fuzz test Python modules with libFuzzer.
Home-page: https://github.com/eerimoq/pyfuzzer
Author: Erik Moqvist
Author-email: erik.moqvist@gmail.com
License: MIT
Description: |buildstatus|_
        |coverage|_
        
        About
        =====
        
        Use `libFuzzer`_ to fuzz test Python 3.6+ C extension modules.
        
        Installation
        ============
        
        `clang 8` or later is required.
        
        .. code-block:: text
        
           $ apt install clang
           $ pip install pyfuzzer
        
        Example Usage
        =============
        
        Hello world
        -----------
        
        Use the default mutator ``pyfuzzer.mutators.generic`` when testing the
        module ``hello_world``.
        
        .. code-block:: text
        
           $ cd examples/hello_world
           $ pyfuzzer run -l max_total_time=1 hello_world.c
           <lots of libFuzzer output>
        
        Print the function calls that found new code paths. This information
        is usually useful when writing unit tests.
        
        .. code-block:: text
        
           $ pyfuzzer print_corpus
           corpus/25409981b15b978c9fb5a5a2f4dab0c4b04e295f:
               tell(b'') = 5
           corpus/a8a4e6c9abfd3c6cba171579190702ddc1317df0:
               tell(b'\xfd#') = b'Hello!'
           corpus/80f87702ef9fbe4baf17095c79ff928b9fa1ea14:
               tell(b'\x00') = True
           corpus/be3d1b7df189727b2cecd6526aa8f24abbf6df10:
               tell(b'\x00\xfd\x00') = 0
           corpus/defd8787d638f271cd83362eafe7fdeed9fa4a8f:
               tell(None) raises:
               Traceback (most recent call last):
                 File "/home/erik/workspace/pyfuzzer/pyfuzzer/mutators/utils.py", line 35, in print_callable
                   res = obj(*args)
               TypeError: expected bytes, NoneType found
        
        See the `hello_world`_ for all files.
        
        Hello world fatal error
        -----------------------
        
        Similar to the previous example, but triggers a fatal error when
        ``tell()`` is called with a bytes object longer than 2 bytes as its
        first argument.
        
        .. code-block:: text
        
           $ cd examples/hello_world_fatal_error
           $ pyfuzzer run hello_world.c
           ...
           Fatal Python error: deallocating None
        
           Current thread 0x00007f7ca99c2780 (most recent call first):
           ...
        
        Print the function call that caused the crash. Just as expected, the
        first argument is clearly longer than 2 bytes.
        
        .. code-block:: text
        
           $ pyfuzzer print_crashes
           crash-1013ed88cd71fd14407b2bdbc17b95d7bc317c21:
               tell(b'\n\xbf+') = None
        
        See the `hello_world_fatal_error`_ for all files.
        
        Custom mutator
        --------------
        
        Use the custom mutator ``hello_world_mutator`` when testing the module
        ``hello_world``.
        
        Testing with a custom mutator is often more efficient than using a
        generic one.
        
        .. code-block:: text
        
           $ cd examples/hello_world_custom_mutator
           $ pyfuzzer run -l max_total_time=1 -m hello_world_mutator.py hello_world.c
           ...
        
        See the `hello_world_custom_mutator`_ for all files.
        
        Mutators
        ========
        
        A mutator module uses data from `libFuzzer`_ to test a module. A
        mutator module must implement the function ``setup(module)``, where
        ``module`` is the module under test. It shall return a mutator
        instance that implements the methods ``test_one_input(self, data)``
        and ``test_one_input_print(self, data)``, where ``data`` is the data
        generated by `libFuzzer`_ (as a bytes object).
        
        ``test_one_input(self, data)`` performs the actual fuzz testing, while
        ``test_one_input_print(self, data)`` prints corpus and crashes.
        
        A minimal mutator fuzz testing a CRC-32 algorithm could look like
        below. It simply calls ``crc_32()`` with ``data`` as its only
        argument.
        
        .. code-block:: python
        
           from pyfuzzer.mutators.generic import print_callable
        
           class Mutator:
        
               def __init__(self, module):
                   self._module = module
        
               def test_one_input(self, data):
                   return module.crc_32(data)
        
               def test_one_input_print(self, data):
                   print_callable(self._module.crc_32, [data])
        
            def setup(module):
                return Mutator(module)
        
        Ideas
        =====
        
        - Add support to fuzz test pure Python modules by generating C code
          using Cython.
        
        .. |buildstatus| image:: https://travis-ci.org/eerimoq/pyfuzzer.svg
        .. _buildstatus: https://travis-ci.org/eerimoq/pyfuzzer
        
        .. |coverage| image:: https://coveralls.io/repos/github/eerimoq/pyfuzzer/badge.svg?branch=master
        .. _coverage: https://coveralls.io/github/eerimoq/pyfuzzer
        
        .. _libFuzzer: https://llvm.org/docs/LibFuzzer.html
        
        .. _hello_world: https://github.com/eerimoq/pyfuzzer/tree/master/examples/hello_world
        
        .. _hello_world_fatal_error: https://github.com/eerimoq/pyfuzzer/tree/master/examples/hello_world_fatal_error
        
        .. _hello_world_custom_mutator: https://github.com/eerimoq/pyfuzzer/tree/master/examples/hello_world_custom_mutator
        
Keywords: fuzz,fuzzying,test
Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
