From: Brian Warner Date: Wed, 24 Sep 2008 20:35:05 +0000 (-0700) Subject: webapi: survive slashes in filenames better: make t=info and t=delete to work, and... X-Git-Url: https://git.rkrishnan.org/vdrive/index.php?a=commitdiff_plain;h=54fce5c06630b1b7fe47131b6ab104fda311521d;p=tahoe-lafs%2Ftahoe-lafs.git webapi: survive slashes in filenames better: make t=info and t=delete to work, and let t=rename fix the problem --- diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index 16da92e1..365b5de9 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -1836,21 +1836,6 @@ class Web(WebMixin, unittest.TestCase): ) d.addCallback(lambda res: self.failUnlessNodeHasChild(self._foo_node, u"bar.txt")) - d.addCallback(lambda res: self.POST(self.public_url, t="rename", - from_name="foo/bar.txt", to_name='george.txt')) - d.addBoth(self.shouldFail, error.Error, - "test_POST_rename_file_slash_fail", - "400 Bad Request", - "from_name= may not contain a slash", - ) - d.addCallback(lambda res: - self.failUnlessNodeHasChild(self.public_root, u"foo")) - d.addCallback(lambda res: - self.failIfNodeHasChild(self.public_root, u"george.txt")) - d.addCallback(lambda res: - self.failUnlessNodeHasChild(self._foo_node, u"bar.txt")) - d.addCallback(lambda res: self.GET(self.public_url + "/foo?t=json")) - d.addCallback(self.failUnlessIsFooJSON) return d def test_POST_rename_dir(self): diff --git a/src/allmydata/web/directory.py b/src/allmydata/web/directory.py index a2600773..5990570a 100644 --- a/src/allmydata/web/directory.py +++ b/src/allmydata/web/directory.py @@ -324,10 +324,12 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin): assert isinstance(to_name, unicode) if not from_name or not to_name: raise WebError("rename requires from_name and to_name") - for k,v in [ ('from_name', from_name), ('to_name', to_name) ]: - if v and "/" in v: - raise WebError("%s= may not contain a slash" % k, - http.BAD_REQUEST) + + # allow from_name to contain slashes, so they can fix names that were + # accidentally created with them. But disallow them in to_name, to + # discourage the practice. + if "/" in to_name: + raise WebError("to_name= may not contain a slash", http.BAD_REQUEST) replace = boolean_of_arg(get_arg(req, "replace", "true")) d = self.node.move_child_to(from_name, self.node, to_name, replace) @@ -444,6 +446,7 @@ class DirectoryAsHTML(rend.Page): name, (target, metadata) = data name = name.encode("utf-8") assert not isinstance(name, unicode) + nameurl = urllib.quote(name, safe="") # encode any slashes too root = self.get_root(ctx) here = "%s/uri/%s/" % (root, urllib.quote(self.node.get_uri())) @@ -495,7 +498,7 @@ class DirectoryAsHTML(rend.Page): # to prevent javascript in displayed .html files from stealing a # secret directory URI from the URL, send the browser to a URI-based # page that doesn't know about the directory at all - dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, urllib.quote(name)) + dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, nameurl) ctx.fillSlots("filename", T.a(href=dlurl)[html.escape(name)]) @@ -504,10 +507,10 @@ class DirectoryAsHTML(rend.Page): ctx.fillSlots("size", "?") text_plain_url = "%s/file/%s/@@named=/foo.txt" % (root, quoted_uri) - info_link = "%s?t=info" % name + info_link = "%s?t=info" % nameurl elif IFileNode.providedBy(target): - dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, urllib.quote(name)) + dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, nameurl) ctx.fillSlots("filename", T.a(href=dlurl)[html.escape(name)]) @@ -516,7 +519,7 @@ class DirectoryAsHTML(rend.Page): ctx.fillSlots("size", target.get_size()) text_plain_url = "%s/file/%s/@@named=/foo.txt" % (root, quoted_uri) - info_link = "%s?t=info" % name + info_link = "%s?t=info" % nameurl elif IDirectoryNode.providedBy(target): # directory @@ -529,7 +532,7 @@ class DirectoryAsHTML(rend.Page): dirtype = "DIR" ctx.fillSlots("type", dirtype) ctx.fillSlots("size", "-") - info_link = "%s/?t=info" % name + info_link = "%s/?t=info" % nameurl ctx.fillSlots("info", T.a(href=info_link)["More Info"])