##// END OF EJS Templates
fuzz: add support for fuzzing under either Python 2 or 3...
Augie Fackler -
r44311:8766728d default
parent child Browse files
Show More
@@ -1,56 +1,55 b''
1 #include <Python.h>
1 #include <Python.h>
2 #include <assert.h>
2 #include <assert.h>
3 #include <stdlib.h>
3 #include <stdlib.h>
4 #include <unistd.h>
4 #include <unistd.h>
5
5
6 #include "pyutil.h"
6 #include "pyutil.h"
7
7
8 #include <string>
8 #include <string>
9
9
10 extern "C" {
10 extern "C" {
11
11
12 static PyCodeObject *code;
12 static PYCODETYPE *code;
13
13
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
15 {
15 {
16 contrib::initpy(*argv[0]);
16 contrib::initpy(*argv[0]);
17 code = (PyCodeObject *)Py_CompileString(R"py(
17 code = (PYCODETYPE *)Py_CompileString(R"py(
18 from parsers import dirs
19 try:
18 try:
20 files = mdata.split('\n')
19 files = mdata.split('\n')
21 d = dirs(files)
20 d = parsers.dirs(files)
22 list(d)
21 list(d)
23 'a' in d
22 'a' in d
24 if files:
23 if files:
25 files[0] in d
24 files[0] in d
26 except Exception as e:
25 except Exception as e:
27 pass
26 pass
28 # uncomment this print if you're editing this Python code
27 # uncomment this print if you're editing this Python code
29 # to debug failures.
28 # to debug failures.
30 # print e
29 # print e
31 )py",
30 )py",
32 "fuzzer", Py_file_input);
31 "fuzzer", Py_file_input);
33 return 0;
32 return 0;
34 }
33 }
35
34
36 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
35 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
37 {
36 {
38 // Don't allow fuzzer inputs larger than 100k, since we'll just bog
37 // Don't allow fuzzer inputs larger than 100k, since we'll just bog
39 // down and not accomplish much.
38 // down and not accomplish much.
40 if (Size > 100000) {
39 if (Size > 100000) {
41 return 0;
40 return 0;
42 }
41 }
43 PyObject *mtext =
42 PyObject *mtext =
44 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
43 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
45 PyObject *locals = PyDict_New();
44 PyObject *locals = PyDict_New();
46 PyDict_SetItemString(locals, "mdata", mtext);
45 PyDict_SetItemString(locals, "mdata", mtext);
47 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
46 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
48 if (!res) {
47 if (!res) {
49 PyErr_Print();
48 PyErr_Print();
50 }
49 }
51 Py_XDECREF(res);
50 Py_XDECREF(res);
52 Py_DECREF(locals);
51 Py_DECREF(locals);
53 Py_DECREF(mtext);
52 Py_DECREF(mtext);
54 return 0; // Non-zero return values are reserved for future use.
53 return 0; // Non-zero return values are reserved for future use.
55 }
54 }
56 }
55 }
@@ -1,48 +1,47 b''
1 #include <Python.h>
1 #include <Python.h>
2 #include <assert.h>
2 #include <assert.h>
3 #include <stdlib.h>
3 #include <stdlib.h>
4 #include <unistd.h>
4 #include <unistd.h>
5
5
6 #include <string>
6 #include <string>
7
7
8 #include "pyutil.h"
8 #include "pyutil.h"
9
9
10 extern "C" {
10 extern "C" {
11
11
12 static PyCodeObject *code;
12 static PYCODETYPE *code;
13
13
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
15 {
15 {
16 contrib::initpy(*argv[0]);
16 contrib::initpy(*argv[0]);
17 code = (PyCodeObject *)Py_CompileString(R"py(
17 code = (PYCODETYPE *)Py_CompileString(R"py(
18 from parsers import parse_dirstate
19 try:
18 try:
20 dmap = {}
19 dmap = {}
21 copymap = {}
20 copymap = {}
22 p = parse_dirstate(dmap, copymap, data)
21 p = parsers.parse_dirstate(dmap, copymap, data)
23 except Exception as e:
22 except Exception as e:
24 pass
23 pass
25 # uncomment this print if you're editing this Python code
24 # uncomment this print if you're editing this Python code
26 # to debug failures.
25 # to debug failures.
27 # print e
26 # print e
28 )py",
27 )py",
29 "fuzzer", Py_file_input);
28 "fuzzer", Py_file_input);
30 return 0;
29 return 0;
31 }
30 }
32
31
33 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
32 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
34 {
33 {
35 PyObject *text =
34 PyObject *text =
36 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
35 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
37 PyObject *locals = PyDict_New();
36 PyObject *locals = PyDict_New();
38 PyDict_SetItemString(locals, "data", text);
37 PyDict_SetItemString(locals, "data", text);
39 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
38 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
40 if (!res) {
39 if (!res) {
41 PyErr_Print();
40 PyErr_Print();
42 }
41 }
43 Py_XDECREF(res);
42 Py_XDECREF(res);
44 Py_DECREF(locals);
43 Py_DECREF(locals);
45 Py_DECREF(text);
44 Py_DECREF(text);
46 return 0; // Non-zero return values are reserved for future use.
45 return 0; // Non-zero return values are reserved for future use.
47 }
46 }
48 }
47 }
@@ -1,60 +1,59 b''
1 #include <Python.h>
1 #include <Python.h>
2 #include <assert.h>
2 #include <assert.h>
3 #include <stdlib.h>
3 #include <stdlib.h>
4 #include <unistd.h>
4 #include <unistd.h>
5
5
6 #include <string>
6 #include <string>
7
7
8 #include "pyutil.h"
8 #include "pyutil.h"
9
9
10 extern "C" {
10 extern "C" {
11
11
12 static PyCodeObject *code;
12 static PYCODETYPE *code;
13
13
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
15 {
15 {
16 contrib::initpy(*argv[0]);
16 contrib::initpy(*argv[0]);
17 code = (PyCodeObject *)Py_CompileString(R"py(
17 code = (PYCODETYPE *)Py_CompileString(R"py(
18 from parsers import fm1readmarkers
19 def maybeint(s, default):
18 def maybeint(s, default):
20 try:
19 try:
21 return int(s)
20 return int(s)
22 except ValueError:
21 except ValueError:
23 return default
22 return default
24 try:
23 try:
25 parts = data.split('\0', 2)
24 parts = data.split('\0', 2)
26 if len(parts) == 3:
25 if len(parts) == 3:
27 offset, stop, data = parts
26 offset, stop, data = parts
28 elif len(parts) == 2:
27 elif len(parts) == 2:
29 stop, data = parts
28 stop, data = parts
30 offset = 0
29 offset = 0
31 else:
30 else:
32 offset = stop = 0
31 offset = stop = 0
33 offset, stop = maybeint(offset, 0), maybeint(stop, len(data))
32 offset, stop = maybeint(offset, 0), maybeint(stop, len(data))
34 fm1readmarkers(data, offset, stop)
33 parsers.fm1readmarkers(data, offset, stop)
35 except Exception as e:
34 except Exception as e:
36 pass
35 pass
37 # uncomment this print if you're editing this Python code
36 # uncomment this print if you're editing this Python code
38 # to debug failures.
37 # to debug failures.
39 # print e
38 # print e
40 )py",
39 )py",
41 "fuzzer", Py_file_input);
40 "fuzzer", Py_file_input);
42 return 0;
41 return 0;
43 }
42 }
44
43
45 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
44 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
46 {
45 {
47 PyObject *text =
46 PyObject *text =
48 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
47 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
49 PyObject *locals = PyDict_New();
48 PyObject *locals = PyDict_New();
50 PyDict_SetItemString(locals, "data", text);
49 PyDict_SetItemString(locals, "data", text);
51 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
50 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
52 if (!res) {
51 if (!res) {
53 PyErr_Print();
52 PyErr_Print();
54 }
53 }
55 Py_XDECREF(res);
54 Py_XDECREF(res);
56 Py_DECREF(locals);
55 Py_DECREF(locals);
57 Py_DECREF(text);
56 Py_DECREF(text);
58 return 0; // Non-zero return values are reserved for future use.
57 return 0; // Non-zero return values are reserved for future use.
59 }
58 }
60 }
59 }
@@ -1,78 +1,69 b''
1 #include <Python.h>
1 #include <Python.h>
2 #include <assert.h>
2 #include <assert.h>
3 #include <stdlib.h>
3 #include <stdlib.h>
4 #include <unistd.h>
4 #include <unistd.h>
5
5
6 #include "pyutil.h"
6 #include "pyutil.h"
7
7
8 #include <iostream>
8 #include <iostream>
9 #include <string>
9 #include <string>
10
10
11 extern "C" {
11 extern "C" {
12
12
13 static PyCodeObject *code;
13 static PYCODETYPE *code;
14
14
15 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
15 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
16 {
16 {
17 contrib::initpy(*argv[0]);
17 contrib::initpy(*argv[0]);
18 code = (PyCodeObject *)Py_CompileString(R"py(
18 code = (PYCODETYPE *)Py_CompileString(R"py(
19 from parsers import (
20 isasciistr,
21 asciilower,
22 asciiupper,
23 encodedir,
24 pathencode,
25 lowerencode,
26 )
27
28 try:
19 try:
29 for fn in (
20 for fn in (
30 isasciistr,
21 parsers.isasciistr,
31 asciilower,
22 parsers.asciilower,
32 asciiupper,
23 parsers.asciiupper,
33 encodedir,
24 parsers.encodedir,
34 pathencode,
25 parsers.pathencode,
35 lowerencode,
26 parsers.lowerencode,
36 ):
27 ):
37 try:
28 try:
38 fn(data)
29 fn(data)
39 except UnicodeDecodeError:
30 except UnicodeDecodeError:
40 pass # some functions emit this exception
31 pass # some functions emit this exception
41 except AttributeError:
32 except AttributeError:
42 # pathencode needs hashlib, which fails to import because the time
33 # pathencode needs hashlib, which fails to import because the time
43 # module fails to import. We should try and fix that some day, but
34 # module fails to import. We should try and fix that some day, but
44 # for now we at least get coverage on non-hashencoded codepaths.
35 # for now we at least get coverage on non-hashencoded codepaths.
45 if fn != pathencode:
36 if fn != pathencode:
46 raise
37 raise
47 # uncomment this for debugging exceptions
38 # uncomment this for debugging exceptions
48 # except Exception as e:
39 # except Exception as e:
49 # raise Exception('%r: %r' % (fn, e))
40 # raise Exception('%r: %r' % (fn, e))
50 except Exception as e:
41 except Exception as e:
51 pass
42 pass
52 # uncomment this print if you're editing this Python code
43 # uncomment this print if you're editing this Python code
53 # to debug failures.
44 # to debug failures.
54 # print(e)
45 # print(e)
55 )py",
46 )py",
56 "fuzzer", Py_file_input);
47 "fuzzer", Py_file_input);
57 if (!code) {
48 if (!code) {
58 std::cerr << "failed to compile Python code!" << std::endl;
49 std::cerr << "failed to compile Python code!" << std::endl;
59 }
50 }
60 return 0;
51 return 0;
61 }
52 }
62
53
63 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
54 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
64 {
55 {
65 PyObject *mtext =
56 PyObject *mtext =
66 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
57 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
67 PyObject *locals = PyDict_New();
58 PyObject *locals = PyDict_New();
68 PyDict_SetItemString(locals, "data", mtext);
59 PyDict_SetItemString(locals, "data", mtext);
69 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
60 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
70 if (!res) {
61 if (!res) {
71 PyErr_Print();
62 PyErr_Print();
72 }
63 }
73 Py_XDECREF(res);
64 Py_XDECREF(res);
74 Py_DECREF(locals);
65 Py_DECREF(locals);
75 Py_DECREF(mtext);
66 Py_DECREF(mtext);
76 return 0; // Non-zero return values are reserved for future use.
67 return 0; // Non-zero return values are reserved for future use.
77 }
68 }
78 }
69 }
@@ -1,57 +1,55 b''
1 #include <Python.h>
1 #include <Python.h>
2 #include <assert.h>
2 #include <assert.h>
3 #include <stdlib.h>
3 #include <stdlib.h>
4 #include <unistd.h>
4 #include <unistd.h>
5
5
6 #include "pyutil.h"
6 #include "pyutil.h"
7
7
8 #include <iostream>
8 #include <iostream>
9 #include <string>
9 #include <string>
10 #include "FuzzedDataProvider.h"
10 #include "FuzzedDataProvider.h"
11
11
12 extern "C" {
12 extern "C" {
13
13
14 static PyCodeObject *code;
14 static PYCODETYPE *code;
15
15
16 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
16 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
17 {
17 {
18 contrib::initpy(*argv[0]);
18 contrib::initpy(*argv[0]);
19 code = (PyCodeObject *)Py_CompileString(R"py(
19 code = (PYCODETYPE *)Py_CompileString(R"py(
20 from parsers import jsonescapeu8fast
21
22 try:
20 try:
23 jsonescapeu8fast(data, paranoid)
21 parsers.jsonescapeu8fast(data, paranoid)
24 except Exception as e:
22 except Exception as e:
25 pass
23 pass
26 # uncomment this print if you're editing this Python code
24 # uncomment this print if you're editing this Python code
27 # to debug failures.
25 # to debug failures.
28 # print(e)
26 # print(e)
29 )py",
27 )py",
30 "fuzzer", Py_file_input);
28 "fuzzer", Py_file_input);
31 if (!code) {
29 if (!code) {
32 std::cerr << "failed to compile Python code!" << std::endl;
30 std::cerr << "failed to compile Python code!" << std::endl;
33 }
31 }
34 return 0;
32 return 0;
35 }
33 }
36
34
37 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
35 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
38 {
36 {
39 FuzzedDataProvider provider(Data, Size);
37 FuzzedDataProvider provider(Data, Size);
40 bool paranoid = provider.ConsumeBool();
38 bool paranoid = provider.ConsumeBool();
41 std::string remainder = provider.ConsumeRemainingBytesAsString();
39 std::string remainder = provider.ConsumeRemainingBytesAsString();
42
40
43 PyObject *mtext = PyBytes_FromStringAndSize(
41 PyObject *mtext = PyBytes_FromStringAndSize(
44 (const char *)remainder.c_str(), remainder.size());
42 (const char *)remainder.c_str(), remainder.size());
45 PyObject *locals = PyDict_New();
43 PyObject *locals = PyDict_New();
46 PyDict_SetItemString(locals, "data", mtext);
44 PyDict_SetItemString(locals, "data", mtext);
47 PyDict_SetItemString(locals, "paranoid", paranoid ? Py_True : Py_False);
45 PyDict_SetItemString(locals, "paranoid", paranoid ? Py_True : Py_False);
48 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
46 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
49 if (!res) {
47 if (!res) {
50 PyErr_Print();
48 PyErr_Print();
51 }
49 }
52 Py_XDECREF(res);
50 Py_XDECREF(res);
53 Py_DECREF(locals);
51 Py_DECREF(locals);
54 Py_DECREF(mtext);
52 Py_DECREF(mtext);
55 return 0; // Non-zero return values are reserved for future use.
53 return 0; // Non-zero return values are reserved for future use.
56 }
54 }
57 }
55 }
@@ -1,68 +1,67 b''
1 #include <Python.h>
1 #include <Python.h>
2 #include <assert.h>
2 #include <assert.h>
3 #include <stdlib.h>
3 #include <stdlib.h>
4 #include <unistd.h>
4 #include <unistd.h>
5
5
6 #include "pyutil.h"
6 #include "pyutil.h"
7
7
8 #include <string>
8 #include <string>
9
9
10 extern "C" {
10 extern "C" {
11
11
12 static PyCodeObject *code;
12 static PYCODETYPE *code;
13
13
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
15 {
15 {
16 contrib::initpy(*argv[0]);
16 contrib::initpy(*argv[0]);
17 code = (PyCodeObject *)Py_CompileString(R"py(
17 code = (PYCODETYPE *)Py_CompileString(R"py(
18 from parsers import lazymanifest
19 try:
18 try:
20 lm = lazymanifest(mdata)
19 lm = parsers.lazymanifest(mdata)
21 # iterate the whole thing, which causes the code to fully parse
20 # iterate the whole thing, which causes the code to fully parse
22 # every line in the manifest
21 # every line in the manifest
23 for e, _, _ in lm.iterentries():
22 for e, _, _ in lm.iterentries():
24 # also exercise __getitem__ et al
23 # also exercise __getitem__ et al
25 lm[e]
24 lm[e]
26 e in lm
25 e in lm
27 (e + 'nope') in lm
26 (e + 'nope') in lm
28 lm[b'xyzzy'] = (b'\0' * 20, 'x')
27 lm[b'xyzzy'] = (b'\0' * 20, 'x')
29 # do an insert, text should change
28 # do an insert, text should change
30 assert lm.text() != mdata, "insert should change text and didn't: %r %r" % (lm.text(), mdata)
29 assert lm.text() != mdata, "insert should change text and didn't: %r %r" % (lm.text(), mdata)
31 cloned = lm.filtercopy(lambda x: x != 'xyzzy')
30 cloned = lm.filtercopy(lambda x: x != 'xyzzy')
32 assert cloned.text() == mdata, 'cloned text should equal mdata'
31 assert cloned.text() == mdata, 'cloned text should equal mdata'
33 cloned.diff(lm)
32 cloned.diff(lm)
34 del lm[b'xyzzy']
33 del lm[b'xyzzy']
35 cloned.diff(lm)
34 cloned.diff(lm)
36 # should be back to the same
35 # should be back to the same
37 assert lm.text() == mdata, "delete should have restored text but didn't: %r %r" % (lm.text(), mdata)
36 assert lm.text() == mdata, "delete should have restored text but didn't: %r %r" % (lm.text(), mdata)
38 except Exception as e:
37 except Exception as e:
39 pass
38 pass
40 # uncomment this print if you're editing this Python code
39 # uncomment this print if you're editing this Python code
41 # to debug failures.
40 # to debug failures.
42 # print e
41 # print e
43 )py",
42 )py",
44 "fuzzer", Py_file_input);
43 "fuzzer", Py_file_input);
45 return 0;
44 return 0;
46 }
45 }
47
46
48 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
47 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
49 {
48 {
50 // Don't allow fuzzer inputs larger than 100k, since we'll just bog
49 // Don't allow fuzzer inputs larger than 100k, since we'll just bog
51 // down and not accomplish much.
50 // down and not accomplish much.
52 if (Size > 100000) {
51 if (Size > 100000) {
53 return 0;
52 return 0;
54 }
53 }
55 PyObject *mtext =
54 PyObject *mtext =
56 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
55 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
57 PyObject *locals = PyDict_New();
56 PyObject *locals = PyDict_New();
58 PyDict_SetItemString(locals, "mdata", mtext);
57 PyDict_SetItemString(locals, "mdata", mtext);
59 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
58 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
60 if (!res) {
59 if (!res) {
61 PyErr_Print();
60 PyErr_Print();
62 }
61 }
63 Py_XDECREF(res);
62 Py_XDECREF(res);
64 Py_DECREF(locals);
63 Py_DECREF(locals);
65 Py_DECREF(mtext);
64 Py_DECREF(mtext);
66 return 0; // Non-zero return values are reserved for future use.
65 return 0; // Non-zero return values are reserved for future use.
67 }
66 }
68 }
67 }
@@ -1,54 +1,76 b''
1 #include "pyutil.h"
1 #include "pyutil.h"
2
2
3 #include <iostream>
3 #include <iostream>
4 #include <string>
4 #include <string>
5
5
6 namespace contrib
6 namespace contrib
7 {
7 {
8
8
9 #if PY_MAJOR_VERSION >= 3
10 #define HG_FUZZER_PY3 1
11 PyMODINIT_FUNC PyInit_parsers(void);
12 #else
13 PyMODINIT_FUNC initparsers(void);
14 #endif
15
9 static char cpypath[8192] = "\0";
16 static char cpypath[8192] = "\0";
10
17
11 static PyObject *mainmod;
18 static PyObject *mainmod;
12 static PyObject *globals;
19 static PyObject *globals;
13
20
14 /* TODO: use Python 3 for this fuzzing? */
15 PyMODINIT_FUNC initparsers(void);
16
17 void initpy(const char *cselfpath)
21 void initpy(const char *cselfpath)
18 {
22 {
23 #ifdef HG_FUZZER_PY3
24 const std::string subdir = "/sanpy/lib/python3.7";
25 #else
19 const std::string subdir = "/sanpy/lib/python2.7";
26 const std::string subdir = "/sanpy/lib/python2.7";
27 #endif
28
20 /* HACK ALERT: we need a full Python installation built without
29 /* HACK ALERT: we need a full Python installation built without
21 pymalloc and with ASAN, so we dump one in
30 pymalloc and with ASAN, so we dump one in
22 $OUT/sanpy/lib/python2.7. This helps us wire that up. */
31 $OUT/sanpy/lib/python2.7. This helps us wire that up. */
23 std::string selfpath(cselfpath);
32 std::string selfpath(cselfpath);
24 std::string pypath;
33 std::string pypath;
25 auto pos = selfpath.rfind("/");
34 auto pos = selfpath.rfind("/");
26 if (pos == std::string::npos) {
35 if (pos == std::string::npos) {
27 char wd[8192];
36 char wd[8192];
28 if (!getcwd(wd, 8192)) {
37 if (!getcwd(wd, 8192)) {
29 std::cerr << "Failed to call getcwd: errno " << errno
38 std::cerr << "Failed to call getcwd: errno " << errno
30 << std::endl;
39 << std::endl;
31 exit(1);
40 exit(1);
32 }
41 }
33 pypath = std::string(wd) + subdir;
42 pypath = std::string(wd) + subdir;
34 } else {
43 } else {
35 pypath = selfpath.substr(0, pos) + subdir;
44 pypath = selfpath.substr(0, pos) + subdir;
36 }
45 }
37 strncpy(cpypath, pypath.c_str(), pypath.size());
46 strncpy(cpypath, pypath.c_str(), pypath.size());
38 setenv("PYTHONPATH", cpypath, 1);
47 setenv("PYTHONPATH", cpypath, 1);
39 setenv("PYTHONNOUSERSITE", "1", 1);
48 setenv("PYTHONNOUSERSITE", "1", 1);
40 /* prevent Python from looking up users in the fuzz environment */
49 /* prevent Python from looking up users in the fuzz environment */
41 setenv("PYTHONUSERBASE", cpypath, 1);
50 setenv("PYTHONUSERBASE", cpypath, 1);
51 #ifdef HG_FUZZER_PY3
52 std::wstring wcpypath(pypath.begin(), pypath.end());
53 Py_SetPythonHome(wcpypath.c_str());
54 #else
42 Py_SetPythonHome(cpypath);
55 Py_SetPythonHome(cpypath);
56 #endif
43 Py_InitializeEx(0);
57 Py_InitializeEx(0);
44 mainmod = PyImport_AddModule("__main__");
58 mainmod = PyImport_AddModule("__main__");
45 globals = PyModule_GetDict(mainmod);
59 globals = PyModule_GetDict(mainmod);
60
61 #ifdef HG_FUZZER_PY3
62 PyObject *mod = PyInit_parsers();
63 #else
46 initparsers();
64 initparsers();
65 PyObject *mod = PyImport_ImportModule("parsers");
66 #endif
67
68 PyDict_SetItemString(globals, "parsers", mod);
47 }
69 }
48
70
49 PyObject *pyglobals()
71 PyObject *pyglobals()
50 {
72 {
51 return globals;
73 return globals;
52 }
74 }
53
75
54 } // namespace contrib
76 } // namespace contrib
@@ -1,9 +1,15 b''
1 #include <Python.h>
1 #include <Python.h>
2
2
3 #if PY_MAJOR_VERSION >= 3
4 #define PYCODETYPE PyObject
5 #else
6 #define PYCODETYPE PyCodeObject
7 #endif
8
3 namespace contrib
9 namespace contrib
4 {
10 {
5
11
6 void initpy(const char *cselfpath);
12 void initpy(const char *cselfpath);
7 PyObject *pyglobals();
13 PyObject *pyglobals();
8
14
9 } /* namespace contrib */
15 } /* namespace contrib */
@@ -1,62 +1,61 b''
1 #include <Python.h>
1 #include <Python.h>
2 #include <assert.h>
2 #include <assert.h>
3 #include <stdlib.h>
3 #include <stdlib.h>
4 #include <unistd.h>
4 #include <unistd.h>
5
5
6 #include <string>
6 #include <string>
7
7
8 #include "pyutil.h"
8 #include "pyutil.h"
9
9
10 extern "C" {
10 extern "C" {
11
11
12 static PyCodeObject *code;
12 static PYCODETYPE *code;
13
13
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
15 {
15 {
16 contrib::initpy(*argv[0]);
16 contrib::initpy(*argv[0]);
17 code = (PyCodeObject *)Py_CompileString(R"py(
17 code = (PYCODETYPE *)Py_CompileString(R"py(
18 from parsers import parse_index2
19 for inline in (True, False):
18 for inline in (True, False):
20 try:
19 try:
21 index, cache = parse_index2(data, inline)
20 index, cache = parsers.parse_index2(data, inline)
22 index.slicechunktodensity(list(range(len(index))), 0.5, 262144)
21 index.slicechunktodensity(list(range(len(index))), 0.5, 262144)
23 index.stats()
22 index.stats()
24 index.findsnapshots({}, 0)
23 index.findsnapshots({}, 0)
25 10 in index
24 10 in index
26 for rev in range(len(index)):
25 for rev in range(len(index)):
27 index.reachableroots(0, [len(index)-1], [rev])
26 index.reachableroots(0, [len(index)-1], [rev])
28 node = index[rev][7]
27 node = index[rev][7]
29 partial = index.shortest(node)
28 partial = index.shortest(node)
30 index.partialmatch(node[:partial])
29 index.partialmatch(node[:partial])
31 index.deltachain(rev, None, True)
30 index.deltachain(rev, None, True)
32 except Exception as e:
31 except Exception as e:
33 pass
32 pass
34 # uncomment this print if you're editing this Python code
33 # uncomment this print if you're editing this Python code
35 # to debug failures.
34 # to debug failures.
36 # print e
35 # print e
37 )py",
36 )py",
38 "fuzzer", Py_file_input);
37 "fuzzer", Py_file_input);
39 return 0;
38 return 0;
40 }
39 }
41
40
42 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
41 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
43 {
42 {
44 // Don't allow fuzzer inputs larger than 60k, since we'll just bog
43 // Don't allow fuzzer inputs larger than 60k, since we'll just bog
45 // down and not accomplish much.
44 // down and not accomplish much.
46 if (Size > 60000) {
45 if (Size > 60000) {
47 return 0;
46 return 0;
48 }
47 }
49 PyObject *text =
48 PyObject *text =
50 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
49 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
51 PyObject *locals = PyDict_New();
50 PyObject *locals = PyDict_New();
52 PyDict_SetItemString(locals, "data", text);
51 PyDict_SetItemString(locals, "data", text);
53 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
52 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
54 if (!res) {
53 if (!res) {
55 PyErr_Print();
54 PyErr_Print();
56 }
55 }
57 Py_XDECREF(res);
56 Py_XDECREF(res);
58 Py_DECREF(locals);
57 Py_DECREF(locals);
59 Py_DECREF(text);
58 Py_DECREF(text);
60 return 0; // Non-zero return values are reserved for future use.
59 return 0; // Non-zero return values are reserved for future use.
61 }
60 }
62 }
61 }
General Comments 0
You need to be logged in to leave comments. Login now