##// END OF EJS Templates
parseindex: implement context manager method on the wrapper...
Boris Feld -
r35984:8140ce44 default
parent child Browse files
Show More
@@ -1,185 +1,192 b''
1 1 revlog.parseindex must be able to parse the index file even if
2 2 an index entry is split between two 64k blocks. The ideal test
3 3 would be to create an index file with inline data where
4 4 64k < size < 64k + 64 (64k is the size of the read buffer, 64 is
5 5 the size of an index entry) and with an index entry starting right
6 6 before the 64k block boundary, and try to read it.
7 7 We approximate that by reducing the read buffer to 1 byte.
8 8
9 9 $ hg init a
10 10 $ cd a
11 11 $ echo abc > foo
12 12 $ hg add foo
13 13 $ hg commit -m 'add foo'
14 14 $ echo >> foo
15 15 $ hg commit -m 'change foo'
16 16 $ hg log -r 0:
17 17 changeset: 0:7c31755bf9b5
18 18 user: test
19 19 date: Thu Jan 01 00:00:00 1970 +0000
20 20 summary: add foo
21 21
22 22 changeset: 1:26333235a41c
23 23 tag: tip
24 24 user: test
25 25 date: Thu Jan 01 00:00:00 1970 +0000
26 26 summary: change foo
27 27
28 28 $ cat >> test.py << EOF
29 29 > from mercurial import changelog, vfs
30 30 > from mercurial.node import *
31 31 >
32 32 > class singlebyteread(object):
33 33 > def __init__(self, real):
34 34 > self.real = real
35 35 >
36 36 > def read(self, size=-1):
37 37 > if size == 65536:
38 38 > size = 1
39 39 > return self.real.read(size)
40 40 >
41 41 > def __getattr__(self, key):
42 42 > return getattr(self.real, key)
43 43 >
44 > def __enter__(self):
45 > self.real.__enter__()
46 > return self
47 >
48 > def __exit__(self, *args, **kwargs):
49 > return self.real.__exit__(*args, **kwargs)
50 >
44 51 > def opener(*args):
45 52 > o = vfs.vfs(*args)
46 53 > def wrapper(*a, **kwargs):
47 54 > f = o(*a, **kwargs)
48 55 > return singlebyteread(f)
49 56 > return wrapper
50 57 >
51 58 > cl = changelog.changelog(opener('.hg/store'))
52 59 > print len(cl), 'revisions:'
53 60 > for r in cl:
54 61 > print short(cl.node(r))
55 62 > EOF
56 63 $ $PYTHON test.py
57 64 2 revisions:
58 65 7c31755bf9b5
59 66 26333235a41c
60 67
61 68 $ cd ..
62 69
63 70 #if no-pure
64 71
65 72 Test SEGV caused by bad revision passed to reachableroots() (issue4775):
66 73
67 74 $ cd a
68 75
69 76 $ $PYTHON <<EOF
70 77 > from mercurial import changelog, vfs
71 78 > cl = changelog.changelog(vfs.vfs('.hg/store'))
72 79 > print 'good heads:'
73 80 > for head in [0, len(cl) - 1, -1]:
74 81 > print'%s: %r' % (head, cl.reachableroots(0, [head], [0]))
75 82 > print 'bad heads:'
76 83 > for head in [len(cl), 10000, -2, -10000, None]:
77 84 > print '%s:' % head,
78 85 > try:
79 86 > cl.reachableroots(0, [head], [0])
80 87 > print 'uncaught buffer overflow?'
81 88 > except (IndexError, TypeError) as inst:
82 89 > print inst
83 90 > print 'good roots:'
84 91 > for root in [0, len(cl) - 1, -1]:
85 92 > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))
86 93 > print 'out-of-range roots are ignored:'
87 94 > for root in [len(cl), 10000, -2, -10000]:
88 95 > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))
89 96 > print 'bad roots:'
90 97 > for root in [None]:
91 98 > print '%s:' % root,
92 99 > try:
93 100 > cl.reachableroots(root, [len(cl) - 1], [root])
94 101 > print 'uncaught error?'
95 102 > except TypeError as inst:
96 103 > print inst
97 104 > EOF
98 105 good heads:
99 106 0: [0]
100 107 1: [0]
101 108 -1: []
102 109 bad heads:
103 110 2: head out of range
104 111 10000: head out of range
105 112 -2: head out of range
106 113 -10000: head out of range
107 114 None: an integer is required
108 115 good roots:
109 116 0: [0]
110 117 1: [1]
111 118 -1: [-1]
112 119 out-of-range roots are ignored:
113 120 2: []
114 121 10000: []
115 122 -2: []
116 123 -10000: []
117 124 bad roots:
118 125 None: an integer is required
119 126
120 127 $ cd ..
121 128
122 129 Test corrupted p1/p2 fields that could cause SEGV at parsers.c:
123 130
124 131 $ mkdir invalidparent
125 132 $ cd invalidparent
126 133
127 134 $ hg clone --pull -q --config phases.publish=False ../a limit
128 135 $ hg clone --pull -q --config phases.publish=False ../a segv
129 136 $ rm -R limit/.hg/cache segv/.hg/cache
130 137
131 138 $ $PYTHON <<EOF
132 139 > data = open("limit/.hg/store/00changelog.i", "rb").read()
133 140 > for n, p in [('limit', '\0\0\0\x02'), ('segv', '\0\x01\0\0')]:
134 141 > # corrupt p1 at rev0 and p2 at rev1
135 142 > d = data[:24] + p + data[28:127 + 28] + p + data[127 + 32:]
136 143 > open(n + "/.hg/store/00changelog.i", "wb").write(d)
137 144 > EOF
138 145
139 146 $ hg debugindex -f1 limit/.hg/store/00changelog.i
140 147 rev flag offset length size base link p1 p2 nodeid
141 148 0 0000 0 63 62 0 0 2 -1 7c31755bf9b5
142 149 1 0000 63 66 65 1 1 0 2 26333235a41c
143 150 $ hg debugindex -f1 segv/.hg/store/00changelog.i
144 151 rev flag offset length size base link p1 p2 nodeid
145 152 0 0000 0 63 62 0 0 65536 -1 7c31755bf9b5
146 153 1 0000 63 66 65 1 1 0 65536 26333235a41c
147 154
148 155 $ cat <<EOF > test.py
149 156 > import sys
150 157 > from mercurial import changelog, vfs
151 158 > cl = changelog.changelog(vfs.vfs(sys.argv[1]))
152 159 > n0, n1 = cl.node(0), cl.node(1)
153 160 > ops = [
154 161 > ('reachableroots',
155 162 > lambda: cl.index.reachableroots2(0, [1], [0], False)),
156 163 > ('compute_phases_map_sets', lambda: cl.computephases([[0], []])),
157 164 > ('index_headrevs', lambda: cl.headrevs()),
158 165 > ('find_gca_candidates', lambda: cl.commonancestorsheads(n0, n1)),
159 166 > ('find_deepest', lambda: cl.ancestor(n0, n1)),
160 167 > ]
161 168 > for l, f in ops:
162 169 > print l + ':',
163 170 > try:
164 171 > f()
165 172 > print 'uncaught buffer overflow?'
166 173 > except ValueError, inst:
167 174 > print inst
168 175 > EOF
169 176
170 177 $ $PYTHON test.py limit/.hg/store
171 178 reachableroots: parent out of range
172 179 compute_phases_map_sets: parent out of range
173 180 index_headrevs: parent out of range
174 181 find_gca_candidates: parent out of range
175 182 find_deepest: parent out of range
176 183 $ $PYTHON test.py segv/.hg/store
177 184 reachableroots: parent out of range
178 185 compute_phases_map_sets: parent out of range
179 186 index_headrevs: parent out of range
180 187 find_gca_candidates: parent out of range
181 188 find_deepest: parent out of range
182 189
183 190 $ cd ..
184 191
185 192 #endif
General Comments 0
You need to be logged in to leave comments. Login now