Mercurial > hg
changeset 38335:ae7f27867c2a stable
manifest: fix possible SEGV caused by uninitialized lazymanifest fields
Before, uninitialized self->pydata would be passed to lazymanifest_dealloc()
on OOM, and Py_DECREF(self->pydata) would crash if we were unlucky.
It's still wrong to do malloc() thingy in tp_init because __init__() may be
called more than once [1], but I don't want to go a step further in stable
branch.
[1]: https://docs.python.org/2/c-api/typeobj.html#c.PyTypeObject.tp_new
"The tp_new function should ... do only as much further initialization as
is absolutely necessary. Initialization that can safely be ignored or
repeated should be placed in the tp_init handler."
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Fri, 15 Jun 2018 22:16:58 +0900 |
parents | 2baf79933b45 |
children | 1322ae04d3d7 |
files | mercurial/cext/manifest.c |
diffstat | 1 files changed, 12 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/cext/manifest.c Fri Jun 15 10:14:32 2018 -0400 +++ b/mercurial/cext/manifest.c Fri Jun 15 22:16:58 2018 +0900 @@ -135,12 +135,22 @@ return 0; } +static void lazymanifest_init_early(lazymanifest *self) +{ + self->pydata = NULL; + self->lines = NULL; + self->numlines = 0; + self->maxlines = 0; +} + static int lazymanifest_init(lazymanifest *self, PyObject *args) { char *data; Py_ssize_t len; int err, ret; PyObject *pydata; + + lazymanifest_init_early(self); if (!PyArg_ParseTuple(args, "S", &pydata)) { return -1; } @@ -668,6 +678,7 @@ if (!copy) { goto nomem; } + lazymanifest_init_early(copy); copy->numlines = self->numlines; copy->livelines = self->livelines; copy->dirty = false; @@ -705,6 +716,7 @@ if (!copy) { goto nomem; } + lazymanifest_init_early(copy); copy->dirty = true; copy->lines = malloc(self->maxlines * sizeof(line)); if (!copy->lines) {