]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
cp: trailing slash on source filename is an error, just like on targets
authorBrian Warner <warner@lothar.com>
Sat, 2 May 2015 00:37:07 +0000 (17:37 -0700)
committerBrian Warner <warner@lothar.com>
Mon, 4 May 2015 05:14:35 +0000 (22:14 -0700)
src/allmydata/scripts/tahoe_cp.py
src/allmydata/test/test_cli_cp.py

index a5cfe16a1a25b7b65e9ca9d9856256457b7da9a4..7c3026218563b7ca085bcd8cb8c3f8e883048ec4 100644 (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
index 24087a4f49f00325b194dbb77746e02ef92430da..03abcc4595cb344122ecec23b2b1fe68e462d369 100644 (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