test-parseindex.t
225 lines
| 7.1 KiB
| text/troff
|
Tads3Lexer
/ tests / test-parseindex.t
Matt Mackall
|
r12476 | revlog.parseindex must be able to parse the index file even if | ||
an index entry is split between two 64k blocks. The ideal test | ||||
would be to create an index file with inline data where | ||||
64k < size < 64k + 64 (64k is the size of the read buffer, 64 is | ||||
the size of an index entry) and with an index entry starting right | ||||
before the 64k block boundary, and try to read it. | ||||
We approximate that by reducing the read buffer to 1 byte. | ||||
$ hg init a | ||||
$ cd a | ||||
$ echo abc > foo | ||||
$ hg add foo | ||||
$ hg commit -m 'add foo' | ||||
$ echo >> foo | ||||
$ hg commit -m 'change foo' | ||||
$ hg log -r 0: | ||||
changeset: 0:7c31755bf9b5 | ||||
user: test | ||||
date: Thu Jan 01 00:00:00 1970 +0000 | ||||
summary: add foo | ||||
changeset: 1:26333235a41c | ||||
tag: tip | ||||
user: test | ||||
date: Thu Jan 01 00:00:00 1970 +0000 | ||||
summary: change foo | ||||
$ cat >> test.py << EOF | ||||
Augie Fackler
|
r41389 | > from mercurial import changelog, node, pycompat, vfs | ||
Matt Mackall
|
r12476 | > | ||
> class singlebyteread(object): | ||||
> def __init__(self, real): | ||||
> self.real = real | ||||
> | ||||
> def read(self, size=-1): | ||||
> if size == 65536: | ||||
> size = 1 | ||||
> return self.real.read(size) | ||||
> | ||||
> def __getattr__(self, key): | ||||
> return getattr(self.real, key) | ||||
> | ||||
Boris Feld
|
r35984 | > def __enter__(self): | ||
> self.real.__enter__() | ||||
> return self | ||||
> | ||||
> def __exit__(self, *args, **kwargs): | ||||
> return self.real.__exit__(*args, **kwargs) | ||||
> | ||||
Matt Mackall
|
r12476 | > def opener(*args): | ||
Pierre-Yves David
|
r31250 | > o = vfs.vfs(*args) | ||
Boris Feld
|
r35983 | > def wrapper(*a, **kwargs): | ||
> f = o(*a, **kwargs) | ||||
Matt Mackall
|
r12476 | > return singlebyteread(f) | ||
r43295 | > wrapper.options = o.options | |||
Matt Mackall
|
r12476 | > return wrapper | ||
> | ||||
Augie Fackler
|
r41389 | > cl = changelog.changelog(opener(b'.hg/store')) | ||
Pulkit Goyal
|
r38090 | > print(len(cl), 'revisions:') | ||
Matt Mackall
|
r12476 | > for r in cl: | ||
Augie Fackler
|
r41389 | > print(pycompat.sysstr(node.short(cl.node(r)))) | ||
Matt Mackall
|
r12476 | > EOF | ||
Matt Harbison
|
r39743 | $ "$PYTHON" test.py | ||
Matt Mackall
|
r12476 | 2 revisions: | ||
7c31755bf9b5 | ||||
26333235a41c | ||||
Mads Kiilerich
|
r16913 | |||
$ cd .. | ||||
Yuya Nishihara
|
r25810 | |||
Yuya Nishihara
|
r26017 | #if no-pure | ||
Test SEGV caused by bad revision passed to reachableroots() (issue4775): | ||||
$ cd a | ||||
Yuya Nishihara
|
r25810 | |||
Matt Harbison
|
r39743 | $ "$PYTHON" <<EOF | ||
Pierre-Yves David
|
r31250 | > from mercurial import changelog, vfs | ||
Augie Fackler
|
r41389 | > cl = changelog.changelog(vfs.vfs(b'.hg/store')) | ||
Pulkit Goyal
|
r38090 | > print('good heads:') | ||
Yuya Nishihara
|
r26017 | > for head in [0, len(cl) - 1, -1]: | ||
Pulkit Goyal
|
r38090 | > print('%s: %r' % (head, cl.reachableroots(0, [head], [0]))) | ||
> print('bad heads:') | ||||
Yuya Nishihara
|
r26018 | > for head in [len(cl), 10000, -2, -10000, None]: | ||
Pulkit Goyal
|
r38090 | > print('%s:' % head, end=' ') | ||
Yuya Nishihara
|
r26017 | > try: | ||
Yuya Nishihara
|
r26053 | > cl.reachableroots(0, [head], [0]) | ||
Pulkit Goyal
|
r38090 | > print('uncaught buffer overflow?') | ||
Yuya Nishihara
|
r26018 | > except (IndexError, TypeError) as inst: | ||
Pulkit Goyal
|
r38090 | > print(inst) | ||
> print('good roots:') | ||||
Yuya Nishihara
|
r26053 | > for root in [0, len(cl) - 1, -1]: | ||
Pulkit Goyal
|
r38090 | > print('%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))) | ||
> print('out-of-range roots are ignored:') | ||||
Yuya Nishihara
|
r26053 | > for root in [len(cl), 10000, -2, -10000]: | ||
Pulkit Goyal
|
r38090 | > print('%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))) | ||
> print('bad roots:') | ||||
Yuya Nishihara
|
r26053 | > for root in [None]: | ||
Pulkit Goyal
|
r38090 | > print('%s:' % root, end=' ') | ||
Yuya Nishihara
|
r26053 | > try: | ||
> cl.reachableroots(root, [len(cl) - 1], [root]) | ||||
Pulkit Goyal
|
r38090 | > print('uncaught error?') | ||
Yuya Nishihara
|
r26053 | > except TypeError as inst: | ||
Pulkit Goyal
|
r38090 | > print(inst) | ||
Yuya Nishihara
|
r26017 | > EOF | ||
Yuya Nishihara
|
r26053 | good heads: | ||
Yuya Nishihara
|
r26094 | 0: [0] | ||
1: [0] | ||||
-1: [] | ||||
Yuya Nishihara
|
r26053 | bad heads: | ||
Yuya Nishihara
|
r26017 | 2: head out of range | ||
10000: head out of range | ||||
-2: head out of range | ||||
-10000: head out of range | ||||
Julien Cristau
|
r49928 | None: (an integer is required( .got type NoneType.)?|'NoneType' object cannot be interpreted as an integer) (re) | ||
Yuya Nishihara
|
r26053 | good roots: | ||
Yuya Nishihara
|
r26094 | 0: [0] | ||
1: [1] | ||||
-1: [-1] | ||||
Yuya Nishihara
|
r26053 | out-of-range roots are ignored: | ||
Yuya Nishihara
|
r26094 | 2: [] | ||
10000: [] | ||||
-2: [] | ||||
-10000: [] | ||||
Yuya Nishihara
|
r26053 | bad roots: | ||
Julien Cristau
|
r49928 | None: (an integer is required( .got type NoneType.)?|'NoneType' object cannot be interpreted as an integer) (re) | ||
Yuya Nishihara
|
r26017 | |||
$ cd .. | ||||
Test corrupted p1/p2 fields that could cause SEGV at parsers.c: | ||||
Yuya Nishihara
|
r25859 | |||
Yuya Nishihara
|
r25810 | $ mkdir invalidparent | ||
$ cd invalidparent | ||||
Boris Feld
|
r40923 | $ hg clone --pull -q --config phases.publish=False ../a limit --config format.sparse-revlog=no | ||
$ hg clone --pull -q --config phases.publish=False ../a neglimit --config format.sparse-revlog=no | ||||
$ hg clone --pull -q --config phases.publish=False ../a segv --config format.sparse-revlog=no | ||||
Yuya Nishihara
|
r40848 | $ rm -R limit/.hg/cache neglimit/.hg/cache segv/.hg/cache | ||
Yuya Nishihara
|
r25810 | |||
Matt Harbison
|
r39743 | $ "$PYTHON" <<EOF | ||
Yuya Nishihara
|
r25810 | > data = open("limit/.hg/store/00changelog.i", "rb").read() | ||
Yuya Nishihara
|
r40848 | > poisons = [ | ||
> (b'limit', b'\0\0\0\x02'), | ||||
> (b'neglimit', b'\xff\xff\xff\xfe'), | ||||
> (b'segv', b'\0\x01\0\0'), | ||||
> ] | ||||
> for n, p in poisons: | ||||
Yuya Nishihara
|
r25810 | > # corrupt p1 at rev0 and p2 at rev1 | ||
r52074 | > rev_0 = data[:64] | |||
> rev_1 = data[64:] | ||||
r52071 | > altered_rev_0 = rev_0[:24] + p + rev_0[24 + 4:] | |||
> altered_rev_1 = rev_1[:28] + p + rev_1[28 + 4:] | ||||
> new_data = altered_rev_0 + altered_rev_1 | ||||
> with open(n + b"/.hg/store/00changelog.i", "wb") as f: | ||||
> f.write(new_data) | ||||
Yuya Nishihara
|
r25810 | > EOF | ||
Gregory Szorc
|
r39318 | $ hg -R limit debugrevlogindex -f1 -c | ||
Gregory Szorc
|
r37301 | rev flag size link p1 p2 nodeid | ||
0 0000 62 0 2 -1 7c31755bf9b5 | ||||
1 0000 65 1 0 2 26333235a41c | ||||
Gregory Szorc
|
r37299 | |||
$ hg -R limit debugdeltachain -c | ||||
r51969 | rev p1 p2 chain# chainlen prev delta | |||
0 2 -1 1 1 -1 base | ||||
1 0 2 2 1 -1 base | ||||
Gregory Szorc
|
r37299 | |||
Yuya Nishihara
|
r40848 | $ hg -R neglimit debugrevlogindex -f1 -c | ||
rev flag size link p1 p2 nodeid | ||||
0 0000 62 0 -2 -1 7c31755bf9b5 | ||||
1 0000 65 1 0 -2 26333235a41c | ||||
Gregory Szorc
|
r39318 | $ hg -R segv debugrevlogindex -f1 -c | ||
Gregory Szorc
|
r37301 | rev flag size link p1 p2 nodeid | ||
0 0000 62 0 65536 -1 7c31755bf9b5 | ||||
1 0000 65 1 0 65536 26333235a41c | ||||
Yuya Nishihara
|
r25810 | |||
Gregory Szorc
|
r37299 | $ hg -R segv debugdeltachain -c | ||
r51969 | rev p1 p2 chain# chainlen prev delta | |||
0 65536 -1 1 1 -1 base | ||||
1 0 65536 2 1 -1 base | ||||
Gregory Szorc
|
r37299 | |||
Yuya Nishihara
|
r25810 | $ cat <<EOF > test.py | ||
> import sys | ||||
Augie Fackler
|
r41389 | > from mercurial import changelog, pycompat, vfs | ||
> cl = changelog.changelog(vfs.vfs(pycompat.fsencode(sys.argv[1]))) | ||||
Yuya Nishihara
|
r25810 | > n0, n1 = cl.node(0), cl.node(1) | ||
> ops = [ | ||||
Yuya Nishihara
|
r26016 | > ('reachableroots', | ||
Yuya Nishihara
|
r26053 | > lambda: cl.index.reachableroots2(0, [1], [0], False)), | ||
r52299 | > ('compute_phases_map_sets', lambda: cl.computephases({1: {0}})), | |||
Yuya Nishihara
|
r25810 | > ('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: | ||||
Pulkit Goyal
|
r38090 | > print(l + ':', end=' ') | ||
Yuya Nishihara
|
r25810 | > try: | ||
> f() | ||||
Pulkit Goyal
|
r38090 | > print('uncaught buffer overflow?') | ||
Pulkit Goyal
|
r38100 | > except ValueError as inst: | ||
Pulkit Goyal
|
r38090 | > print(inst) | ||
Yuya Nishihara
|
r25810 | > EOF | ||
Matt Harbison
|
r39743 | $ "$PYTHON" test.py limit/.hg/store | ||
Yuya Nishihara
|
r26016 | reachableroots: parent out of range | ||
Yuya Nishihara
|
r25810 | 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 | ||||
Yuya Nishihara
|
r40848 | $ "$PYTHON" test.py neglimit/.hg/store | ||
reachableroots: parent out of range | ||||
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 | ||||
Matt Harbison
|
r39743 | $ "$PYTHON" test.py segv/.hg/store | ||
Yuya Nishihara
|
r26016 | reachableroots: parent out of range | ||
Yuya Nishihara
|
r25810 | 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 .. | ||||
Yuya Nishihara
|
r25859 | |||
#endif | ||||