tests/test-parseindex.t
changeset 25810 82d6a35cf432
parent 16913 f2719b387380
child 25859 1619563959b3
--- a/tests/test-parseindex.t	Thu Jul 16 11:12:15 2015 -0700
+++ b/tests/test-parseindex.t	Thu Jul 16 23:36:08 2015 +0900
@@ -59,3 +59,62 @@
   26333235a41c
 
   $ cd ..
+
+Test corrupted p1/p2 fields that could cause SEGV at parsers.c:
+
+  $ mkdir invalidparent
+  $ cd invalidparent
+
+  $ hg clone --pull -q --config phases.publish=False ../a limit
+  $ hg clone --pull -q --config phases.publish=False ../a segv
+  $ rm -R limit/.hg/cache segv/.hg/cache
+
+  $ python <<EOF
+  > data = open("limit/.hg/store/00changelog.i", "rb").read()
+  > for n, p in [('limit', '\0\0\0\x02'), ('segv', '\0\x01\0\0')]:
+  >     # corrupt p1 at rev0 and p2 at rev1
+  >     d = data[:24] + p + data[28:127 + 28] + p + data[127 + 32:]
+  >     open(n + "/.hg/store/00changelog.i", "wb").write(d)
+  > EOF
+
+  $ hg debugindex -f1 limit/.hg/store/00changelog.i
+     rev flag   offset   length     size   base   link     p1     p2       nodeid
+       0 0000        0       63       62      0      0      2     -1 7c31755bf9b5
+       1 0000       63       66       65      1      1      0      2 26333235a41c
+  $ hg debugindex -f1 segv/.hg/store/00changelog.i
+     rev flag   offset   length     size   base   link     p1     p2       nodeid
+       0 0000        0       63       62      0      0  65536     -1 7c31755bf9b5
+       1 0000       63       66       65      1      1      0  65536 26333235a41c
+
+  $ cat <<EOF > test.py
+  > import sys
+  > from mercurial import changelog, scmutil
+  > cl = changelog.changelog(scmutil.vfs(sys.argv[1]))
+  > n0, n1 = cl.node(0), cl.node(1)
+  > ops = [
+  >     ('compute_phases_map_sets', lambda: cl.computephases([[0], []])),
+  >     ('index_headrevs', lambda: cl.headrevs()),
+  >     ('find_gca_candidates', lambda: cl.commonancestorsheads(n0, n1)),
+  >     ('find_deepest', lambda: cl.ancestor(n0, n1)),
+  >     ]
+  > for l, f in ops:
+  >     print l + ':',
+  >     try:
+  >         f()
+  >         print 'uncaught buffer overflow?'
+  >     except ValueError, inst:
+  >         print inst
+  > EOF
+
+  $ python test.py limit/.hg/store
+  compute_phases_map_sets: parent out of range
+  index_headrevs: parent out of range
+  find_gca_candidates: parent out of range
+  find_deepest: parent out of range
+  $ python test.py segv/.hg/store
+  compute_phases_map_sets: parent out of range
+  index_headrevs: parent out of range
+  find_gca_candidates: parent out of range
+  find_deepest: parent out of range
+
+  $ cd ..