##// END OF EJS Templates
path_auditor: check filenames for basic platform validity (issue2755)...
Adrian Buehlmann -
r13916:98ee3dd5 default
parent child Browse files
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