# HG changeset patch # User Vadim Gelfer # Date 1147710447 25200 # Node ID 1cad19678b4cb5a20c3172a3f960366ae8d969cb # Parent dfa17bd1d45ed4f46c50a4fdfd3dd29721bdb22f# Parent 6563438219e3710d2ae8bd84fca69c1080e5dbce merge with crew. diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -405,19 +405,17 @@ class revlog(object): if n == 0 and self.inlinedata(): # cache the first chunk self.chunkcache = (0, data) + if leftover: + data = leftover + data + leftover = None off = 0 l = len(data) while off < l: if l - off < s: leftover = data[off:] break - if leftover: - cur = leftover + data[off:off + s - len(leftover)] - off += s - len(leftover) - leftover = None - else: - cur = data[off:off + s] - off += s + cur = data[off:off + s] + off += s e = struct.unpack(self.indexformat, cur) self.index.append(e) self.nodemap[e[-1]] = n diff --git a/tests/test-parseindex b/tests/test-parseindex new file mode 100755 --- /dev/null +++ b/tests/test-parseindex @@ -0,0 +1,52 @@ +#!/bin/sh +# +# 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' -d '1000000 0' + +echo >> foo +hg commit -m 'change foo' -d '1000001 0' +hg log -r 0: + +cat >> test.py << EOF +from mercurial import changelog, util +from mercurial.node import * + +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) + +def opener(*args): + o = util.opener(*args) + def wrapper(*a): + f = o(*a) + return singlebyteread(f) + return wrapper + +cl = changelog.changelog(opener('.hg')) +print cl.count(), 'revisions:' +for r in xrange(cl.count()): + print short(cl.node(r)) +EOF + +python test.py diff --git a/tests/test-parseindex.out b/tests/test-parseindex.out new file mode 100644 --- /dev/null +++ b/tests/test-parseindex.out @@ -0,0 +1,14 @@ +changeset: 0:9c2cf2b35aa7 +user: test +date: Mon Jan 12 13:46:40 1970 +0000 +summary: add foo + +changeset: 1:3756a9556b89 +tag: tip +user: test +date: Mon Jan 12 13:46:41 1970 +0000 +summary: change foo + +2 revisions: +9c2cf2b35aa7 +3756a9556b89