##// END OF EJS Templates
fuzz: tell manifest fuzzer about longer node hashes...
Augie Fackler -
r45519:0ff59434 default
parent child Browse files
Show More
@@ -1,67 +1,72 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 "FuzzedDataProvider.h"
6 #include "pyutil.h"
7 #include "pyutil.h"
7
8
8 #include <string>
9 #include <string>
9
10
10 extern "C" {
11 extern "C" {
11
12
12 static PYCODETYPE *code;
13 static PYCODETYPE *code;
13
14
14 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
15 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
15 {
16 {
16 contrib::initpy(*argv[0]);
17 contrib::initpy(*argv[0]);
17 code = (PYCODETYPE *)Py_CompileString(R"py(
18 code = (PYCODETYPE *)Py_CompileString(R"py(
18 try:
19 try:
19 lm = parsers.lazymanifest(mdata)
20 lm = parsers.lazymanifest(mdata)
20 # iterate the whole thing, which causes the code to fully parse
21 # iterate the whole thing, which causes the code to fully parse
21 # every line in the manifest
22 # every line in the manifest
22 for e, _, _ in lm.iterentries():
23 for e, _, _ in lm.iterentries():
23 # also exercise __getitem__ et al
24 # also exercise __getitem__ et al
24 lm[e]
25 lm[e]
25 e in lm
26 e in lm
26 (e + 'nope') in lm
27 (e + 'nope') in lm
27 lm[b'xyzzy'] = (b'\0' * 20, 'x')
28 lm[b'xyzzy'] = (b'\0' * nlen, 'x')
28 # do an insert, text should change
29 # do an insert, text should change
29 assert lm.text() != mdata, "insert should change text and didn't: %r %r" % (lm.text(), mdata)
30 assert lm.text() != mdata, "insert should change text and didn't: %r %r" % (lm.text(), mdata)
30 cloned = lm.filtercopy(lambda x: x != 'xyzzy')
31 cloned = lm.filtercopy(lambda x: x != 'xyzzy')
31 assert cloned.text() == mdata, 'cloned text should equal mdata'
32 assert cloned.text() == mdata, 'cloned text should equal mdata'
32 cloned.diff(lm)
33 cloned.diff(lm)
33 del lm[b'xyzzy']
34 del lm[b'xyzzy']
34 cloned.diff(lm)
35 cloned.diff(lm)
35 # should be back to the same
36 # should be back to the same
36 assert lm.text() == mdata, "delete should have restored text but didn't: %r %r" % (lm.text(), mdata)
37 assert lm.text() == mdata, "delete should have restored text but didn't: %r %r" % (lm.text(), mdata)
37 except Exception as e:
38 except Exception as e:
38 pass
39 pass
39 # uncomment this print if you're editing this Python code
40 # uncomment this print if you're editing this Python code
40 # to debug failures.
41 # to debug failures.
41 # print e
42 # print e
42 )py",
43 )py",
43 "fuzzer", Py_file_input);
44 "fuzzer", Py_file_input);
44 return 0;
45 return 0;
45 }
46 }
46
47
47 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
48 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
48 {
49 {
49 // Don't allow fuzzer inputs larger than 100k, since we'll just bog
50 // Don't allow fuzzer inputs larger than 100k, since we'll just bog
50 // down and not accomplish much.
51 // down and not accomplish much.
51 if (Size > 100000) {
52 if (Size > 100000) {
52 return 0;
53 return 0;
53 }
54 }
55 FuzzedDataProvider provider(Data, Size);
56 Py_ssize_t nodelength = provider.ConsumeBool() ? 20 : 32;
57 PyObject *nlen = PyLong_FromSsize_t(nodelength);
54 PyObject *mtext =
58 PyObject *mtext =
55 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
59 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
56 PyObject *locals = PyDict_New();
60 PyObject *locals = PyDict_New();
57 PyDict_SetItemString(locals, "mdata", mtext);
61 PyDict_SetItemString(locals, "mdata", mtext);
62 PyDict_SetItemString(locals, "nlen", nlen);
58 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
63 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
59 if (!res) {
64 if (!res) {
60 PyErr_Print();
65 PyErr_Print();
61 }
66 }
62 Py_XDECREF(res);
67 Py_XDECREF(res);
63 Py_DECREF(locals);
68 Py_DECREF(locals);
64 Py_DECREF(mtext);
69 Py_DECREF(mtext);
65 return 0; // Non-zero return values are reserved for future use.
70 return 0; // Non-zero return values are reserved for future use.
66 }
71 }
67 }
72 }
@@ -1,33 +1,38 b''
1 from __future__ import absolute_import, print_function
1 from __future__ import absolute_import, print_function
2
2
3 import argparse
3 import argparse
4 import zipfile
4 import zipfile
5
5
6 ap = argparse.ArgumentParser()
6 ap = argparse.ArgumentParser()
7 ap.add_argument("out", metavar="some.zip", type=str, nargs=1)
7 ap.add_argument("out", metavar="some.zip", type=str, nargs=1)
8 args = ap.parse_args()
8 args = ap.parse_args()
9
9
10 with zipfile.ZipFile(args.out[0], "w", zipfile.ZIP_STORED) as zf:
10 with zipfile.ZipFile(args.out[0], "w", zipfile.ZIP_STORED) as zf:
11 zf.writestr(
11 zf.writestr(
12 "manifest_zero",
12 "manifest_zero",
13 '''PKG-INFO\09b3ed8f2b81095a13064402e930565f083346e9a
13 '''\0PKG-INFO\09b3ed8f2b81095a13064402e930565f083346e9a
14 README\080b6e76643dcb44d4bc729e932fc464b3e36dbe3
14 README\080b6e76643dcb44d4bc729e932fc464b3e36dbe3
15 hg\0b6444347c629cc058d478023905cfb83b7f5bb9d
15 hg\0b6444347c629cc058d478023905cfb83b7f5bb9d
16 mercurial/__init__.py\0b80de5d138758541c5f05265ad144ab9fa86d1db
16 mercurial/__init__.py\0b80de5d138758541c5f05265ad144ab9fa86d1db
17 mercurial/byterange.py\017f5a9fbd99622f31a392c33ac1e903925dc80ed
17 mercurial/byterange.py\017f5a9fbd99622f31a392c33ac1e903925dc80ed
18 mercurial/fancyopts.py\0b6f52e23e356748c5039313d8b639cda16bf67ba
18 mercurial/fancyopts.py\0b6f52e23e356748c5039313d8b639cda16bf67ba
19 mercurial/hg.py\023cc12f225f1b42f32dc0d897a4f95a38ddc8f4a
19 mercurial/hg.py\023cc12f225f1b42f32dc0d897a4f95a38ddc8f4a
20 mercurial/mdiff.py\0a05f65c44bfbeec6a42336cd2ff0b30217899ca3
20 mercurial/mdiff.py\0a05f65c44bfbeec6a42336cd2ff0b30217899ca3
21 mercurial/revlog.py\0217bc3fde6d82c0210cf56aeae11d05a03f35b2b
21 mercurial/revlog.py\0217bc3fde6d82c0210cf56aeae11d05a03f35b2b
22 mercurial/transaction.py\09d180df101dc14ce3dd582fd998b36c98b3e39aa
22 mercurial/transaction.py\09d180df101dc14ce3dd582fd998b36c98b3e39aa
23 notes.txt\0703afcec5edb749cf5cec67831f554d6da13f2fb
23 notes.txt\0703afcec5edb749cf5cec67831f554d6da13f2fb
24 setup.py\0ccf3f6daf0f13101ca73631f7a1769e328b472c9
24 setup.py\0ccf3f6daf0f13101ca73631f7a1769e328b472c9
25 tkmerge\03c922edb43a9c143682f7bc7b00f98b3c756ebe7
25 tkmerge\03c922edb43a9c143682f7bc7b00f98b3c756ebe7
26 ''',
26 ''',
27 )
27 )
28 zf.writestr("badmanifest_shorthashes", "narf\0aa\nnarf2\0aaa\n")
28 zf.writestr("badmanifest_shorthashes", "\0narf\0aa\nnarf2\0aaa\n")
29 zf.writestr(
29 zf.writestr(
30 "badmanifest_nonull",
30 "badmanifest_nonull",
31 "narf\0cccccccccccccccccccccccccccccccccccccccc\n"
31 "\0narf\0cccccccccccccccccccccccccccccccccccccccc\n"
32 "narf2aaaaaaaaaaaaaaaaaaaa\n",
32 "narf2aaaaaaaaaaaaaaaaaaaa\n",
33 )
33 )
34
35 zf.writestr(
36 "manifest_long_nodes",
37 "\1a\0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n",
38 )
General Comments 0
You need to be logged in to leave comments. Login now