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