Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/pure/parsers.py @ 14421:639f26cab2f5
pure parsers: properly detect corrupt index files
This new Python code should be equivalent in behavior to the if
statement at line 312 of parsers.c. Without this, the pure-python
parsers improperly ignore truncated revlogs as created in
test-verify.t.
author | Augie Fackler <durin42@gmail.com> |
---|---|
date | Tue, 24 May 2011 13:30:10 -0500 |
parents | e4bfb9c337f3 |
children | 8d928799dab5 |
rev | line source |
---|---|
7700
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
1 # parsers.py - Python implementation of parsers.c |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
2 # |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
7945
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
7700
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
7 |
14064
e4bfb9c337f3
remove unused imports and variables
Alexander Solovyov <alexander@solovyov.net>
parents:
13435
diff
changeset
|
8 from mercurial.node import bin, nullid |
7945
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
9 from mercurial import util |
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
10 import struct, zlib |
7700
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
11 |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
12 _pack = struct.pack |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
13 _unpack = struct.unpack |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
14 _compress = zlib.compress |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
15 _decompress = zlib.decompress |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
16 _sha = util.sha1 |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
17 |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
18 def parse_manifest(mfdict, fdict, lines): |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
19 for l in lines.splitlines(): |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
20 f, n = l.split('\0') |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
21 if len(n) > 40: |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
22 fdict[f] = n[40:] |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
23 mfdict[f] = bin(n[:40]) |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
24 else: |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
25 mfdict[f] = bin(n) |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
26 |
13261
20a54bdf2328
pure: update index parsing
Matt Mackall <mpm@selenic.com>
parents:
13253
diff
changeset
|
27 def parse_index2(data, inline): |
7945
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
28 def gettype(q): |
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
29 return int(q & 0xFFFF) |
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
30 |
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
31 def offset_type(offset, type): |
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
32 return long(long(offset) << 16 | type) |
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
33 |
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
34 indexformatng = ">Qiiiiii20s12x" |
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
35 |
7700
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
36 s = struct.calcsize(indexformatng) |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
37 index = [] |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
38 cache = None |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
39 n = off = 0 |
13253 | 40 |
7700
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
41 l = len(data) - s |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
42 append = index.append |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
43 if inline: |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
44 cache = (0, data) |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
45 while off <= l: |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
46 e = _unpack(indexformatng, data[off:off + s]) |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
47 append(e) |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
48 n += 1 |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
49 if e[1] < 0: |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
50 break |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
51 off += e[1] + s |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
52 else: |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
53 while off <= l: |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
54 e = _unpack(indexformatng, data[off:off + s]) |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
55 append(e) |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
56 n += 1 |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
57 off += s |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
58 |
14421
639f26cab2f5
pure parsers: properly detect corrupt index files
Augie Fackler <durin42@gmail.com>
parents:
14064
diff
changeset
|
59 if off != len(data): |
639f26cab2f5
pure parsers: properly detect corrupt index files
Augie Fackler <durin42@gmail.com>
parents:
14064
diff
changeset
|
60 raise ValueError('corrupt index file') |
639f26cab2f5
pure parsers: properly detect corrupt index files
Augie Fackler <durin42@gmail.com>
parents:
14064
diff
changeset
|
61 |
13435
90d7ce986565
pure: fix index parsing on empty repositories
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
13261
diff
changeset
|
62 if index: |
90d7ce986565
pure: fix index parsing on empty repositories
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
13261
diff
changeset
|
63 e = list(index[0]) |
90d7ce986565
pure: fix index parsing on empty repositories
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
13261
diff
changeset
|
64 type = gettype(e[0]) |
90d7ce986565
pure: fix index parsing on empty repositories
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
13261
diff
changeset
|
65 e[0] = offset_type(0, type) |
90d7ce986565
pure: fix index parsing on empty repositories
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
13261
diff
changeset
|
66 index[0] = tuple(e) |
7700
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
67 |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
68 # add the magic null revision at -1 |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
69 index.append((0, 0, 0, -1, -1, -1, -1, nullid)) |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
70 |
13261
20a54bdf2328
pure: update index parsing
Matt Mackall <mpm@selenic.com>
parents:
13253
diff
changeset
|
71 return index, cache |
7700
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
72 |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
73 def parse_dirstate(dmap, copymap, st): |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
74 parents = [st[:20], st[20: 40]] |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
75 # deref fields so they will be local in loop |
7945
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
76 format = ">cllll" |
94d7e14cfa42
pure/parsers: fix circular imports, import mercurial modules properly
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
77 e_size = struct.calcsize(format) |
7700
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
78 pos1 = 40 |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
79 l = len(st) |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
80 |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
81 # the inner loop |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
82 while pos1 < l: |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
83 pos2 = pos1 + e_size |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
84 e = _unpack(">cllll", st[pos1:pos2]) # a literal here is faster |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
85 pos1 = pos2 + e[4] |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
86 f = st[pos2:pos1] |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
87 if '\0' in f: |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
88 f, c = f.split('\0') |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
89 copymap[f] = c |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
90 dmap[f] = e[:4] |
f410c552fa15
pure Python implementation of parsers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
91 return parents |