Coverage Report

Created: 2025-07-09 06:54

/src/mercurial/contrib/fuzz/fncache.cc
Line
Count
Source (jump to first uncovered line)
1
#include <Python.h>
2
#include <assert.h>
3
#include <stdlib.h>
4
#include <unistd.h>
5
6
#include "pyutil.h"
7
8
#include <iostream>
9
#include <string>
10
11
extern "C" {
12
13
static PYCODETYPE *code;
14
15
extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
16
4
{
17
4
  contrib::initpy(*argv[0]);
18
4
  code = (PYCODETYPE *)Py_CompileString(R"py(
19
4
try:
20
4
    for fn in (
21
4
        parsers.isasciistr,
22
4
        parsers.asciilower,
23
4
        parsers.asciiupper,
24
4
        parsers.encodedir,
25
4
        parsers.pathencode,
26
4
        parsers.lowerencode,
27
4
    ):
28
4
        try:
29
4
            fn(data)
30
4
        except UnicodeDecodeError:
31
4
            pass  # some functions emit this exception
32
4
        except AttributeError:
33
4
            # pathencode needs hashlib, which fails to import because the time
34
4
            # module fails to import. We should try and fix that some day, but
35
4
            # for now we at least get coverage on non-hashencoded codepaths.
36
4
            if fn != pathencode:
37
4
                raise
38
4
        # uncomment this for debugging exceptions
39
4
        # except Exception as e:
40
4
        #     raise Exception('%r: %r' % (fn, e))
41
4
except Exception as e:
42
4
    pass
43
4
    # uncomment this print if you're editing this Python code
44
4
    # to debug failures.
45
4
    # print(e)
46
4
)py",
47
4
                                        "fuzzer", Py_file_input);
48
4
  if (!code) {
49
0
    std::cerr << "failed to compile Python code!" << std::endl;
50
0
  }
51
4
  return 0;
52
4
}
53
54
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
55
1.77k
{
56
1.77k
  PyObject *mtext =
57
1.77k
      PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
58
1.77k
  PyObject *locals = PyDict_New();
59
1.77k
  PyDict_SetItemString(locals, "data", mtext);
60
1.77k
  PyObject *res = PyEval_EvalCode(code, contrib::pyglobals(), locals);
61
1.77k
  if (!res) {
62
0
    PyErr_Print();
63
0
  }
64
1.77k
  Py_XDECREF(res);
65
1.77k
  Py_DECREF(locals);
66
1.77k
  Py_DECREF(mtext);
67
1.77k
  return 0; // Non-zero return values are reserved for future use.
68
1.77k
}
69
}