Details
Details
- Reviewers
- None
- Group Reviewers
hg-reviewers - Commits
- rHGc06f0ef9a5ba: fuzz: new fuzzer for revlog's parse_index2 method
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Lint
Lint Skipped - Unit
Unit Tests Skipped
( )
| hg-reviewers |
| Lint Skipped |
| Unit Tests Skipped |
| Path | Packages | |||
|---|---|---|---|---|
| M | contrib/fuzz/Makefile (13 lines) | |||
| A | M | contrib/fuzz/revlog.cc (47 lines) | ||
| A | M | contrib/fuzz/revlog_corpus.py (28 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| Augie Fackler | Dec 19 2018, 8:26 PM |
| -I../../mercurial manifest.cc \ | -I../../mercurial manifest.cc \ | ||||
| manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o pyutil.o \ | manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o pyutil.o \ | ||||
| -lFuzzingEngine `$$OUT/sanpy/bin/python-config --ldflags` \ | -lFuzzingEngine `$$OUT/sanpy/bin/python-config --ldflags` \ | ||||
| -o $$OUT/manifest_fuzzer | -o $$OUT/manifest_fuzzer | ||||
| manifest_corpus.zip: | manifest_corpus.zip: | ||||
| python manifest_corpus.py $$OUT/manifest_fuzzer_seed_corpus.zip | python manifest_corpus.py $$OUT/manifest_fuzzer_seed_corpus.zip | ||||
| revlog_fuzzer: sanpy revlog.cc manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o pyutil.o | |||||
| $(CXX) $(CXXFLAGS) `$$OUT/sanpy/bin/python-config --cflags` \ | |||||
| -Wno-register -Wno-macro-redefined \ | |||||
| -I../../mercurial revlog.cc \ | |||||
| manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o pyutil.o \ | |||||
| -lFuzzingEngine `$$OUT/sanpy/bin/python-config --ldflags` \ | |||||
| -o $$OUT/revlog_fuzzer | |||||
| revlog_corpus.zip: | |||||
| python revlog_corpus.py $$OUT/revlog_fuzzer_seed_corpus.zip | |||||
| clean: | clean: | ||||
| $(RM) *.o *_fuzzer \ | $(RM) *.o *_fuzzer \ | ||||
| bdiff \ | bdiff \ | ||||
| mpatch \ | mpatch \ | ||||
| xdiff | xdiff | ||||
| oss-fuzz: bdiff_fuzzer mpatch_fuzzer mpatch_corpus.zip xdiff_fuzzer manifest_fuzzer manifest_corpus.zip | oss-fuzz: bdiff_fuzzer mpatch_fuzzer mpatch_corpus.zip xdiff_fuzzer manifest_fuzzer manifest_corpus.zip revlog_fuzzer revlog_corpus.zip | ||||
| .PHONY: all clean oss-fuzz sanpy | .PHONY: all clean oss-fuzz sanpy | ||||
| #include <Python.h> | |||||
| #include <assert.h> | |||||
| #include <stdlib.h> | |||||
| #include <unistd.h> | |||||
| #include <string> | |||||
| #include "pyutil.h" | |||||
| extern "C" { | |||||
| static PyCodeObject *code; | |||||
| extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) | |||||
| { | |||||
| contrib::initpy(*argv[0]); | |||||
| code = (PyCodeObject *)Py_CompileString(R"py( | |||||
| from parsers import parse_index2 | |||||
| for inline in (True, False): | |||||
| try: | |||||
| index, cache = parse_index2(data, inline) | |||||
| except Exception as e: | |||||
| pass | |||||
| # uncomment this print if you're editing this Python code | |||||
| # to debug failures. | |||||
| # print e | |||||
| )py", | |||||
| "fuzzer", Py_file_input); | |||||
| return 0; | |||||
| } | |||||
| int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) | |||||
| { | |||||
| PyObject *text = | |||||
| PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size); | |||||
| PyObject *locals = PyDict_New(); | |||||
| PyDict_SetItemString(locals, "data", text); | |||||
| PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals); | |||||
| if (!res) { | |||||
| PyErr_Print(); | |||||
| } | |||||
| Py_XDECREF(res); | |||||
| Py_DECREF(locals); | |||||
| Py_DECREF(text); | |||||
| return 0; // Non-zero return values are reserved for future use. | |||||
| } | |||||
| } | |||||
| from __future__ import absolute_import, print_function | |||||
| import argparse | |||||
| import os | |||||
| import zipfile | |||||
| ap = argparse.ArgumentParser() | |||||
| ap.add_argument("out", metavar="some.zip", type=str, nargs=1) | |||||
| args = ap.parse_args() | |||||
| reporoot = os.path.normpath(os.path.join(os.path.dirname(__file__), | |||||
| '..', '..')) | |||||
| # typically a standalone index | |||||
| changelog = os.path.join(reporoot, '.hg', 'store', '00changelog.i') | |||||
| # an inline revlog with only a few revisions | |||||
| contributing = os.path.join( | |||||
| reporoot, '.hg', 'store', 'data', 'contrib', 'fuzz', 'mpatch.cc.i') | |||||
| print(changelog, os.path.exists(changelog)) | |||||
| print(contributing, os.path.exists(contributing)) | |||||
| with zipfile.ZipFile(args.out[0], "w", zipfile.ZIP_STORED) as zf: | |||||
| if os.path.exists(changelog): | |||||
| with open(changelog) as f: | |||||
| zf.writestr("00changelog.i", f.read()) | |||||
| if os.path.exists(contributing): | |||||
| with open(contributing) as f: | |||||
| zf.writestr("contributing.i", f.read()) | |||||