{ "info": { "author": "Erik Moqvist", "author_email": "erik.moqvist@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3" ], "description": "|buildstatus|_\n|coverage|_\n\nAbout\n=====\n\nUse `libFuzzer`_ to fuzz test Python 3.6+ C extension modules.\n\nInstallation\n============\n\n`clang 8` or later is required.\n\n.. code-block:: text\n\n $ apt install clang\n $ pip install pyfuzzer\n\nExample Usage\n=============\n\nHello world\n-----------\n\nUse the default mutator ``pyfuzzer.mutators.generic`` when testing the\nmodule ``hello_world``.\n\n.. code-block:: text\n\n $ cd examples/hello_world\n $ pyfuzzer run -l max_total_time=1 hello_world.c\n \n\nPrint the function calls that found new code paths. This information\nis usually useful when writing unit tests.\n\n.. code-block:: text\n\n $ pyfuzzer print_corpus\n corpus/25409981b15b978c9fb5a5a2f4dab0c4b04e295f:\n tell(b'') = 5\n corpus/a8a4e6c9abfd3c6cba171579190702ddc1317df0:\n tell(b'\\xfd#') = b'Hello!'\n corpus/80f87702ef9fbe4baf17095c79ff928b9fa1ea14:\n tell(b'\\x00') = True\n corpus/be3d1b7df189727b2cecd6526aa8f24abbf6df10:\n tell(b'\\x00\\xfd\\x00') = 0\n corpus/defd8787d638f271cd83362eafe7fdeed9fa4a8f:\n tell(None) raises:\n Traceback (most recent call last):\n File \"/home/erik/workspace/pyfuzzer/pyfuzzer/mutators/utils.py\", line 35, in print_callable\n res = obj(*args)\n TypeError: expected bytes, NoneType found\n\nSee the `hello_world`_ for all files.\n\nHello world fatal error\n-----------------------\n\nSimilar to the previous example, but triggers a fatal error when\n``tell()`` is called with a bytes object longer than 2 bytes as its\nfirst argument.\n\n.. code-block:: text\n\n $ cd examples/hello_world_fatal_error\n $ pyfuzzer run hello_world.c\n ...\n Fatal Python error: deallocating None\n\n Current thread 0x00007f7ca99c2780 (most recent call first):\n ...\n\nPrint the function call that caused the crash. Just as expected, the\nfirst argument is clearly longer than 2 bytes.\n\n.. code-block:: text\n\n $ pyfuzzer print_crashes\n crash-1013ed88cd71fd14407b2bdbc17b95d7bc317c21:\n tell(b'\\n\\xbf+') = None\n\nSee the `hello_world_fatal_error`_ for all files.\n\nCustom mutator\n--------------\n\nUse the custom mutator ``hello_world_mutator`` when testing the module\n``hello_world``.\n\nTesting with a custom mutator is often more efficient than using a\ngeneric one.\n\n.. code-block:: text\n\n $ cd examples/hello_world_custom_mutator\n $ pyfuzzer run -l max_total_time=1 -m hello_world_mutator.py hello_world.c\n ...\n\nSee the `hello_world_custom_mutator`_ for all files.\n\nMutators\n========\n\nA mutator module uses data from `libFuzzer`_ to test a module. A\nmutator module must implement the function ``setup(module)``, where\n``module`` is the module under test. It shall return a mutator\ninstance that implements the methods ``test_one_input(self, data)``\nand ``test_one_input_print(self, data)``, where ``data`` is the data\ngenerated by `libFuzzer`_ (as a bytes object).\n\n``test_one_input(self, data)`` performs the actual fuzz testing, while\n``test_one_input_print(self, data)`` prints corpus and crashes.\n\nA minimal mutator fuzz testing a CRC-32 algorithm could look like\nbelow. It simply calls ``crc_32()`` with ``data`` as its only\nargument.\n\n.. code-block:: python\n\n from pyfuzzer.mutators.generic import print_callable\n\n class Mutator:\n\n def __init__(self, module):\n self._module = module\n\n def test_one_input(self, data):\n return module.crc_32(data)\n\n def test_one_input_print(self, data):\n print_callable(self._module.crc_32, [data])\n\n def setup(module):\n return Mutator(module)\n\nIdeas\n=====\n\n- Add support to fuzz test pure Python modules by generating C code\n using Cython.\n\n.. |buildstatus| image:: https://travis-ci.org/eerimoq/pyfuzzer.svg\n.. _buildstatus: https://travis-ci.org/eerimoq/pyfuzzer\n\n.. |coverage| image:: https://coveralls.io/repos/github/eerimoq/pyfuzzer/badge.svg?branch=master\n.. _coverage: https://coveralls.io/github/eerimoq/pyfuzzer\n\n.. _libFuzzer: https://llvm.org/docs/LibFuzzer.html\n\n.. _hello_world: https://github.com/eerimoq/pyfuzzer/tree/master/examples/hello_world\n\n.. _hello_world_fatal_error: https://github.com/eerimoq/pyfuzzer/tree/master/examples/hello_world_fatal_error\n\n.. _hello_world_custom_mutator: https://github.com/eerimoq/pyfuzzer/tree/master/examples/hello_world_custom_mutator", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/eerimoq/pyfuzzer", "keywords": "fuzz,fuzzying,test", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "pyfuzzer", "package_url": "https://pypi.org/project/pyfuzzer/", "platform": "", "project_url": "https://pypi.org/project/pyfuzzer/", "project_urls": { "Homepage": "https://github.com/eerimoq/pyfuzzer" }, "release_url": "https://pypi.org/project/pyfuzzer/0.17.0/", "requires_dist": null, "requires_python": "", "summary": "Fuzz test Python modules with libFuzzer.", "version": "0.17.0" }, "last_serial": 5963504, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "edd64f61b9a84f057cd821f2a27d7503", "sha256": "69813fb7c9ad8a88af9cd13688574f7d9f49456152bca16987fead9f02a3a0b4" }, "downloads": -1, "filename": "pyfuzzer-0.1.0.tar.gz", "has_sig": false, "md5_digest": "edd64f61b9a84f057cd821f2a27d7503", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3430, "upload_time": "2019-10-05T07:10:44", "url": "https://files.pythonhosted.org/packages/09/77/c7cae5e2ae48b4cd3941d7c3ba923d46d92a56801216e4359f2803fd3eea/pyfuzzer-0.1.0.tar.gz" } ], "0.10.0": [ { "comment_text": "", "digests": { "md5": "28994280576fd050a9f3959f0abe14f3", "sha256": "4cb7ca237338191f6fe1b31b5c4046f481864981795344567209b015f000abb3" }, "downloads": -1, "filename": "pyfuzzer-0.10.0.tar.gz", "has_sig": false, "md5_digest": "28994280576fd050a9f3959f0abe14f3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8343, "upload_time": "2019-10-07T06:31:09", "url": "https://files.pythonhosted.org/packages/c9/24/f1e1d4f530e7944d427aababa2c8942f617dd58b69d1782ad1f0b5564470/pyfuzzer-0.10.0.tar.gz" } ], "0.11.0": [ { "comment_text": "", "digests": { "md5": "088cf11afc7803cfbb018d9187a99237", "sha256": "95504971b749cb986f4bbf907d624e1170f36802b9f23447cd077fece396f347" }, "downloads": -1, "filename": "pyfuzzer-0.11.0.tar.gz", "has_sig": false, "md5_digest": "088cf11afc7803cfbb018d9187a99237", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9017, "upload_time": "2019-10-07T19:58:25", "url": "https://files.pythonhosted.org/packages/de/93/d1ca75e45d9d9050339097b94f2ed14ee5407dfa7309a2c6345a9bec90cc/pyfuzzer-0.11.0.tar.gz" } ], "0.12.0": [ { "comment_text": "", "digests": { "md5": "bd9b73ccee1a25c7e6b2d7359aacd288", "sha256": "fe7dd682bfa84bb7fc39cfad5abcb444e64b268a094f7487aa90dc1a9a6bc038" }, "downloads": -1, "filename": "pyfuzzer-0.12.0.tar.gz", "has_sig": false, "md5_digest": "bd9b73ccee1a25c7e6b2d7359aacd288", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8795, "upload_time": "2019-10-08T05:57:50", "url": "https://files.pythonhosted.org/packages/c6/3e/67ee1513d7ce62bb1d2bd6d6d68d3f40ad2f1e0a2be6e593bfc2036bd529/pyfuzzer-0.12.0.tar.gz" } ], "0.13.0": [ { "comment_text": "", "digests": { "md5": "01ff1bab02199d8d18293e7b2da5ccda", "sha256": "656796369a96991a5daf428e9c161447ca5a60b1d528077e9f21e321d199fa6e" }, "downloads": -1, "filename": "pyfuzzer-0.13.0.tar.gz", "has_sig": false, "md5_digest": "01ff1bab02199d8d18293e7b2da5ccda", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9350, "upload_time": "2019-10-08T20:24:05", "url": "https://files.pythonhosted.org/packages/d4/1c/3261e580732135250585fd6fc6bf1705c3bcc2cedd1f123f75359721ec14/pyfuzzer-0.13.0.tar.gz" } ], "0.14.0": [ { "comment_text": "", "digests": { "md5": "b1166c6bea4bec298cd417e0da9bf020", "sha256": "f136648a90bca935a189ceba0e2b8f68748a2d1d4ab6e3b3d6ebf692534202a8" }, "downloads": -1, "filename": "pyfuzzer-0.14.0.tar.gz", "has_sig": false, "md5_digest": "b1166c6bea4bec298cd417e0da9bf020", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10497, "upload_time": "2019-10-09T12:26:28", "url": "https://files.pythonhosted.org/packages/09/9a/d8d6597ce695929389cdf86e1cf6403bf4ed6e99a3ed6b681a7e57526d7c/pyfuzzer-0.14.0.tar.gz" } ], "0.15.0": [ { "comment_text": "", "digests": { "md5": "177dfd92a8b9204f85e9918c3d1fafae", "sha256": "85a660d2f9e0d9ebacde64f7f4ef31ff8b03aeb27699034a95c3acc1ae59fabf" }, "downloads": -1, "filename": "pyfuzzer-0.15.0.tar.gz", "has_sig": false, "md5_digest": "177dfd92a8b9204f85e9918c3d1fafae", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11567, "upload_time": "2019-10-09T20:38:57", "url": "https://files.pythonhosted.org/packages/92/f5/7f2c63043e00037aa8309fc313c3f63854df9ffd61bbc634014ad42f354d/pyfuzzer-0.15.0.tar.gz" } ], "0.16.0": [ { "comment_text": "", "digests": { "md5": "07bbfb778ae4e4fbed768827d4f0c9bb", "sha256": "8e67ef3b0a512ed6df97839eb1d0b045aabe46cc9200abcf3ed1988ce3863a24" }, "downloads": -1, "filename": "pyfuzzer-0.16.0.tar.gz", "has_sig": false, "md5_digest": "07bbfb778ae4e4fbed768827d4f0c9bb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11537, "upload_time": "2019-10-10T17:45:35", "url": "https://files.pythonhosted.org/packages/0c/c0/2b6e51b02c6ed38f1d66fc476fc5e08df551311c13fd8e5aa44eec275430/pyfuzzer-0.16.0.tar.gz" } ], "0.17.0": [ { "comment_text": "", "digests": { "md5": "9ba679b8b23db97036c2ac66e175e754", "sha256": "4f715929db20a1d773c5121843475fb89a9ce99f028a091cab55b9b74c6852bf" }, "downloads": -1, "filename": "pyfuzzer-0.17.0.tar.gz", "has_sig": false, "md5_digest": "9ba679b8b23db97036c2ac66e175e754", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10675, "upload_time": "2019-10-12T08:16:46", "url": "https://files.pythonhosted.org/packages/65/d0/35e8f890a7f499dfca20093d154f01c40cc5cb61510cfa3a493a43ea3982/pyfuzzer-0.17.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "eea4c332f03c474387159fc309881a7b", "sha256": "cbbaae0db55fa7ab6983bccded1110f1fbfe1a0f85c89fc2b89ad2b93ddbf248" }, "downloads": -1, "filename": "pyfuzzer-0.2.0.tar.gz", "has_sig": false, "md5_digest": "eea4c332f03c474387159fc309881a7b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5849, "upload_time": "2019-10-05T09:24:05", "url": "https://files.pythonhosted.org/packages/8a/db/e5e6185ddb9e2f45df6f3c3edfd68d5a066fac6944f7aaa281351bd9d950/pyfuzzer-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "93c968e0b1fbcb0d37e80b75008d0b39", "sha256": "61142e0791c7faaaff0126ee984ebbd737a8aee8d3929d6c196689d79dad68e9" }, "downloads": -1, "filename": "pyfuzzer-0.3.0.tar.gz", "has_sig": false, "md5_digest": "93c968e0b1fbcb0d37e80b75008d0b39", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6157, "upload_time": "2019-10-05T11:47:13", "url": "https://files.pythonhosted.org/packages/22/26/b5203ad4a9703de7be55d7e84fc4820d3f24ebebf925455f39863fa3fa65/pyfuzzer-0.3.0.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "57ef95e9920ecc3887bae37883228dde", "sha256": "d32c88017350c5a4a9715f32417ab309f377b4237d5c92b8a020ac47e1dddd20" }, "downloads": -1, "filename": "pyfuzzer-0.4.0.tar.gz", "has_sig": false, "md5_digest": "57ef95e9920ecc3887bae37883228dde", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6250, "upload_time": "2019-10-05T12:05:14", "url": "https://files.pythonhosted.org/packages/f6/2b/3c54a9a68ec35351665055b29f4fd9f18137c448412235735cd5e6057345/pyfuzzer-0.4.0.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "43b4e007da509c7a713b1b746fef9642", "sha256": "723ff09c06362b469c6f8fb900a0781d8a1bf9f299f9244ec54684454ff76c87" }, "downloads": -1, "filename": "pyfuzzer-0.5.0.tar.gz", "has_sig": false, "md5_digest": "43b4e007da509c7a713b1b746fef9642", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6188, "upload_time": "2019-10-05T15:25:56", "url": "https://files.pythonhosted.org/packages/0e/63/5775269eb0b61e837c794eebb690791ee383b78162daa814bc0e73c1922d/pyfuzzer-0.5.0.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "c00013112c7af07ac168fba6a9571264", "sha256": "54537a16b33e91b3514e986298625b51369bac1cf54ac87ba2c28f09c197f927" }, "downloads": -1, "filename": "pyfuzzer-0.6.0.tar.gz", "has_sig": false, "md5_digest": "c00013112c7af07ac168fba6a9571264", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6174, "upload_time": "2019-10-05T18:28:40", "url": "https://files.pythonhosted.org/packages/6c/59/31a7aca9e98f7ca35fe6b54fbdbd2cf1131b7b5aae5330b54520360da7bc/pyfuzzer-0.6.0.tar.gz" } ], "0.7.0": [ { "comment_text": "", "digests": { "md5": "2fc937cfe54caa1f3ca9854de0bce963", "sha256": "a10de65e61cb848d0ba26e18c36bbceee6763d16284833b07bf9f82dcc13a0fb" }, "downloads": -1, "filename": "pyfuzzer-0.7.0.tar.gz", "has_sig": false, "md5_digest": "2fc937cfe54caa1f3ca9854de0bce963", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9038, "upload_time": "2019-10-06T09:36:12", "url": "https://files.pythonhosted.org/packages/0a/9d/6fa2ae92e0dad0aa5811bcd10975b6195daee3b8806ef6efc9c63fcb1e75/pyfuzzer-0.7.0.tar.gz" } ], "0.7.1": [ { "comment_text": "", "digests": { "md5": "d7fbcc1b66696bb47f6201994030af46", "sha256": "dd2f09b72481abd95d0d91c73110677e84b782a22e0b9e81f76efc3cf4e75052" }, "downloads": -1, "filename": "pyfuzzer-0.7.1.tar.gz", "has_sig": false, "md5_digest": "d7fbcc1b66696bb47f6201994030af46", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9266, "upload_time": "2019-10-06T09:53:50", "url": "https://files.pythonhosted.org/packages/c7/7b/8870201c25e6c496dc6450a2c65182aca642037696b521cd3704551c0cd5/pyfuzzer-0.7.1.tar.gz" } ], "0.8.0": [ { "comment_text": "", "digests": { "md5": "f0fdf547d21a8c7996fb3f1a4bacffb4", "sha256": "0b496be321c17010ae8183457286737b7feeb111bf8f7c0bc72ad6e6eb8cc4c6" }, "downloads": -1, "filename": "pyfuzzer-0.8.0.tar.gz", "has_sig": false, "md5_digest": "f0fdf547d21a8c7996fb3f1a4bacffb4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9515, "upload_time": "2019-10-06T10:21:08", "url": "https://files.pythonhosted.org/packages/8e/97/8ede4b8e11c560f050cae9033b80e05a1477b263a4b06c003894d026881d/pyfuzzer-0.8.0.tar.gz" } ], "0.9.0": [ { "comment_text": "", "digests": { "md5": "aa3c6dd9257903c137c521eae6b17662", "sha256": "ba525541d2a15c6892539ab21089121333c5fdd2487d19654b920031d2a65f4e" }, "downloads": -1, "filename": "pyfuzzer-0.9.0.tar.gz", "has_sig": false, "md5_digest": "aa3c6dd9257903c137c521eae6b17662", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7929, "upload_time": "2019-10-06T11:55:33", "url": "https://files.pythonhosted.org/packages/d5/55/2e55168a05a67c17226367e28e7ce97bee5e89e4f75ba56233bdb131c460/pyfuzzer-0.9.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9ba679b8b23db97036c2ac66e175e754", "sha256": "4f715929db20a1d773c5121843475fb89a9ce99f028a091cab55b9b74c6852bf" }, "downloads": -1, "filename": "pyfuzzer-0.17.0.tar.gz", "has_sig": false, "md5_digest": "9ba679b8b23db97036c2ac66e175e754", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10675, "upload_time": "2019-10-12T08:16:46", "url": "https://files.pythonhosted.org/packages/65/d0/35e8f890a7f499dfca20093d154f01c40cc5cb61510cfa3a493a43ea3982/pyfuzzer-0.17.0.tar.gz" } ] }