issue352: disallow '\n' and '\r' in filenames (dirstate and manifest)
--- a/mercurial/dirstate.py Tue Oct 31 18:10:23 2006 -0800
+++ b/mercurial/dirstate.py Wed Nov 01 17:56:55 2006 +0100
@@ -211,7 +211,7 @@
self.dirs.setdefault(pc, 0)
self.dirs[pc] += delta
- def checkshadows(self, files):
+ def checkinterfering(self, files):
def prefixes(f):
for c in strutil.rfindall(f, '/'):
yield f[:c]
@@ -219,6 +219,7 @@
self.initdirs()
seendirs = {}
for f in files:
+ # shadows
if self.dirs.get(f):
raise util.Abort(_('directory named %r already in dirstate') %
f)
@@ -229,6 +230,9 @@
raise util.Abort(_('file named %r already in dirstate') %
d)
seendirs[d] = True
+ # disallowed
+ if '\r' in f or '\n' in f:
+ raise util.Abort(_("'\\n' and '\\r' disallowed in filenames"))
def update(self, files, state, **kw):
''' current states:
@@ -242,7 +246,7 @@
self.markdirty()
if state == "a":
self.initdirs()
- self.checkshadows(files)
+ self.checkinterfering(files)
for f in files:
if state == "r":
self.map[f] = ('r', 0, 0, 0)
--- a/mercurial/manifest.py Tue Oct 31 18:10:23 2006 -0800
+++ b/mercurial/manifest.py Wed Nov 01 17:56:55 2006 +0100
@@ -138,6 +138,10 @@
return "".join([struct.pack(">lll", d[0], d[1], len(d[2])) + d[2] \
for d in x ])
+ def checkforbidden(f):
+ if '\n' in f or '\r' in f:
+ raise RevlogError(_("'\\n' and '\\r' disallowed in filenames"))
+
# if we're using the listcache, make sure it is valid and
# parented by the same node we're diffing against
if not changed or not self.listcache or not p1 or \
@@ -145,6 +149,9 @@
files = map.keys()
files.sort()
+ for f in files:
+ checkforbidden(f)
+
# if this is changed to support newlines in filenames,
# be sure to check the templates/ dir again (especially *-raw.tmpl)
text = ["%s\000%s%s\n" % (f, hex(map[f]), map.flags(f)) for f in files]
@@ -153,6 +160,8 @@
else:
addlist = self.listcache
+ for f in changed[0]:
+ checkforbidden(f)
# combine the changed lists into one list for sorting
work = [[x, 0] for x in changed[0]]
work[len(work):] = [[x, 1] for x in changed[1]]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-issue352 Wed Nov 01 17:56:55 2006 +0100
@@ -0,0 +1,21 @@
+#!/bin/bash
+# http://www.selenic.com/mercurial/bts/issue352
+
+hg init foo
+cd foo
+
+A=`echo -e -n 'he\rllo'`
+
+echo foo > "hell
+o"
+echo foo > "$A"
+hg add
+hg ci -A -m m
+rm "$A"
+ls
+hg add
+# BUG ? we don't walk on filenames with '\n' (regexp related) ?
+hg debugwalk
+hg ci -A -m m
+
+exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-issue352.out Wed Nov 01 17:56:55 2006 +0100
@@ -0,0 +1,7 @@
+adding he
llo
+abort: '\n' and '\r' disallowed in filenames
+adding he
llo
+abort: '\n' and '\r' disallowed in filenames
+hell
+o
+nothing changed