Rather than blow up late in the game, after we've already committed
and are just trying to write the dirstate, catch it much earlier. Then
we avoid putting the working dir in a bad state (dirstate does not
reflect commit), and it's also quite obvious that the problem is that
some file has blown one of the 32-bit limits in dirstate.
Error messages need work. Commence bikeshedding at will. ;-)
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -46,6 +46,16 @@
return
del dirs[base]
+_toobig = 2**31
+def _lstat(fn):
+ '''wrapper for os.lstat() to ensure the size and mtime are 32-bit safe,
+ i.e. won't make dirstate.write() blow up with struct.error'''
+ s = os.lstat(fn)
+ if s.st_size >= _toobig:
+ raise util.Abort('file %s too big for dirstate' % fn)
+ if s.st_mtime >= _toobig:
+ raise util.Abort('file %s too new for dirstate' % fn)
+
class dirstate(object):
def __init__(self, opener, ui, root, validate):
@@ -308,7 +318,7 @@
'''Mark a file normal and clean.'''
self._dirty = True
self._addpath(f)
- s = os.lstat(self._join(f))
+ s = _lstat(self._join(f))
mtime = int(s.st_mtime)
self._map[f] = ('n', s.st_mode, s.st_size, mtime)
if f in self._copymap:
@@ -356,6 +366,7 @@
def add(self, f):
'''Mark a file added.'''
+ _lstat(f) # trigger the 32-bit safety check
self._dirty = True
self._addpath(f, True)
self._map[f] = ('a', 0, -1, -1)
@@ -381,7 +392,7 @@
def merge(self, f):
'''Mark a file merged.'''
self._dirty = True
- s = os.lstat(self._join(f))
+ s = _lstat(self._join(f))
self._addpath(f)
self._map[f] = ('m', s.st_mode, s.st_size, int(s.st_mtime))
if f in self._copymap:
diff --git a/tests/gpg/trustdb.gpg b/tests/gpg/trustdb.gpg
index 4008cdab6dbf5976ed84e1bd48fd954edd0bd6df..826f03e0e42de51482d52fc6fc87e9eababd9589
GIT binary patch
literal 1280
zc${NQFGy!*W@Ke#VqoykDzRh04j8#`NT7pJb))Jq)X5Eyy`$=eojM+dhSR^3+@~`O
xY&Gq*Tcpdm+)w4>CpL(rJVG5W17G+x=V>!}{~YYC+iiDPMtj+*xJot*^8j}D7cBq)
_______________________________________________
Mercurial-devel mailing list
Mercuri...@selenic.com
http://selenic.com/mailman/listinfo/mercurial-devel
It has previously been proposed that we just could store the lower bits
of the file size in the dirstate. That should be sufficiently safe for
most real world usage.
Something similar could perhaps be done with the time stamp.
/Mads