Show More
@@ -147,6 +147,11 b' def checklink(path):' | |||||
147 | except (OSError, AttributeError): |
|
147 | except (OSError, AttributeError): | |
148 | return False |
|
148 | return False | |
149 |
|
149 | |||
|
150 | def checkosfilename(path): | |||
|
151 | '''Check that the base-relative path is a valid filename on this platform. | |||
|
152 | Returns None if the path is ok, or a UI string describing the problem.''' | |||
|
153 | pass # on posix platforms, every path is ok | |||
|
154 | ||||
150 | def set_binary(fd): |
|
155 | def set_binary(fd): | |
151 | pass |
|
156 | pass | |
152 |
|
157 |
@@ -493,6 +493,48 b' def copyfiles(src, dst, hardlink=None):' | |||||
493 |
|
493 | |||
494 | return hardlink, num |
|
494 | return hardlink, num | |
495 |
|
495 | |||
|
496 | _windows_reserved_filenames = '''con prn aux nul | |||
|
497 | com1 com2 com3 com4 com5 com6 com7 com8 com9 | |||
|
498 | lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9'''.split() | |||
|
499 | _windows_reserved_chars = ':*?"<>|' | |||
|
500 | def checkwinfilename(path): | |||
|
501 | '''Check that the base-relative path is a valid filename on Windows. | |||
|
502 | Returns None if the path is ok, or a UI string describing the problem. | |||
|
503 | ||||
|
504 | >>> checkwinfilename("just/a/normal/path") | |||
|
505 | >>> checkwinfilename("foo/bar/con.xml") | |||
|
506 | "filename contains 'con', which is reserved on Windows" | |||
|
507 | >>> checkwinfilename("foo/con.xml/bar") | |||
|
508 | "filename contains 'con', which is reserved on Windows" | |||
|
509 | >>> checkwinfilename("foo/bar/xml.con") | |||
|
510 | >>> checkwinfilename("foo/bar/AUX/bla.txt") | |||
|
511 | "filename contains 'AUX', which is reserved on Windows" | |||
|
512 | >>> checkwinfilename("foo/bar/bla:.txt") | |||
|
513 | "filename contains ':', which is reserved on Windows" | |||
|
514 | >>> checkwinfilename("foo/bar/b\07la.txt") | |||
|
515 | "filename contains '\\x07', which is invalid on Windows" | |||
|
516 | >>> checkwinfilename("foo/bar/bla ") | |||
|
517 | "filename ends with ' ', which is not allowed on Windows" | |||
|
518 | ''' | |||
|
519 | for n in path.replace('\\', '/').split('/'): | |||
|
520 | if not n: | |||
|
521 | continue | |||
|
522 | for c in n: | |||
|
523 | if c in _windows_reserved_chars: | |||
|
524 | return _("filename contains '%s', which is reserved " | |||
|
525 | "on Windows") % c | |||
|
526 | if ord(c) <= 31: | |||
|
527 | return _("filename contains '%s', which is invalid " | |||
|
528 | "on Windows") % c | |||
|
529 | base = n.split('.')[0] | |||
|
530 | if base and base.lower() in _windows_reserved_filenames: | |||
|
531 | return _("filename contains '%s', which is reserved " | |||
|
532 | "on Windows") % base | |||
|
533 | t = n[-1] | |||
|
534 | if t in '. ': | |||
|
535 | return _("filename ends with '%s', which is not allowed " | |||
|
536 | "on Windows") % t | |||
|
537 | ||||
496 | class path_auditor(object): |
|
538 | class path_auditor(object): | |
497 | '''ensure that a filesystem path contains no banned components. |
|
539 | '''ensure that a filesystem path contains no banned components. | |
498 | the following properties of a path are checked: |
|
540 | the following properties of a path are checked: | |
@@ -560,6 +602,9 b' class path_auditor(object):' | |||||
560 | prefixes.append(prefix) |
|
602 | prefixes.append(prefix) | |
561 | parts.pop() |
|
603 | parts.pop() | |
562 |
|
604 | |||
|
605 | r = checkosfilename(path) | |||
|
606 | if r: | |||
|
607 | raise Abort("%s: %s" % (r, path)) | |||
563 | self.audited.add(path) |
|
608 | self.audited.add(path) | |
564 | # only add prefixes to the cache after checking everything: we don't |
|
609 | # only add prefixes to the cache after checking everything: we don't | |
565 | # want to add "foo/bar/baz" before checking if there's a "foo/.hg" |
|
610 | # want to add "foo/bar/baz" before checking if there's a "foo/.hg" | |
@@ -577,6 +622,7 b' def hidewindow():' | |||||
577 | pass |
|
622 | pass | |
578 |
|
623 | |||
579 | if os.name == 'nt': |
|
624 | if os.name == 'nt': | |
|
625 | checkosfilename = checkwinfilename | |||
580 | from windows import * |
|
626 | from windows import * | |
581 | else: |
|
627 | else: | |
582 | from posix import * |
|
628 | from posix import * |
General Comments 0
You need to be logged in to leave comments.
Login now