Mercurial > hg
annotate contrib/fuzz/manifest.cc @ 50329:3dbc7b1ecaba stable
typing: correct the signature of error.CommandError
There's a place in `mercurial.dispatch._parse()` that passes None if a parse
error happens before the command can be parsed out, and casting the error to
bytes works fine because the command and message fields are apparently ignored.
Likewise, TortoiseHg similarly passes None for the same reason.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Fri, 24 Mar 2023 02:22:12 -0400 |
parents | 0ff59434af72 |
children |
rev | line source |
---|---|
40053
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1 #include <Python.h> |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
2 #include <assert.h> |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
3 #include <stdlib.h> |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
4 #include <unistd.h> |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
5 |
44986
0ff59434af72
fuzz: tell manifest fuzzer about longer node hashes
Augie Fackler <augie@google.com>
parents:
43859
diff
changeset
|
6 #include "FuzzedDataProvider.h" |
41013
ef103c96ed33
fuzz: extract Python initialization to utility package
Augie Fackler <augie@google.com>
parents:
40373
diff
changeset
|
7 #include "pyutil.h" |
ef103c96ed33
fuzz: extract Python initialization to utility package
Augie Fackler <augie@google.com>
parents:
40373
diff
changeset
|
8 |
40053
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
9 #include <string> |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
10 |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
11 extern "C" { |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
12 |
43859
8766728dbce6
fuzz: add support for fuzzing under either Python 2 or 3
Augie Fackler <augie@google.com>
parents:
41312
diff
changeset
|
13 static PYCODETYPE *code; |
40373
c3ab0a89331d
fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents:
40280
diff
changeset
|
14 |
40053
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
15 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
16 { |
41013
ef103c96ed33
fuzz: extract Python initialization to utility package
Augie Fackler <augie@google.com>
parents:
40373
diff
changeset
|
17 contrib::initpy(*argv[0]); |
43859
8766728dbce6
fuzz: add support for fuzzing under either Python 2 or 3
Augie Fackler <augie@google.com>
parents:
41312
diff
changeset
|
18 code = (PYCODETYPE *)Py_CompileString(R"py( |
40053
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
19 try: |
43859
8766728dbce6
fuzz: add support for fuzzing under either Python 2 or 3
Augie Fackler <augie@google.com>
parents:
41312
diff
changeset
|
20 lm = parsers.lazymanifest(mdata) |
40053
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
21 # iterate the whole thing, which causes the code to fully parse |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
22 # every line in the manifest |
41312
d60bd5c71cbb
fuzz: exercise more of the lazymanifest code
Augie Fackler <raf@durin42.com>
parents:
41311
diff
changeset
|
23 for e, _, _ in lm.iterentries(): |
d60bd5c71cbb
fuzz: exercise more of the lazymanifest code
Augie Fackler <raf@durin42.com>
parents:
41311
diff
changeset
|
24 # also exercise __getitem__ et al |
d60bd5c71cbb
fuzz: exercise more of the lazymanifest code
Augie Fackler <raf@durin42.com>
parents:
41311
diff
changeset
|
25 lm[e] |
d60bd5c71cbb
fuzz: exercise more of the lazymanifest code
Augie Fackler <raf@durin42.com>
parents:
41311
diff
changeset
|
26 e in lm |
d60bd5c71cbb
fuzz: exercise more of the lazymanifest code
Augie Fackler <raf@durin42.com>
parents:
41311
diff
changeset
|
27 (e + 'nope') in lm |
44986
0ff59434af72
fuzz: tell manifest fuzzer about longer node hashes
Augie Fackler <augie@google.com>
parents:
43859
diff
changeset
|
28 lm[b'xyzzy'] = (b'\0' * nlen, 'x') |
40053
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
29 # do an insert, text should change |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
30 assert lm.text() != mdata, "insert should change text and didn't: %r %r" % (lm.text(), mdata) |
41312
d60bd5c71cbb
fuzz: exercise more of the lazymanifest code
Augie Fackler <raf@durin42.com>
parents:
41311
diff
changeset
|
31 cloned = lm.filtercopy(lambda x: x != 'xyzzy') |
d60bd5c71cbb
fuzz: exercise more of the lazymanifest code
Augie Fackler <raf@durin42.com>
parents:
41311
diff
changeset
|
32 assert cloned.text() == mdata, 'cloned text should equal mdata' |
d60bd5c71cbb
fuzz: exercise more of the lazymanifest code
Augie Fackler <raf@durin42.com>
parents:
41311
diff
changeset
|
33 cloned.diff(lm) |
40053
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
34 del lm[b'xyzzy'] |
41312
d60bd5c71cbb
fuzz: exercise more of the lazymanifest code
Augie Fackler <raf@durin42.com>
parents:
41311
diff
changeset
|
35 cloned.diff(lm) |
40053
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
36 # should be back to the same |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
37 assert lm.text() == mdata, "delete should have restored text but didn't: %r %r" % (lm.text(), mdata) |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
38 except Exception as e: |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
39 pass |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
40 # uncomment this print if you're editing this Python code |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
41 # to debug failures. |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
42 # print e |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
43 )py", |
43859
8766728dbce6
fuzz: add support for fuzzing under either Python 2 or 3
Augie Fackler <augie@google.com>
parents:
41312
diff
changeset
|
44 "fuzzer", Py_file_input); |
40373
c3ab0a89331d
fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents:
40280
diff
changeset
|
45 return 0; |
c3ab0a89331d
fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents:
40280
diff
changeset
|
46 } |
c3ab0a89331d
fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents:
40280
diff
changeset
|
47 |
c3ab0a89331d
fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents:
40280
diff
changeset
|
48 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) |
c3ab0a89331d
fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents:
40280
diff
changeset
|
49 { |
41311
44cd432aed9f
fuzz: restrict manifest input size
Augie Fackler <raf@durin42.com>
parents:
41013
diff
changeset
|
50 // Don't allow fuzzer inputs larger than 100k, since we'll just bog |
44cd432aed9f
fuzz: restrict manifest input size
Augie Fackler <raf@durin42.com>
parents:
41013
diff
changeset
|
51 // down and not accomplish much. |
44cd432aed9f
fuzz: restrict manifest input size
Augie Fackler <raf@durin42.com>
parents:
41013
diff
changeset
|
52 if (Size > 100000) { |
44cd432aed9f
fuzz: restrict manifest input size
Augie Fackler <raf@durin42.com>
parents:
41013
diff
changeset
|
53 return 0; |
44cd432aed9f
fuzz: restrict manifest input size
Augie Fackler <raf@durin42.com>
parents:
41013
diff
changeset
|
54 } |
44986
0ff59434af72
fuzz: tell manifest fuzzer about longer node hashes
Augie Fackler <augie@google.com>
parents:
43859
diff
changeset
|
55 FuzzedDataProvider provider(Data, Size); |
0ff59434af72
fuzz: tell manifest fuzzer about longer node hashes
Augie Fackler <augie@google.com>
parents:
43859
diff
changeset
|
56 Py_ssize_t nodelength = provider.ConsumeBool() ? 20 : 32; |
0ff59434af72
fuzz: tell manifest fuzzer about longer node hashes
Augie Fackler <augie@google.com>
parents:
43859
diff
changeset
|
57 PyObject *nlen = PyLong_FromSsize_t(nodelength); |
40373
c3ab0a89331d
fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents:
40280
diff
changeset
|
58 PyObject *mtext = |
c3ab0a89331d
fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents:
40280
diff
changeset
|
59 PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size); |
c3ab0a89331d
fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents:
40280
diff
changeset
|
60 PyObject *locals = PyDict_New(); |
c3ab0a89331d
fuzz: move many initialization steps into LLVMFuzzerInitialize
Augie Fackler <augie@google.com>
parents:
40280
diff
changeset
|
61 PyDict_SetItemString(locals, "mdata", mtext); |
44986
0ff59434af72
fuzz: tell manifest fuzzer about longer node hashes
Augie Fackler <augie@google.com>
parents:
43859
diff
changeset
|
62 PyDict_SetItemString(locals, "nlen", nlen); |
41013
ef103c96ed33
fuzz: extract Python initialization to utility package
Augie Fackler <augie@google.com>
parents:
40373
diff
changeset
|
63 PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals); |
40100
ca4a32d0a4d6
fuzz: report error if Python code raised exception
Yuya Nishihara <yuya@tcha.org>
parents:
40089
diff
changeset
|
64 if (!res) { |
ca4a32d0a4d6
fuzz: report error if Python code raised exception
Yuya Nishihara <yuya@tcha.org>
parents:
40089
diff
changeset
|
65 PyErr_Print(); |
ca4a32d0a4d6
fuzz: report error if Python code raised exception
Yuya Nishihara <yuya@tcha.org>
parents:
40089
diff
changeset
|
66 } |
ca4a32d0a4d6
fuzz: report error if Python code raised exception
Yuya Nishihara <yuya@tcha.org>
parents:
40089
diff
changeset
|
67 Py_XDECREF(res); |
40053
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
68 Py_DECREF(locals); |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
69 Py_DECREF(mtext); |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
70 return 0; // Non-zero return values are reserved for future use. |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
71 } |
8c692a6b5ad1
fuzz: new fuzzer for cext/manifest.c
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
72 } |