mercurial/cext/revlog.c
changeset 40819 cb372d09d30a
parent 40756 c85964d715fd
parent 40813 884321cd26c3
child 40859 aa76be85029b
--- a/mercurial/cext/revlog.c	Thu Nov 29 09:13:13 2018 +0000
+++ b/mercurial/cext/revlog.c	Tue Dec 04 17:13:01 2018 -0500
@@ -158,6 +158,12 @@
 	return (const char *)(self->buf.buf) + pos * v1_hdrsize;
 }
 
+/*
+ * Get parents of the given rev.
+ *
+ * The specified rev must be valid and must not be nullrev. A returned
+ * parent revision may be nullrev, but is guaranteed to be in valid range.
+ */
 static inline int index_get_parents(indexObject *self, Py_ssize_t rev, int *ps,
                                     int maxrev)
 {
@@ -180,7 +186,7 @@
 	}
 	/* If index file is corrupted, ps[] may point to invalid revisions. So
 	 * there is a risk of buffer overflow to trust them unconditionally. */
-	if (ps[0] > maxrev || ps[1] > maxrev) {
+	if (ps[0] < -1 || ps[0] > maxrev || ps[1] < -1 || ps[1] > maxrev) {
 		PyErr_SetString(PyExc_ValueError, "parent out of range");
 		return -1;
 	}
@@ -2688,6 +2694,16 @@
 int rustlazyancestors_next(rustlazyancestorsObject *self);
 int rustlazyancestors_contains(rustlazyancestorsObject *self, long rev);
 
+static int index_get_parents_checked(indexObject *self, Py_ssize_t rev, int *ps,
+                                     int maxrev)
+{
+	if (rev < 0 || rev >= index_length(self)) {
+		PyErr_SetString(PyExc_ValueError, "rev out of range");
+		return -1;
+	}
+	return index_get_parents(self, rev, ps, maxrev);
+}
+
 /* CPython instance methods */
 static int rustla_init(rustlazyancestorsObject *self, PyObject *args)
 {
@@ -2729,7 +2745,8 @@
 	                                    initrevs, stoprev, inclusive);
 	if (self->iter == NULL) {
 		/* if this is because of GraphError::ParentOutOfRange
-		 * index_get_parents() has already set the proper ValueError */
+		 * index_get_parents_checked() has already set the proper
+		 * ValueError */
 		goto bail;
 	}