/src/mercurial/contrib/fuzz/jsonescapeu8fast.cc
Line | Count | Source |
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 | | #include "FuzzedDataProvider.h" |
11 | | |
12 | | extern "C" { |
13 | | |
14 | | static PYCODETYPE *code; |
15 | | |
16 | | extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) |
17 | 3 | { |
18 | 3 | contrib::initpy(*argv[0]); |
19 | 3 | code = (PYCODETYPE *)Py_CompileString(R"py( |
20 | 3 | try: |
21 | 3 | parsers.jsonescapeu8fast(data, paranoid) |
22 | 3 | except Exception as e: |
23 | 3 | pass |
24 | 3 | # uncomment this print if you're editing this Python code |
25 | 3 | # to debug failures. |
26 | 3 | # print(e) |
27 | 3 | )py", |
28 | 3 | "fuzzer", Py_file_input); |
29 | 3 | if (!code) { |
30 | 0 | std::cerr << "failed to compile Python code!" << std::endl; |
31 | 0 | } |
32 | 3 | return 0; |
33 | 3 | } |
34 | | |
35 | | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) |
36 | | { |
37 | | FuzzedDataProvider provider(Data, Size); |
38 | | bool paranoid = provider.ConsumeBool(); |
39 | | std::string remainder = provider.ConsumeRemainingBytesAsString(); |
40 | | |
41 | | PyObject *mtext = PyBytes_FromStringAndSize( |
42 | | (const char *)remainder.c_str(), remainder.size()); |
43 | | PyObject *locals = PyDict_New(); |
44 | | PyDict_SetItemString(locals, "data", mtext); |
45 | | PyDict_SetItemString(locals, "paranoid", paranoid ? Py_True : Py_False); |
46 | | PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals); |
47 | | if (!res) { |
48 | | PyErr_Print(); |
49 | | } |
50 | | Py_XDECREF(res); |
51 | | Py_DECREF(locals); |
52 | | Py_DECREF(mtext); |
53 | | return 0; // Non-zero return values are reserved for future use. |
54 | | } |
55 | | } |