diff --git a/mercurial/cext/dirs.c b/mercurial/cext/dirs.c --- a/mercurial/cext/dirs.c +++ b/mercurial/cext/dirs.c @@ -48,12 +48,30 @@ return pos; } +/* Mercurial will fail to run on directory hierarchies deeper than + * this constant, so we should try and keep this constant as big as + * possible. + */ +#define MAX_DIRS_DEPTH 2048 + static int _addpath(PyObject *dirs, PyObject *path) { const char *cpath = PyBytes_AS_STRING(path); Py_ssize_t pos = PyBytes_GET_SIZE(path); PyObject *key = NULL; int ret = -1; + size_t num_slashes = 0, i; + + for (i = 0; i < pos; ++i) { + if (cpath[i] == '/') { + ++num_slashes; + } + } + if (num_slashes > MAX_DIRS_DEPTH) { + PyErr_SetString(PyExc_ValueError, + "Directory hierarchy too deep."); + goto bail; + } /* This loop is super critical for performance. That's why we inline * access to Python structs instead of going through a supported API.