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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }