comparison contrib/fuzz/jsonescapeu8fast.cc @ 43153:741fb1a95da2

fuzz: new target to fuzz jsonescapeu8fast This code just feels complicated enough we should go ahead and give it a dedicated fuzzer: we've found bugs in similar things before. Differential Revision: https://phab.mercurial-scm.org/D7034
author Augie Fackler <augie@google.com>
date Wed, 09 Oct 2019 20:49:58 -0700
parents
children 5a9e2ae9899b
comparison
equal deleted inserted replaced
43152:b37dd26935ee 43153:741fb1a95da2
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 }