cp: trailing slash on source filename is an error, just like on targets

This commit is contained in:
Brian Warner 2015-05-01 17:37:07 -07:00
parent ca23c4fa23
commit 275ddb93cc
2 changed files with 23 additions and 6 deletions

View File

@ -20,6 +20,10 @@ class MissingSourceError(TahoeError):
def __init__(self, name, quotefn=quote_output):
TahoeError.__init__(self, "No such file or directory %s" % quotefn(name))
class FilenameWithTrailingSlashError(TahoeError):
def __init__(self, name, quotefn=quote_output):
TahoeError.__init__(self, "source '%s' is not a directory, but ends with a slash" % quotefn(name))
def GET_to_file(url):
resp = do_http("GET", url)
@ -501,7 +505,11 @@ class Copier:
sources = [] # list of source objects
for ss in source_specs:
si = self.get_source_info(ss)
try:
si = self.get_source_info(ss)
except FilenameWithTrailingSlashError:
self.to_stderr("source is not a directory, but ends with a slash")
return 1
precondition(isinstance(si, FileSources + DirectorySources), si)
sources.append(si)
@ -622,6 +630,9 @@ class Copier:
precondition(isinstance(source_spec, unicode), source_spec)
rootcap, path_utf8 = get_alias(self.aliases, source_spec, None)
path = path_utf8.decode("utf-8")
# any trailing slash is removed in abspath_expanduser_unicode(), so
# make a note of it here, to throw an error later
had_trailing_slash = path.endswith("/")
if rootcap == DefaultAliasMarker:
# no alias, so this is a local file
pathname = abspath_expanduser_unicode(path)
@ -631,6 +642,8 @@ class Copier:
if os.path.isdir(pathname):
t = LocalDirectorySource(self.progress, pathname, name)
else:
if had_trailing_slash:
raise FilenameWithTrailingSlashError(source_spec)
assert os.path.isfile(pathname)
t = LocalFileSource(pathname, name) # non-empty
else:
@ -659,6 +672,8 @@ class Copier:
self.progress, name)
t.init_from_parsed(parsed)
else:
if had_trailing_slash:
raise FilenameWithTrailingSlashError(source_spec)
writecap = to_str(d.get("rw_uri"))
readcap = to_str(d.get("ro_uri"))
mutable = d.get("mutable", False) # older nodes don't provide it

View File

@ -660,7 +660,7 @@ starting copy, 2 files, 1 directories
# trailing slash on target *directory* should not matter, test both
# trailing slash on target files should cause error
# trailing slash on source directory should not matter, test a few
# ignore trailing slash on source file, that's easiest
# trailing slash on source files should cause error
COPYOUT_TESTCASES = """
cp $FILECAP to/existing-file : to/existing-file
@ -686,12 +686,12 @@ cp $FILECAP to : E2-DESTNAME
cp -r $FILECAP to : E2-DESTNAME
cp $DIRCAP/file to : to/file
cp -r $DIRCAP/file to : to/file
# these two should behave like the two above: ignore trailing slash
cp $DIRCAP/file/ to : to/file
cp -r $DIRCAP/file/ to : to/file
# these two are errors
cp $DIRCAP/file/ to : E8-BADSLASH
cp -r $DIRCAP/file/ to : E8-BADSLASH
cp $PARENTCAP/dir to : E4-NEED-R
cp -r $PARENTCAP/dir to : to/dir/file
# these two should ignore the trailing source slash too
# but these two should ignore the trailing source slash
cp $PARENTCAP/dir/ to : E4-NEED-R
cp -r $PARENTCAP/dir/ to : to/dir/file
cp $DIRCAP to : E4-NEED-R
@ -949,6 +949,8 @@ class CopyOut(GridTestMixin, CLITestMixin, unittest.TestCase):
return set(["E6-MANYONE"])
if err == "target is not a directory, but ends with a slash":
return set(["E7-BADSLASH"])
if err == "source is not a directory, but ends with a slash":
return set(["E8-BADSLASH"])
self.fail("unrecognized error ('%s') %s" % (case, res))
d.addCallback(_check)
return d