Show More
@@ -0,0 +1,21 | |||||
|
1 | #!/bin/bash | |||
|
2 | # http://www.selenic.com/mercurial/bts/issue352 | |||
|
3 | ||||
|
4 | hg init foo | |||
|
5 | cd foo | |||
|
6 | ||||
|
7 | A=`echo -e -n 'he\rllo'` | |||
|
8 | ||||
|
9 | echo foo > "hell | |||
|
10 | o" | |||
|
11 | echo foo > "$A" | |||
|
12 | hg add | |||
|
13 | hg ci -A -m m | |||
|
14 | rm "$A" | |||
|
15 | ls | |||
|
16 | hg add | |||
|
17 | # BUG ? we don't walk on filenames with '\n' (regexp related) ? | |||
|
18 | hg debugwalk | |||
|
19 | hg ci -A -m m | |||
|
20 | ||||
|
21 | exit 0 |
@@ -0,0 +1,7 | |||||
|
1 | adding he llo | |||
|
2 | abort: '\n' and '\r' disallowed in filenames | |||
|
3 | adding he llo | |||
|
4 | abort: '\n' and '\r' disallowed in filenames | |||
|
5 | hell | |||
|
6 | o | |||
|
7 | nothing changed |
@@ -211,7 +211,7 class dirstate(object): | |||||
211 | self.dirs.setdefault(pc, 0) |
|
211 | self.dirs.setdefault(pc, 0) | |
212 | self.dirs[pc] += delta |
|
212 | self.dirs[pc] += delta | |
213 |
|
213 | |||
214 |
def check |
|
214 | def checkinterfering(self, files): | |
215 | def prefixes(f): |
|
215 | def prefixes(f): | |
216 | for c in strutil.rfindall(f, '/'): |
|
216 | for c in strutil.rfindall(f, '/'): | |
217 | yield f[:c] |
|
217 | yield f[:c] | |
@@ -219,6 +219,7 class dirstate(object): | |||||
219 | self.initdirs() |
|
219 | self.initdirs() | |
220 | seendirs = {} |
|
220 | seendirs = {} | |
221 | for f in files: |
|
221 | for f in files: | |
|
222 | # shadows | |||
222 | if self.dirs.get(f): |
|
223 | if self.dirs.get(f): | |
223 | raise util.Abort(_('directory named %r already in dirstate') % |
|
224 | raise util.Abort(_('directory named %r already in dirstate') % | |
224 | f) |
|
225 | f) | |
@@ -229,6 +230,9 class dirstate(object): | |||||
229 | raise util.Abort(_('file named %r already in dirstate') % |
|
230 | raise util.Abort(_('file named %r already in dirstate') % | |
230 | d) |
|
231 | d) | |
231 | seendirs[d] = True |
|
232 | seendirs[d] = True | |
|
233 | # disallowed | |||
|
234 | if '\r' in f or '\n' in f: | |||
|
235 | raise util.Abort(_("'\\n' and '\\r' disallowed in filenames")) | |||
232 |
|
236 | |||
233 | def update(self, files, state, **kw): |
|
237 | def update(self, files, state, **kw): | |
234 | ''' current states: |
|
238 | ''' current states: | |
@@ -242,7 +246,7 class dirstate(object): | |||||
242 | self.markdirty() |
|
246 | self.markdirty() | |
243 | if state == "a": |
|
247 | if state == "a": | |
244 | self.initdirs() |
|
248 | self.initdirs() | |
245 |
self.check |
|
249 | self.checkinterfering(files) | |
246 | for f in files: |
|
250 | for f in files: | |
247 | if state == "r": |
|
251 | if state == "r": | |
248 | self.map[f] = ('r', 0, 0, 0) |
|
252 | self.map[f] = ('r', 0, 0, 0) |
@@ -138,6 +138,10 class manifest(revlog): | |||||
138 | return "".join([struct.pack(">lll", d[0], d[1], len(d[2])) + d[2] \ |
|
138 | return "".join([struct.pack(">lll", d[0], d[1], len(d[2])) + d[2] \ | |
139 | for d in x ]) |
|
139 | for d in x ]) | |
140 |
|
140 | |||
|
141 | def checkforbidden(f): | |||
|
142 | if '\n' in f or '\r' in f: | |||
|
143 | raise RevlogError(_("'\\n' and '\\r' disallowed in filenames")) | |||
|
144 | ||||
141 | # if we're using the listcache, make sure it is valid and |
|
145 | # if we're using the listcache, make sure it is valid and | |
142 | # parented by the same node we're diffing against |
|
146 | # parented by the same node we're diffing against | |
143 | if not changed or not self.listcache or not p1 or \ |
|
147 | if not changed or not self.listcache or not p1 or \ | |
@@ -145,6 +149,9 class manifest(revlog): | |||||
145 | files = map.keys() |
|
149 | files = map.keys() | |
146 | files.sort() |
|
150 | files.sort() | |
147 |
|
151 | |||
|
152 | for f in files: | |||
|
153 | checkforbidden(f) | |||
|
154 | ||||
148 | # if this is changed to support newlines in filenames, |
|
155 | # if this is changed to support newlines in filenames, | |
149 | # be sure to check the templates/ dir again (especially *-raw.tmpl) |
|
156 | # be sure to check the templates/ dir again (especially *-raw.tmpl) | |
150 | text = ["%s\000%s%s\n" % (f, hex(map[f]), map.flags(f)) for f in files] |
|
157 | text = ["%s\000%s%s\n" % (f, hex(map[f]), map.flags(f)) for f in files] | |
@@ -153,6 +160,8 class manifest(revlog): | |||||
153 | else: |
|
160 | else: | |
154 | addlist = self.listcache |
|
161 | addlist = self.listcache | |
155 |
|
162 | |||
|
163 | for f in changed[0]: | |||
|
164 | checkforbidden(f) | |||
156 | # combine the changed lists into one list for sorting |
|
165 | # combine the changed lists into one list for sorting | |
157 | work = [[x, 0] for x in changed[0]] |
|
166 | work = [[x, 0] for x in changed[0]] | |
158 | work[len(work):] = [[x, 1] for x in changed[1]] |
|
167 | work[len(work):] = [[x, 1] for x in changed[1]] |
General Comments 0
You need to be logged in to leave comments.
Login now