Details
Details
- Reviewers
- None
- Group Reviewers
hg-reviewers - Commits
- rHGb444407f635b: fuzz: new fuzzer for dirstate parser
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/dirstate.cc (48 lines) | ||
| A | M | contrib/fuzz/dirstate_corpus.py (18 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| Augie Fackler | Dec 19 2018, 11:48 PM |
| -I../../mercurial revlog.cc \ | -I../../mercurial revlog.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/revlog_fuzzer | -o $$OUT/revlog_fuzzer | ||||
| revlog_corpus.zip: | revlog_corpus.zip: | ||||
| python revlog_corpus.py $$OUT/revlog_fuzzer_seed_corpus.zip | python revlog_corpus.py $$OUT/revlog_fuzzer_seed_corpus.zip | ||||
| dirstate_fuzzer: sanpy dirstate.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 dirstate.cc \ | |||||
| manifest.o charencode.o parsers.o dirs.o pathencode.o revlog.o pyutil.o \ | |||||
| -lFuzzingEngine `$$OUT/sanpy/bin/python-config --ldflags` \ | |||||
| -o $$OUT/dirstate_fuzzer | |||||
| dirstate_corpus.zip: | |||||
| python dirstate_corpus.py $$OUT/dirstate_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 revlog_fuzzer revlog_corpus.zip | oss-fuzz: bdiff_fuzzer mpatch_fuzzer mpatch_corpus.zip xdiff_fuzzer manifest_fuzzer manifest_corpus.zip revlog_fuzzer revlog_corpus.zip dirstate_fuzzer dirstate_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_dirstate | |||||
| try: | |||||
| dmap = {} | |||||
| copymap = {} | |||||
| p = parse_dirstate(dmap, copymap, data) | |||||
| 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__), | |||||
| '..', '..')) | |||||
| dirstate = os.path.join(reporoot, '.hg', 'dirstate') | |||||
| with zipfile.ZipFile(args.out[0], "w", zipfile.ZIP_STORED) as zf: | |||||
| if os.path.exists(dirstate): | |||||
| with open(dirstate) as f: | |||||
| zf.writestr("dirstate", f.read()) | |||||