D4154: index: remove side-effect from failed nt_new()

martinvonz (Martin von Zweigbergk) phabricator at mercurial-scm.org
Tue Aug 7 06:27:24 UTC 2018


martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  As pointed out by Yuya in the review of https://phab.mercurial-scm.org/D4108, if realloc() fails, we
  would end up with an invalid nodetree instance (with nt->nodes set to
  NULL), which means that if it was later accessed again it would likely
  segfault. It's probably unlikely that much else happens in the process
  if it ran out memory, but we should of course do our best to handle
  it. This patch makes it so we don't update the nodetree in this case.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D4154

AFFECTED FILES
  mercurial/cext/revlog.c

CHANGE DETAILS

diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c
--- a/mercurial/cext/revlog.c
+++ b/mercurial/cext/revlog.c
@@ -1018,18 +1018,21 @@
 static int nt_new(nodetree *self)
 {
 	if (self->length == self->capacity) {
+		unsigned newcapacity;
+		nodetreenode *newnodes;
 		if (self->capacity >= INT_MAX / (sizeof(nodetreenode) * 2)) {
 			PyErr_SetString(PyExc_MemoryError,
 					"overflow in nt_new");
 			return -1;
 		}
-		self->capacity *= 2;
-		self->nodes = realloc(self->nodes,
-		                      self->capacity * sizeof(nodetreenode));
-		if (self->nodes == NULL) {
+		newcapacity = self->capacity * 2;
+		newnodes = realloc(self->nodes, newcapacity * sizeof(nodetreenode));
+		if (newnodes == NULL) {
 			PyErr_SetString(PyExc_MemoryError, "out of memory");
 			return -1;
 		}
+		self->capacity = newcapacity;
+		self->nodes = newnodes;
 		memset(&self->nodes[self->length], 0,
 		       sizeof(nodetreenode) * (self->capacity - self->length));
 	}



To: martinvonz, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list