[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6XEP1AMECWWMC4W60K1F254":3,"skill-same:01M6XEP1AMECWWMC4W60K1F254":64},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":13,"repositoryHtmlUrl":46,"repositoryHomepageUrl":6,"ownerHtmlUrl":47,"ownerBlogUrl":6,"ownerDescription":48,"updatedAt":49,"install":50,"resources":63},"01M6XEP1AMECWWMC4W60K1F254","fuzzing-python",null,"Creating fuzz driver for Python libraries using LibFuzzer. This skill is useful when agent needs to work with creating fuzz drivers \u002F fuzz targets for Python project and libraries.","Waaaalnut\u002Fskillsbench","Waaaalnut","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F103995656?v=4","01M6XCS9K1V51EY3JMB7DGMX24","01M6XCS9Q4WPW88W62C55G1H44",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fsetup-fuzzing-py\u002Fenvironment\u002Fskills\u002Ffuzzing-python\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33,34,35,36],"python","fuzzing","fuzzing python","libraries","work","project","libfuzzer","driver","targets","python project","with","for","when","useful","2026-11-10 10:12:30",false,"---\nname: fuzzing-python\ndescription: \"Creating fuzz driver for Python libraries using LibFuzzer. This skill is useful when agent needs to work with creating fuzz drivers \u002F fuzz targets for Python project and libraries.\"\nlicense: Apache License 2.0. https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fatheris\u002Fblob\u002F775b08fb1a781142540995e8a2817c48ffae343f\u002FLICENSE\n---\n\n# Python Fuzzing Skill\n\n## Setting up fuzzing for a Python project\n\nFuzz testing for Python projects are Atheris.\nAtheris is a coverage-guided Python fuzzing engine.\nIt supports fuzzing of Python code, but also native extensions written for CPython.\nAtheris is based off of libFuzzer.\nWhen fuzzing native code,\nAtheris can be used in combination with Address Sanitizer or Undefined Behavior Sanitizer to catch extra bugs.\n\nYou can install prebuilt versions of Atheris with pip:\n\n```sh\npip3 install atheris\n```\n\nThese wheels come with a built-in libFuzzer,\nwhich is fine for fuzzing Python code.\nIf you plan to fuzz native extensions,\nyou may need to build from source to ensure the libFuzzer version in Atheris matches your Clang version.\n\n## Using Atheris\n\n### Example\n\n```python\n#!\u002Fusr\u002Fbin\u002Fpython3\n\nimport atheris\n\nwith atheris.instrument_imports():\n  import some_library\n  import sys\n\ndef TestOneInput(data):\n  some_library.parse(data)\n\natheris.Setup(sys.argv, TestOneInput)\natheris.Fuzz()\n```\n\nWhen fuzzing Python, Atheris will report a failure if the Python code under test throws an uncaught exception.\n\n### Python coverage\n\nAtheris collects Python coverage information by instrumenting bytecode.\nThere are 3 options for adding this instrumentation to the bytecode:\n\n- You can instrument the libraries you import:\n\n  ```python\n  with atheris.instrument_imports():\n    import foo\n    from bar import baz\n  ```\n\n  This will cause instrumentation to be added to `foo` and `bar`, as well as\n  any libraries they import.\n\n- Or, you can instrument individual functions:\n\n  ```python\n  @atheris.instrument_func\n  def my_function(foo, bar):\n    print(\"instrumented\")\n  ```\n\n- Or finally, you can instrument everything:\n\n  ```python\n  atheris.instrument_all()\n  ```\n\n  Put this right before `atheris.Setup()`. This will find every Python function\n  currently loaded in the interpreter, and instrument it.\n  This might take a while.\n\nAtheris can additionally instrument regular expression checks, e.g. `re.search`.\nTo enable this feature, you will need to add:\n`atheris.enabled_hooks.add(\"RegEx\")`\nTo your script before your code calls `re.compile`.\nInternally this will import the `re` module and instrument the necessary functions.\nThis is currently an experimental feature.\n\nSimilarly, Atheris can instrument str methods; currently only `str.startswith`\nand `str.endswith` are supported. To enable this feature, add\n`atheris.enabled_hooks.add(\"str\")`. This is currently an experimental feature.\n\n#### Why am I getting \"No interesting inputs were found\"?\n\nYou might see this error:\n\n```\nERROR: no interesting inputs were found. Is the code instrumented for coverage? Exiting.\n```\n\nYou'll get this error if the first 2 calls to `TestOneInput` didn't produce any\ncoverage events. Even if you have instrumented some Python code,\nthis can happen if the instrumentation isn't reached in those first 2 calls.\n(For example, because you have a nontrivial `TestOneInput`). You can resolve\nthis by adding an `atheris.instrument_func` decorator to `TestOneInput`,\nusing `atheris.instrument_all()`, or moving your `TestOneInput` function into an\ninstrumented module.\n\n### Visualizing Python code coverage\n\nExamining which lines are executed is helpful for understanding the\neffectiveness of your fuzzer. Atheris is compatible with\n[`coverage.py`](https:\u002F\u002Fcoverage.readthedocs.io\u002F): you can run your fuzzer using\nthe `coverage.py` module as you would for any other Python program. Here's an\nexample:\n\n```bash\npython3 -m coverage run your_fuzzer.py -atheris_runs=10000  # Times to run\npython3 -m coverage html\n(cd htmlcov && python3 -m http.server 8000)\n```\n\nCoverage reports are only generated when your fuzzer exits gracefully. This\nhappens if:\n\n- you specify `-atheris_runs=\u003Cnumber>`, and that many runs have elapsed.\n- your fuzzer exits by Python exception.\n- your fuzzer exits by `sys.exit()`.\n\nNo coverage report will be generated if your fuzzer exits due to a\ncrash in native code, or due to libFuzzer's `-runs` flag (use `-atheris_runs`).\nIf your fuzzer exits via other methods, such as SIGINT (Ctrl+C), Atheris will\nattempt to generate a report but may be unable to (depending on your code).\nFor consistent reports, we recommend always using\n`-atheris_runs=\u003Cnumber>`.\n\nIf you'd like to examine coverage when running with your corpus, you can do\nthat with the following command:\n\n```\npython3 -m coverage run your_fuzzer.py corpus_dir\u002F* -atheris_runs=$(( 1 + $(ls corpus_dir | wc -l) ))\n```\n\nThis will cause Atheris to run on each file in `\u003Ccorpus-dir>`, then exit.\nNote: atheris use empty data set as the first input even if there is no empty file in `\u003Ccorpus_dir>`.\nImportantly, if you leave off the `-atheris_runs=$(ls corpus_dir | wc -l)`, no\ncoverage report will be generated.\n\nUsing coverage.py will significantly slow down your fuzzer, so only use it for\nvisualizing coverage; don't use it all the time.\n\n### Fuzzing Native Extensions\n\nIn order for fuzzing native extensions to be effective, your native extensions\nmust be instrumented. See [Native Extension Fuzzing](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fatheris\u002Fblob\u002Fmaster\u002Fnative_extension_fuzzing.md)\nfor instructions.\n\n### Structure-aware Fuzzing\n\nAtheris is based on a coverage-guided mutation-based fuzzer (LibFuzzer). This\nhas the advantage of not requiring any grammar definition for generating inputs,\nmaking its setup easier. The disadvantage is that it will be harder for the\nfuzzer to generate inputs for code that parses complex data types. Often the\ninputs will be rejected early, resulting in low coverage.\n\nAtheris supports custom mutators\n[(as offered by LibFuzzer)](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Ffuzzing\u002Fblob\u002Fmaster\u002Fdocs\u002Fstructure-aware-fuzzing.md)\nto produce grammar-aware inputs.\n\nExample (Atheris-equivalent of the\n[example in the LibFuzzer docs](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Ffuzzing\u002Fblob\u002Fmaster\u002Fdocs\u002Fstructure-aware-fuzzing.md#example-compression)):\n\n```python\n@atheris.instrument_func\ndef TestOneInput(data):\n  try:\n    decompressed = zlib.decompress(data)\n  except zlib.error:\n    return\n\n  if len(decompressed) \u003C 2:\n    return\n\n  try:\n    if decompressed.decode() == 'FU':\n      raise RuntimeError('Boom')\n  except UnicodeDecodeError:\n    pass\n```\n\nTo reach the `RuntimeError` crash, the fuzzer needs to be able to produce inputs\nthat are valid compressed data and satisfy the checks after decompression.\nIt is very unlikely that Atheris will be able to produce such inputs: mutations\non the input data will most probably result in invalid data that will fail at\ndecompression-time.\n\nTo overcome this issue, you can define a custom mutator function (equivalent to\n`LLVMFuzzerCustomMutator`).\nThis example produces valid compressed data. To enable Atheris to make use of\nit, pass the custom mutator function to the invocation of `atheris.Setup`.\n\n```python\ndef CustomMutator(data, max_size, seed):\n  try:\n    decompressed = zlib.decompress(data)\n  except zlib.error:\n    decompressed = b'Hi'\n  else:\n    decompressed = atheris.Mutate(decompressed, len(decompressed))\n  return zlib.compress(decompressed)\n\natheris.Setup(sys.argv, TestOneInput, custom_mutator=CustomMutator)\natheris.Fuzz()\n```\n\nAs seen in the example, the custom mutator may request Atheris to mutate data\nusing `atheris.Mutate()` (this is equivalent to `LLVMFuzzerMutate`).\n\nYou can experiment with [custom_mutator_example.py](example_fuzzers\u002Fcustom_mutator_example.py)\nand see that without the mutator Atheris would not be able to find the crash,\nwhile with the mutator this is achieved in a matter of seconds.\n\n```shell\n$ python3 example_fuzzers\u002Fcustom_mutator_example.py --no_mutator\n[...]\n#2      INITED cov: 2 ft: 2 corp: 1\u002F1b exec\u002Fs: 0 rss: 37Mb\n#524288 pulse  cov: 2 ft: 2 corp: 1\u002F1b lim: 4096 exec\u002Fs: 262144 rss: 37Mb\n#1048576        pulse  cov: 2 ft: 2 corp: 1\u002F1b lim: 4096 exec\u002Fs: 349525 rss: 37Mb\n#2097152        pulse  cov: 2 ft: 2 corp: 1\u002F1b lim: 4096 exec\u002Fs: 299593 rss: 37Mb\n#4194304        pulse  cov: 2 ft: 2 corp: 1\u002F1b lim: 4096 exec\u002Fs: 279620 rss: 37Mb\n[...]\n\n$ python3 example_fuzzers\u002Fcustom_mutator_example.py\n[...]\nINFO: found LLVMFuzzerCustomMutator (0x7f9c989fb0d0). Disabling -len_control by default.\n[...]\n#2      INITED cov: 2 ft: 2 corp: 1\u002F1b exec\u002Fs: 0 rss: 37Mb\n#3      NEW    cov: 4 ft: 4 corp: 2\u002F11b lim: 4096 exec\u002Fs: 0 rss: 37Mb L: 10\u002F10 MS: 1 Custom-\n#12     NEW    cov: 5 ft: 5 corp: 3\u002F21b lim: 4096 exec\u002Fs: 0 rss: 37Mb L: 10\u002F10 MS: 7 Custom-CrossOver-Custom-CrossOver-Custom-ChangeBit-Custom-\n === Uncaught Python exception: ===\nRuntimeError: Boom\nTraceback (most recent call last):\n  File \"example_fuzzers\u002Fcustom_mutator_example.py\", line 62, in TestOneInput\n    raise RuntimeError('Boom')\n[...]\n```\n\nCustom crossover functions (equivalent to `LLVMFuzzerCustomCrossOver`) are also\nsupported. You can pass the custom crossover function to the invocation of\n`atheris.Setup`. See its usage in [custom_crossover_fuzz_test.py](src\u002Fcustom_crossover_fuzz_test.py).\n\n#### Structure-aware Fuzzing with Protocol Buffers\n\n[libprotobuf-mutator](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Flibprotobuf-mutator) has\nbindings to use it together with Atheris to perform structure-aware fuzzing\nusing protocol buffers.\n\nSee the documentation for\n[atheris_libprotobuf_mutator](contrib\u002Flibprotobuf_mutator\u002FREADME.md).\n\n## Integration with OSS-Fuzz\n\nAtheris is fully supported by [OSS-Fuzz](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Foss-fuzz), Google's continuous fuzzing service for open source projects. For integrating with OSS-Fuzz, please see [https:\u002F\u002Fgoogle.github.io\u002Foss-fuzz\u002Fgetting-started\u002Fnew-project-guide\u002Fpython-lang](https:\u002F\u002Fgoogle.github.io\u002Foss-fuzz\u002Fgetting-started\u002Fnew-project-guide\u002Fpython-lang).\n\n## API\n\nThe `atheris` module provides three key functions: `instrument_imports()`, `Setup()` and `Fuzz()`.\n\nIn your source file, import all libraries you wish to fuzz inside a `with atheris.instrument_imports():`-block, like this:\n\n```python\n# library_a will not get instrumented\nimport library_a\n\nwith atheris.instrument_imports():\n    # library_b will get instrumented\n    import library_b\n```\n\nGenerally, it's best to import `atheris` first and then import all other libraries inside of a `with atheris.instrument_imports()` block.\n\nNext, define a fuzzer entry point function and pass it to `atheris.Setup()` along with the fuzzer's arguments (typically `sys.argv`). Finally, call `atheris.Fuzz()` to start fuzzing. You must call `atheris.Setup()` before `atheris.Fuzz()`.\n\n#### `instrument_imports(include=[], exclude=[])`\n\n- `include`: A list of fully-qualified module names that shall be instrumented.\n- `exclude`: A list of fully-qualified module names that shall NOT be instrumented.\n\nThis should be used together with a `with`-statement. All modules imported in\nsaid statement will be instrumented. However, because Python imports all modules\nonly once, this cannot be used to instrument any previously imported module,\nincluding modules required by Atheris. To add coverage to those modules, use\n`instrument_all()` instead.\n\nA full list of unsupported modules can be retrieved as follows:\n\n```python\nimport sys\nimport atheris\nprint(sys.modules.keys())\n```\n\n#### `instrument_func(func)`\n\n- `func`: The function to instrument.\n\nThis will instrument the specified Python function and then return `func`. This\nis typically used as a decorator, but can be used to instrument individual\nfunctions too. Note that the `func` is instrumented in-place, so this will\naffect all call points of the function.\n\nThis cannot be called on a bound method - call it on the unbound version.\n\n#### `instrument_all()`\n\nThis will scan over all objects in the interpreter and call `instrument_func` on\nevery Python function. This works even on core Python interpreter functions,\nsomething which `instrument_imports` cannot do.\n\nThis function is experimental.\n\n#### `Setup(args, test_one_input, internal_libfuzzer=None)`\n\n- `args`: A list of strings: the process arguments to pass to the fuzzer, typically `sys.argv`. This argument list may be modified in-place, to remove arguments consumed by the fuzzer.\n  See [the LibFuzzer docs](https:\u002F\u002Fllvm.org\u002Fdocs\u002FLibFuzzer.html#options) for a list of such options.\n- `test_one_input`: your fuzzer's entry point. Must take a single `bytes` argument. This will be repeatedly invoked with a single bytes container.\n- `internal_libfuzzer`: Indicates whether libfuzzer will be provided by atheris or by an external library (see [native_extension_fuzzing.md](.\u002Fnative_extension_fuzzing.md)). If unspecified, Atheris will determine this\n  automatically. If fuzzing pure Python, leave this as `True`.\n\n#### `Fuzz()`\n\nThis starts the fuzzer. You must have called `Setup()` before calling this function. This function does not return.\n\nIn many cases `Setup()` and `Fuzz()` could be combined into a single function, but they are\nseparated because you may want the fuzzer to consume the command-line arguments it handles\nbefore passing any remaining arguments to another setup function.\n\n#### `FuzzedDataProvider`\n\nOften, a `bytes` object is not convenient input to your code being fuzzed. Similar to libFuzzer, we provide a FuzzedDataProvider to translate these bytes into other input forms.\n\nYou can construct the FuzzedDataProvider with:\n\n```python\nfdp = atheris.FuzzedDataProvider(input_bytes)\n```\n\nThe FuzzedDataProvider then supports the following functions:\n\n```python\ndef ConsumeBytes(count: int)\n```\n\nConsume `count` bytes.\n\n```python\ndef ConsumeUnicode(count: int)\n```\n\nConsume unicode characters. Might contain surrogate pair characters, which according to the specification are invalid in this situation. However, many core software tools (e.g. Windows file paths) support them, so other software often needs to too.\n\n```python\ndef ConsumeUnicodeNoSurrogates(count: int)\n```\n\nConsume unicode characters, but never generate surrogate pair characters.\n\n```python\ndef ConsumeString(count: int)\n```\n\nAlias for `ConsumeBytes` in Python 2, or `ConsumeUnicode` in Python 3.\n\n```python\ndef ConsumeInt(int: bytes)\n```\n\nConsume a signed integer of the specified size (when written in two's complement notation).\n\n```python\ndef ConsumeUInt(int: bytes)\n```\n\nConsume an unsigned integer of the specified size.\n\n```python\ndef ConsumeIntInRange(min: int, max: int)\n```\n\nConsume an integer in the range [`min`, `max`].\n\n```python\ndef ConsumeIntList(count: int, bytes: int)\n```\n\nConsume a list of `count` integers of `size` bytes.\n\n```python\ndef ConsumeIntListInRange(count: int, min: int, max: int)\n```\n\nConsume a list of `count` integers in the range [`min`, `max`].\n\n```python\ndef ConsumeFloat()\n```\n\nConsume an arbitrary floating-point value. Might produce weird values like `NaN` and `Inf`.\n\n```python\ndef ConsumeRegularFloat()\n```\n\nConsume an arbitrary numeric floating-point value; never produces a special type like `NaN` or `Inf`.\n\n```python\ndef ConsumeProbability()\n```\n\nConsume a floating-point value in the range [0, 1].\n\n```python\ndef ConsumeFloatInRange(min: float, max: float)\n```\n\nConsume a floating-point value in the range [`min`, `max`].\n\n```python\ndef ConsumeFloatList(count: int)\n```\n\nConsume a list of `count` arbitrary floating-point values. Might produce weird values like `NaN` and `Inf`.\n\n```python\ndef ConsumeRegularFloatList(count: int)\n```\n\nConsume a list of `count` arbitrary numeric floating-point values; never produces special types like `NaN` or `Inf`.\n\n```python\ndef ConsumeProbabilityList(count: int)\n```\n\nConsume a list of `count` floats in the range [0, 1].\n\n```python\ndef ConsumeFloatListInRange(count: int, min: float, max: float)\n```\n\nConsume a list of `count` floats in the range [`min`, `max`]\n\n```python\ndef PickValueInList(l: list)\n```\n\nGiven a list, pick a random value\n\n```python\ndef ConsumeBool()\n```\n\nConsume either `True` or `False`.\n\n## Important considerations for fuzz targets\n\nSome important things to remember about fuzz targets:\n\n- The fuzzing engine will execute the fuzz target many times with different inputs in the same process.\n- It must tolerate any kind of input (empty, huge, malformed, etc).\n- It must not exit() on any input.\n- It may use threads but ideally all threads should be joined at the end of the function.\n- It must be as deterministic as possible. Non-determinism (e.g. random decisions not based on the input bytes) will make fuzzing inefficient.\n- It must be fast. Try avoiding cubic or greater complexity, logging, or excessive memory consumption.\n- Ideally, it should not modify any global state (although that’s not strict).\n- Usually, the narrower the target the better. E.g. if your target can parse several data formats, split it into several targets, one per format.\n","# Python Fuzzing Skill\n\n## Setting up fuzzing for a Python project\n\nFuzz testing for Python projects are Atheris.\nAtheris is a coverage-guided Python fuzzing engine.\nIt supports fuzzing of Python code, but also native extensions written for CPython.\nAtheris is based off of libFuzzer.\nWhen fuzzing native code,\nAtheris can be used in combination with Address Sanitizer or Undefined Behavior Sanitizer to catch extra bugs.\n\nYou can install prebuilt versions of Atheris with pip:\n\n```sh\npip3 install atheris\n```\n\nThese wheels come with a built-in libFuzzer,\nwhich is fine for fuzzing Python code.\nIf you plan to fuzz native extensions,\nyou may need to build from source to ensure the libFuzzer version in Atheris matches your Clang version.\n\n## Using Atheris\n\n### Example\n\n```python\n#!\u002Fusr\u002Fbin\u002Fpython3\n\nimport atheris\n\nwith atheris.instrument_imports():\n  import some_library\n  import sys\n\ndef TestOneInput(data):\n  some_library.parse(data)\n\natheris.Setup(sys.argv, TestOneInput)\natheris.Fuzz()\n```\n\nWhen fuzzing Python, Atheris will report a failure if the Python code under test throws an uncaught exception.\n\n### Python coverage\n\nAtheris collects Python coverage information by instrumenting bytecode.\nThere are 3 options for adding this instrumentation to the bytecode:\n\n- You can instrument the libraries you import:\n\n  ```python\n  with atheris.instrument_imports():\n    import foo\n    from bar import baz\n  ```\n\n  This will cause instrumentation to be added to `foo` and `bar`, as well as\n  any libraries they import.\n\n- Or, you can instrument individual functions:\n\n  ```python\n  @atheris.instrument_func\n  def my_function(foo, bar):\n    print(\"instrumented\")\n  ```\n\n- Or finally, you can instrument everything:\n\n  ```python\n  atheris.instrument_all()\n  ```\n\n  Put this right before `atheris.Setup()`. This will find every Python function\n  currently loaded in the interpreter, and instrument it.\n  This might take a while.\n\nAtheris can additionally instrument regular expression checks, e.g. `re.search`.\nTo enable this feature, you will need to add:\n`atheris.enabled_hooks.add(\"RegEx\")`\nTo your script before your code calls `re.compile`.\nInternally this will import the `re` module and instrument the necessary functions.\nThis is currently an experimental feature.\n\nSimilarly, Atheris can instrument str methods; currently only `str.startswith`\nand `str.endswith` are supported. To enable this feature, add\n`atheris.enabled_hooks.add(\"str\")`. This is currently an experimental feature.\n\n#### Why am I getting \"No interesting inputs were found\"?\n\nYou might see this error:\n\n```\nERROR: no interesting inputs were found. Is the code instrumented for coverage? Exiting.\n```\n\nYou'll get this error if the first 2 calls to `TestOneInput` didn't produce any\ncoverage events. Even if you have instrumented some Python code,\nthis can happen if the instrumentation isn't reached in those first 2 calls.\n(For example, because you have a nontrivial `TestOneInput`). You can resolve\nthis by adding an `atheris.instrument_func` decorator to `TestOneInput`,\nusing `atheris.instrument_all()`, or moving your `TestOneInput` function into an\ninstrumented module.\n\n### Visualizing Python code coverage\n\nExamining which lines are executed is helpful for understanding the\neffectiveness of your fuzzer. Atheris is compatible with\n[`coverage.py`](https:\u002F\u002Fcoverage.readthedocs.io\u002F): you can run your fuzzer using\nthe `coverage.py` module as you would for any other Python program. Here's an\nexample:\n\n```bash\npython3 -m coverage run your_fuzzer.py -atheris_runs=10000  # Times to run\npython3 -m coverage html\n(cd htmlcov && python3 -m http.server 8000)\n```\n\nCoverage reports are only generated when your fuzzer exits gracefully. This\nhappens if:\n\n- you specify `-atheris_runs=\u003Cnumber>`, and that many runs have elapsed.\n- your fuzzer exits by Python exception.\n- your fuzzer exits by `sys.exit()`.\n\nNo coverage report will be generated if your fuzzer exits due to a\ncrash in native code, or due to libFuzzer's `-runs` flag (use `-atheris_runs`).\nIf your fuzzer exits via other methods, such as SIGINT (Ctrl+C), Atheris will\nattempt to generate a report but may be unable to (depending on your code).\nFor consistent reports, we recommend always using\n`-atheris_runs=\u003Cnumber>`.\n\nIf you'd like to examine coverage when running with your corpus, you can do\nthat with the following command:\n\n```\npython3 -m coverage run your_fuzzer.py corpus_dir\u002F* -atheris_runs=$(( 1 + $(ls corpus_dir | wc -l) ))\n```\n\nThis will cause Atheris to run on each file in `\u003Ccorpus-dir>`, then exit.\nNote: atheris use empty data set as the first input even if there is no empty file in `\u003Ccorpus_dir>`.\nImportantly, if you leave off the `-atheris_runs=$(ls corpus_dir | wc -l)`, no\ncoverage report will be generated.\n\nUsing coverage.py will significantly slow down your fuzzer, so only use it for\nvisualizing coverage; don't use it all the time.\n\n### Fuzzing Native Extensions\n\nIn order for fuzzing native extensions to be effective, your native extensions\nmust be instrumented. See [Native Extension Fuzzing](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fatheris\u002Fblob\u002Fmaster\u002Fnative_extension_fuzzing.md)\nfor instructions.\n\n### Structure-aware Fuzzing\n\nAtheris is based on a coverage-guided mutation-based fuzzer (LibFuzzer). This\nhas the advantage of not requiring any grammar definition for generating inputs,\nmaking its setup easier. The disadvantage is that it will be harder for the\nfuzzer to generate inputs for code that parses complex data types. Often the\ninputs will be rejected early, resulting in low coverage.\n\nAtheris supports custom mutators\n[(as offered by LibFuzzer)](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Ffuzzing\u002Fblob\u002Fmaster\u002Fdocs\u002Fstructure-aware-fuzzing.md)\nto produce grammar-aware inputs.\n\nExample (Atheris-equivalent of the\n[example in the LibFuzzer docs](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Ffuzzing\u002Fblob\u002Fmaster\u002Fdocs\u002Fstructure-aware-fuzzing.md#example-compression)):\n\n```python\n@atheris.instrument_func\ndef TestOneInput(data):\n  try:\n    decompressed = zlib.decompress(data)\n  except zlib.error:\n    return\n\n  if len(decompressed) \u003C 2:\n    return\n\n  try:\n    if decompressed.decode() == 'FU':\n      raise RuntimeError('Boom')\n  except UnicodeDecodeError:\n    pass\n```\n\nTo reach the `RuntimeError` crash, the fuzzer needs to be able to produce inputs\nthat are valid compressed data and satisfy the checks after decompression.\nIt is very unlikely that Atheris will be able to produce such inputs: mutations\non the input data will most probably result in invalid data that will fail at\ndecompression-time.\n\nTo overcome this issue, you can define a custom mutator function (equivalent to\n`LLVMFuzzerCustomMutator`).\nThis example produces valid compressed data. To enable Atheris to make use of\nit, pass the custom mutator function to the invocation of `atheris.Setup`.\n\n```python\ndef CustomMutator(data, max_size, seed):\n  try:\n    decompressed = zlib.decompress(data)\n  except zlib.error:\n    decompressed = b'Hi'\n  else:\n    decompressed = atheris.Mutate(decompressed, len(decompressed))\n  return zlib.compress(decompressed)\n\natheris.Setup(sys.argv, TestOneInput, custom_mutator=CustomMutator)\natheris.Fuzz()\n```\n\nAs seen in the example, the custom mutator may request Atheris to mutate data\nusing `atheris.Mutate()` (this is equivalent to `LLVMFuzzerMutate`).\n\nYou can experiment with [custom_mutator_example.py](example_fuzzers\u002Fcustom_mutator_example.py)\nand see that without the mutator Atheris would not be able to find the crash,\nwhile with the mutator this is achieved in a matter of seconds.\n\n```shell\n$ python3 example_fuzzers\u002Fcustom_mutator_example.py --no_mutator\n[...]\n#2      INITED cov: 2 ft: 2 corp: 1\u002F1b exec\u002Fs: 0 rss: 37Mb\n#524288 pulse  cov: 2 ft: 2 corp: 1\u002F1b lim: 4096 exec\u002Fs: 262144 rss: 37Mb\n#1048576        pulse  cov: 2 ft: 2 corp: 1\u002F1b lim: 4096 exec\u002Fs: 349525 rss: 37Mb\n#2097152        pulse  cov: 2 ft: 2 corp: 1\u002F1b lim: 4096 exec\u002Fs: 299593 rss: 37Mb\n#4194304        pulse  cov: 2 ft: 2 corp: 1\u002F1b lim: 4096 exec\u002Fs: 279620 rss: 37Mb\n[...]\n\n$ python3 example_fuzzers\u002Fcustom_mutator_example.py\n[...]\nINFO: found LLVMFuzzerCustomMutator (0x7f9c989fb0d0). Disabling -len_control by default.\n[...]\n#2      INITED cov: 2 ft: 2 corp: 1\u002F1b exec\u002Fs: 0 rss: 37Mb\n#3      NEW    cov: 4 ft: 4 corp: 2\u002F11b lim: 4096 exec\u002Fs: 0 rss: 37Mb L: 10\u002F10 MS: 1 Custom-\n#12     NEW    cov: 5 ft: 5 corp: 3\u002F21b lim: 4096 exec\u002Fs: 0 rss: 37Mb L: 10\u002F10 MS: 7 Custom-CrossOver-Custom-CrossOver-Custom-ChangeBit-Custom-\n === Uncaught Python exception: ===\nRuntimeError: Boom\nTraceback (most recent call last):\n  File \"example_fuzzers\u002Fcustom_mutator_example.py\", line 62, in TestOneInput\n    raise RuntimeError('Boom')\n[...]\n```\n\nCustom crossover functions (equivalent to `LLVMFuzzerCustomCrossOver`) are also\nsupported. You can pass the custom crossover function to the invocation of\n`atheris.Setup`. See its usage in [custom_crossover_fuzz_test.py](src\u002Fcustom_crossover_fuzz_test.py).\n\n#### Structure-aware Fuzzing with Protocol Buffers\n\n[libprotobuf-mutator](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Flibprotobuf-mutator) has\nbindings to use it together with Atheris to perform structure-aware fuzzing\nusing protocol buffers.\n\nSee the documentation for\n[atheris_libprotobuf_mutator](contrib\u002Flibprotobuf_mutator\u002FREADME.md).\n\n## Integration with OSS-Fuzz\n\nAtheris is fully supported by [OSS-Fuzz](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Foss-fuzz), Google's continuous fuzzing service for open source projects. For integrating with OSS-Fuzz, please see [https:\u002F\u002Fgoogle.github.io\u002Foss-fuzz\u002Fgetting-started\u002Fnew-project-guide\u002Fpython-lang](https:\u002F\u002Fgoogle.github.io\u002Foss-fuzz\u002Fgetting-started\u002Fnew-project-guide\u002Fpython-lang).\n\n## API\n\nThe `atheris` module provides three key functions: `instrument_imports()`, `Setup()` and `Fuzz()`.\n\nIn your source file, import all libraries you wish to fuzz inside a `with atheris.instrument_imports():`-block, like this:\n\n```python\n# library_a will not get instrumented\nimport library_a\n\nwith atheris.instrument_imports():\n    # library_b will get instrumented\n    import library_b\n```\n\nGenerally, it's best to import `atheris` first and then import all other libraries inside of a `with atheris.instrument_imports()` block.\n\nNext, define a fuzzer entry point function and pass it to `atheris.Setup()` along with the fuzzer's arguments (typically `sys.argv`). Finally, call `atheris.Fuzz()` to start fuzzing. You must call `atheris.Setup()` before `atheris.Fuzz()`.\n\n#### `instrument_imports(include=[], exclude=[])`\n\n- `include`: A list of fully-qualified module names that shall be instrumented.\n- `exclude`: A list of fully-qualified module names that shall NOT be instrumented.\n\nThis should be used together with a `with`-statement. All modules imported in\nsaid statement will be instrumented. However, because Python imports all modules\nonly once, this cannot be used to instrument any previously imported module,\nincluding modules required by Atheris. To add coverage to those modules, use\n`instrument_all()` instead.\n\nA full list of unsupported modules can be retrieved as follows:\n\n```python\nimport sys\nimport atheris\nprint(sys.modules.keys())\n```\n\n#### `instrument_func(func)`\n\n- `func`: The function to instrument.\n\nThis will instrument the specified Python function and then return `func`. This\nis typically used as a decorator, but can be used to instrument individual\nfunctions too. Note that the `func` is instrumented in-place, so this will\naffect all call points of the function.\n\nThis cannot be called on a bound method - call it on the unbound version.\n\n#### `instrument_all()`\n\nThis will scan over all objects in the interpreter and call `instrument_func` on\nevery Python function. This works even on core Python interpreter functions,\nsomething which `instrument_imports` cannot do.\n\nThis function is experimental.\n\n#### `Setup(args, test_one_input, internal_libfuzzer=None)`\n\n- `args`: A list of strings: the process arguments to pass to the fuzzer, typically `sys.argv`. This argument list may be modified in-place, to remove arguments consumed by the fuzzer.\n  See [the LibFuzzer docs](https:\u002F\u002Fllvm.org\u002Fdocs\u002FLibFuzzer.html#options) for a list of such options.\n- `test_one_input`: your fuzzer's entry point. Must take a single `bytes` argument. This will be repeatedly invoked with a single bytes container.\n- `internal_libfuzzer`: Indicates whether libfuzzer will be provided by atheris or by an external library (see [native_extension_fuzzing.md](.\u002Fnative_extension_fuzzing.md)). If unspecified, Atheris will determine this\n  automatically. If fuzzing pure Python, leave this as `True`.\n\n#### `Fuzz()`\n\nThis starts the fuzzer. You must have called `Setup()` before calling this function. This function does not return.\n\nIn many cases `Setup()` and `Fuzz()` could be combined into a single function, but they are\nseparated because you may want the fuzzer to consume the command-line arguments it handles\nbefore passing any remaining arguments to another setup function.\n\n#### `FuzzedDataProvider`\n\nOften, a `bytes` object is not convenient input to your code being fuzzed. Similar to libFuzzer, we provide a FuzzedDataProvider to translate these bytes into other input forms.\n\nYou can construct the FuzzedDataProvider with:\n\n```python\nfdp = atheris.FuzzedDataProvider(input_bytes)\n```\n\nThe FuzzedDataProvider then supports the following functions:\n\n```python\ndef ConsumeBytes(count: int)\n```\n\nConsume `count` bytes.\n\n```python\ndef ConsumeUnicode(count: int)\n```\n\nConsume unicode characters. Might contain surrogate pair characters, which according to the specification are invalid in this situation. However, many core software tools (e.g. Windows file paths) support them, so other software often needs to too.\n\n```python\ndef ConsumeUnicodeNoSurrogates(count: int)\n```\n\nConsume unicode characters, but never generate surrogate pair characters.\n\n```python\ndef ConsumeString(count: int)\n```\n\nAlias for `ConsumeBytes` in Python 2, or `ConsumeUnicode` in Python 3.\n\n```python\ndef ConsumeInt(int: bytes)\n```\n\nConsume a signed integer of the specified size (when written in two's complement notation).\n\n```python\ndef ConsumeUInt(int: bytes)\n```\n\nConsume an unsigned integer of the specified size.\n\n```python\ndef ConsumeIntInRange(min: int, max: int)\n```\n\nConsume an integer in the range [`min`, `max`].\n\n```python\ndef ConsumeIntList(count: int, bytes: int)\n```\n\nConsume a list of `count` integers of `size` bytes.\n\n```python\ndef ConsumeIntListInRange(count: int, min: int, max: int)\n```\n\nConsume a list of `count` integers in the range [`min`, `max`].\n\n```python\ndef ConsumeFloat()\n```\n\nConsume an arbitrary floating-point value. Might produce weird values like `NaN` and `Inf`.\n\n```python\ndef ConsumeRegularFloat()\n```\n\nConsume an arbitrary numeric floating-point value; never produces a special type like `NaN` or `Inf`.\n\n```python\ndef ConsumeProbability()\n```\n\nConsume a floating-point value in the range [0, 1].\n\n```python\ndef ConsumeFloatInRange(min: float, max: float)\n```\n\nConsume a floating-point value in the range [`min`, `max`].\n\n```python\ndef ConsumeFloatList(count: int)\n```\n\nConsume a list of `count` arbitrary floating-point values. Might produce weird values like `NaN` and `Inf`.\n\n```python\ndef ConsumeRegularFloatList(count: int)\n```\n\nConsume a list of `count` arbitrary numeric floating-point values; never produces special types like `NaN` or `Inf`.\n\n```python\ndef ConsumeProbabilityList(count: int)\n```\n\nConsume a list of `count` floats in the range [0, 1].\n\n```python\ndef ConsumeFloatListInRange(count: int, min: float, max: float)\n```\n\nConsume a list of `count` floats in the range [`min`, `max`]\n\n```python\ndef PickValueInList(l: list)\n```\n\nGiven a list, pick a random value\n\n```python\ndef ConsumeBool()\n```\n\nConsume either `True` or `False`.\n\n## Important considerations for fuzz targets\n\nSome important things to remember about fuzz targets:\n\n- The fuzzing engine will execute the fuzz target many times with different inputs in the same process.\n- It must tolerate any kind of input (empty, huge, malformed, etc).\n- It must not exit() on any input.\n- It may use threads but ideally all threads should be joined at the end of the function.\n- It must be as deterministic as possible. Non-determinism (e.g. random decisions not based on the input bytes) will make fuzzing inefficient.\n- It must be fast. Try avoiding cubic or greater complexity, logging, or excessive memory consumption.\n- Ideally, it should not modify any global state (although that’s not strict).\n- Usually, the narrower the target the better. E.g. if your target can parse several data formats, split it into several targets, one per format.\n",{"name":5,"license":42,"description":7},"Apache License 2.0. https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fatheris\u002Fblob\u002F775b08fb1a781142540995e8a2817c48ffae343f\u002FLICENSE","main","7eeb258ada72b7f58119b0e7a2c00ea89d9beedd","tasks\u002Fsetup-fuzzing-py\u002Fenvironment\u002Fskills\u002Ffuzzing-python","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench","https:\u002F\u002Fgithub.com\u002FWaaaalnut","student of Zhejiang University","2026-04-21 23:16:23",{"source":8,"skillName":5,"commands":51,"prompt":61,"zipAvailable":62},[52,55,58],{"tool":53,"command":54},"npx","npx skills add Waaaalnut\u002Fskillsbench --skill fuzzing-python",{"tool":56,"command":57},"bunx","bunx skills add Waaaalnut\u002Fskillsbench --skill fuzzing-python",{"tool":59,"command":60},"pnpm","pnpm dlx skills add Waaaalnut\u002Fskillsbench --skill fuzzing-python","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fsetup-fuzzing-py\u002Fenvironment\u002Fskills\u002Ffuzzing-python\u002FSKILL.md",true,[],[65,79,94,119,141,159],{"skillNo":66,"name":67,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":75,"publishedAt":37},"01M6XEWMJ6VY3ZC53MPDCPG3GH","data-reconciliation","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fxlsx-recover-data\u002Fenvironment\u002Fskills\u002Fdata-reconciliation\u002FSKILL.md",[70],{"categoryNo":71,"categoryName":72,"taxonomyType":73,"taxonomyTypeDesc":74},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[76,77,78],"data reconciliation","reconciliation","data",{"skillNo":80,"name":81,"nameZh":6,"description":82,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":83,"categories":84,"keywords":85,"publishedAt":37},"01M6XEW8MNPMF1KRXV6ATGFRQF","speech-to-text","Transcribe video to timestamped text using Whisper tiny model (pre-installed).","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-tutorial-indexer\u002Fenvironment\u002Fskills\u002Fspeech-to-text\u002FSKILL.md",[],[86,87,88,89,90,91,92,93],"speech","text","speech to text","transcribe video","whisper","model","Video","transcribe",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":103,"publishedAt":37},"01M6XEW3FQZP0T1RKQQJFXVY9T","video-processor","Process videos by removing segments and concatenating remaining parts. Use when you need to remove detected pauses\u002Fopenings from videos, create highlight reels, or batch process segment removals using ffmpeg filter_complex.","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Fvideo-processor\u002FSKILL.md",[100],{"categoryNo":101,"categoryName":102,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000016","图像与多媒体",[92,104,105,106,107,108,35,109,110,111,112,113,114,115,116,117,118],"processor","video processor","batch","create","reels","parts","segments","process","videos","you","segment","filter","ffmpeg","use","remove",{"skillNo":120,"name":121,"nameZh":6,"description":122,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":126,"publishedAt":37},"01M6XEVXJ5KZ0NTY3XZKRY4AS1","silence-detector","Detect initial silence segments in audio\u002Fvideo using energy-based analysis. Use when you need to find low-energy periods at the start of recordings (title slides, setup time, pre-roll silence).","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Fsilence-detector\u002FSKILL.md",[125],{"categoryNo":101,"categoryName":102,"taxonomyType":20,"taxonomyTypeDesc":21},[127,128,129,130,35,113,131,132,133,134,135,110,136,137,92,138,139,140,117],"detector","silence detector","title","slides","time","energy","at","recordings","detect","find","Audio","analysis","start","setup",{"skillNo":142,"name":143,"nameZh":6,"description":144,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":145,"categories":146,"keywords":147,"publishedAt":37},"01M6XEVT3NGRN1FT7JPMAPXS6M","segment-combiner","Combine multiple segment detection results into a unified list. Use when you need to merge segments from different detectors, prepare removal lists for video processing, or consolidate detection outputs.","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Fsegment-combiner\u002FSKILL.md",[],[114,148,92,149,150,151,152,34,35,153,154,110,113,155,156,117,157,158],"segment combiner","detection","prepare","merge","video processing","outputs","combine","processing","consolidate","results","list",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":168,"publishedAt":37},"01M6XEVMPVASGS2KX86QK4FMT7","report-generator","Generate compression reports for video processing. Use when you need to create structured JSON reports with duration statistics, compression ratios, and segment details after video processing.","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Freport-generator\u002FSKILL.md",[165],{"categoryNo":166,"categoryName":167,"taxonomyType":73,"taxonomyTypeDesc":74},"01JBSEEDCAT000000000000034","行政与办公人员",[169,170,171,114,35,34,113,33,155,172,173,174,117,152,175,92,176,177,107],"generator","report generator","report","statistics","structured","reports","json","compression","generate"]