contrib/fuzz/manifest.cc
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 07 Mar 2024 04:15:23 +0100
changeset 51536 718f28ea3af4
parent 44986 0ff59434af72
permissions -rw-r--r--
branchcache: add a "pure topological head" fast path In a narrow but actually quick common case, all topological heads are all on the same branch and all open. In this case, computing the branch map is very simple. We can quickly detect situation where this situation will not change. So we update the V3 format to be able to express this situation and upgrade the update code to detect we remains in that mode. The branch cache is populated with the actual value when the branch map is accessed, but the update_disk method can do the update without needing to populate it.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
}