/src/mercurial/contrib/fuzz/fncache.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include <Python.h> |
2 | | #include <assert.h> |
3 | | #include <stdlib.h> |
4 | | #include <unistd.h> |
5 | | |
6 | | #include "pyutil.h" |
7 | | |
8 | | #include <iostream> |
9 | | #include <string> |
10 | | |
11 | | extern "C" { |
12 | | |
13 | | static PYCODETYPE *code; |
14 | | |
15 | | extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) |
16 | 4 | { |
17 | 4 | contrib::initpy(*argv[0]); |
18 | 4 | code = (PYCODETYPE *)Py_CompileString(R"py( |
19 | 4 | try: |
20 | 4 | for fn in ( |
21 | 4 | parsers.isasciistr, |
22 | 4 | parsers.asciilower, |
23 | 4 | parsers.asciiupper, |
24 | 4 | parsers.encodedir, |
25 | 4 | parsers.pathencode, |
26 | 4 | parsers.lowerencode, |
27 | 4 | ): |
28 | 4 | try: |
29 | 4 | fn(data) |
30 | 4 | except UnicodeDecodeError: |
31 | 4 | pass # some functions emit this exception |
32 | 4 | except AttributeError: |
33 | 4 | # pathencode needs hashlib, which fails to import because the time |
34 | 4 | # module fails to import. We should try and fix that some day, but |
35 | 4 | # for now we at least get coverage on non-hashencoded codepaths. |
36 | 4 | if fn != pathencode: |
37 | 4 | raise |
38 | 4 | # uncomment this for debugging exceptions |
39 | 4 | # except Exception as e: |
40 | 4 | # raise Exception('%r: %r' % (fn, e)) |
41 | 4 | except Exception as e: |
42 | 4 | pass |
43 | 4 | # uncomment this print if you're editing this Python code |
44 | 4 | # to debug failures. |
45 | 4 | # print(e) |
46 | 4 | )py", |
47 | 4 | "fuzzer", Py_file_input); |
48 | 4 | if (!code) { |
49 | 0 | std::cerr << "failed to compile Python code!" << std::endl; |
50 | 0 | } |
51 | 4 | return 0; |
52 | 4 | } |
53 | | |
54 | | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) |
55 | 1.84k | { |
56 | 1.84k | PyObject *mtext = |
57 | 1.84k | PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size); |
58 | 1.84k | PyObject *locals = PyDict_New(); |
59 | 1.84k | PyDict_SetItemString(locals, "data", mtext); |
60 | 1.84k | PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals); |
61 | 1.84k | if (!res) { |
62 | 0 | PyErr_Print(); |
63 | 0 | } |
64 | 1.84k | Py_XDECREF(res); |
65 | 1.84k | Py_DECREF(locals); |
66 | 1.84k | Py_DECREF(mtext); |
67 | 1.84k | return 0; // Non-zero return values are reserved for future use. |
68 | 1.84k | } |
69 | | } |