Changeset 1df7f11 in trunk


Ignore:
Timestamp:
2012-10-25T00:01:25Z (13 years ago)
Author:
David-Sarah Hopwood <david-sarah@…>
Branches:
master
Children:
b3bf207
Parents:
05d0b8b
Message:

src/allmydata/web/directory.py: fix HTML double-encoding issue for filenames.

Nevow automatically HTML-escapes strings passed in stan without a raw marker.
Written by MK_FG. fixes #1143

Signed-off-by: David-Sarah Hopwood <david-sarah@…>

Location:
src/allmydata
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/allmydata/test/test_web.py

    r05d0b8b r1df7f11  
    77from twisted.internet import defer, reactor
    88from twisted.internet.task import Clock
    9 from twisted.web import client, error, http
     9from twisted.web import client, error, http, html
    1010from twisted.python import failure, log
    1111
    1212from foolscap.api import fireEventually, flushEventualQueue
    1313
     14from nevow.util import escapeToXML
    1415from nevow import rend
    1516
     
    257258            foo.set_uri(u"blockingfile", blocking_uri, blocking_uri)
    258259
     260            # filenode to test for html encoding issues
     261            self._htmlname_unicode = u"<&weirdly'named\"file>>>_<iframe />.txt"
     262            self._htmlname_raw = self._htmlname_unicode.encode('utf-8')
     263            self._htmlname_urlencoded = urllib.quote(self._htmlname_raw, '')
     264            self._htmlname_escaped = escapeToXML(self._htmlname_raw)
     265            self._htmlname_escaped_attr = html.escape(self._htmlname_raw)
     266            self._htmlname_escaped_double = escapeToXML(html.escape(self._htmlname_raw))
     267            self.HTMLNAME_CONTENTS, n, self._htmlname_txt_uri = self.makefile(0)
     268            foo.set_uri(self._htmlname_unicode, self._htmlname_txt_uri, self._htmlname_txt_uri)
     269
    259270            unicode_filename = u"n\u00fc.txt" # n u-umlaut . t x t
    260271            # ok, unicode calls it LATIN SMALL LETTER U WITH DIAERESIS but I
     
    281292            # public/foo/quux.txt
    282293            # public/foo/blockingfile
     294            # public/foo/<&weirdly'named\"file>>>_<iframe />.txt
    283295            # public/foo/empty/
    284296            # public/foo/sub/
     
    366378        kidnames = sorted([unicode(n) for n in data[1]["children"]])
    367379        self.failUnlessEqual(kidnames,
    368                              [u"bar.txt", u"baz.txt", u"blockingfile",
    369                               u"empty", u"n\u00fc.txt", u"quux.txt", u"sub"])
     380                             [self._htmlname_unicode, u"bar.txt", u"baz.txt",
     381                              u"blockingfile", u"empty", u"n\u00fc.txt", u"quux.txt", u"sub"])
    370382        kids = dict( [(unicode(name),value)
    371383                      for (name,value)
     
    13421354        return d
    13431355
     1356    def test_GET_DIRECTORY_html_filenode_encoding(self):
     1357        d = self.GET(self.public_url + "/foo", followRedirect=True)
     1358        def _check(html):
     1359            # Check if encoded entries are there
     1360            self.failUnlessIn('@@named=/' + self._htmlname_urlencoded + '">'
     1361                              + self._htmlname_escaped + '</a>', html)
     1362            self.failUnlessIn('value="' + self._htmlname_escaped_attr + '"', html)
     1363            self.failIfIn(self._htmlname_escaped_double, html)
     1364            # Make sure that Nevow escaping actually works by checking for unsafe characters
     1365            # and that '&' is escaped.
     1366            for entity in '<>':
     1367                self.failUnlessIn(entity, self._htmlname_raw)
     1368                self.failIfIn(entity, self._htmlname_escaped)
     1369            self.failUnlessIn('&', re.sub(r'&(amp|lt|gt|quot|apos);', '', self._htmlname_raw))
     1370            self.failIfIn('&', re.sub(r'&(amp|lt|gt|quot|apos);', '', self._htmlname_escaped))
     1371        d.addCallback(_check)
     1372        return d
     1373
    13441374    def test_GET_root_html(self):
    13451375        d = self.GET("/")
     
    15641594        d.addCallback(self.get_operation_results, "127", "json")
    15651595        def _got_json(stats):
    1566             expected = {"count-immutable-files": 3,
     1596            expected = {"count-immutable-files": 4,
    15671597                        "count-mutable-files": 2,
    15681598                        "count-literal-files": 0,
    1569                         "count-files": 5,
     1599                        "count-files": 6,
    15701600                        "count-directories": 3,
    1571                         "size-immutable-files": 57,
     1601                        "size-immutable-files": 76,
    15721602                        "size-literal-files": 0,
    15731603                        #"size-directories": 1912, # varies
    15741604                        #"largest-directory": 1590,
    1575                         "largest-directory-children": 7,
     1605                        "largest-directory-children": 8,
    15761606                        "largest-immutable-file": 19,
    15771607                        }
     
    15811611                                           (k, stats[k], v))
    15821612            self.failUnlessReallyEqual(stats["size-files-histogram"],
    1583                                        [ [11, 31, 3] ])
     1613                                       [ [11, 31, 4] ])
    15841614        d.addCallback(_got_json)
    15851615        return d
     
    15901620            self.failUnless(res.endswith("\n"))
    15911621            units = [simplejson.loads(t) for t in res[:-1].split("\n")]
    1592             self.failUnlessReallyEqual(len(units), 9)
     1622            self.failUnlessReallyEqual(len(units), 10)
    15931623            self.failUnlessEqual(units[-1]["type"], "stats")
    15941624            first = units[0]
     
    24352465        d.addCallback(lambda res:
    24362466                      self.failUnlessNodeKeysAre(self._foo_node,
    2437                                                  [u"bar.txt", u"baz.txt", u"blockingfile",
     2467                                                 [self._htmlname_unicode,
     2468                                                  u"bar.txt", u"baz.txt", u"blockingfile",
    24382469                                                  u"empty", u"n\u00fc.txt", u"quux.txt",
    24392470                                                  u"sub"]))
     
    26272658        def _check_json(data):
    26282659            self.failUnlessReallyEqual(data["finished"], True)
    2629             self.failUnlessReallyEqual(data["count-objects-checked"], 10)
    2630             self.failUnlessReallyEqual(data["count-objects-healthy"], 10)
     2660            self.failUnlessReallyEqual(data["count-objects-checked"], 11)
     2661            self.failUnlessReallyEqual(data["count-objects-healthy"], 11)
    26312662        d.addCallback(_check_json)
    26322663        d.addCallback(self.get_operation_results, "123", "html")
    26332664        def _check_html(res):
    2634             self.failUnlessIn("Objects Checked: <span>10</span>", res)
    2635             self.failUnlessIn("Objects Healthy: <span>10</span>", res)
     2665            self.failUnlessIn("Objects Checked: <span>11</span>", res)
     2666            self.failUnlessIn("Objects Healthy: <span>11</span>", res)
    26362667            self.failUnlessIn(FAVICON_MARKUP, res)
    26372668        d.addCallback(_check_html)
     
    26632694        def _check_json(data):
    26642695            self.failUnlessReallyEqual(data["finished"], True)
    2665             self.failUnlessReallyEqual(data["count-objects-checked"], 10)
    2666             self.failUnlessReallyEqual(data["count-objects-healthy-pre-repair"], 10)
     2696            self.failUnlessReallyEqual(data["count-objects-checked"], 11)
     2697            self.failUnlessReallyEqual(data["count-objects-healthy-pre-repair"], 11)
    26672698            self.failUnlessReallyEqual(data["count-objects-unhealthy-pre-repair"], 0)
    26682699            self.failUnlessReallyEqual(data["count-corrupt-shares-pre-repair"], 0)
     
    26702701            self.failUnlessReallyEqual(data["count-repairs-successful"], 0)
    26712702            self.failUnlessReallyEqual(data["count-repairs-unsuccessful"], 0)
    2672             self.failUnlessReallyEqual(data["count-objects-healthy-post-repair"], 10)
     2703            self.failUnlessReallyEqual(data["count-objects-healthy-post-repair"], 11)
    26732704            self.failUnlessReallyEqual(data["count-objects-unhealthy-post-repair"], 0)
    26742705            self.failUnlessReallyEqual(data["count-corrupt-shares-post-repair"], 0)
     
    26762707        d.addCallback(self.get_operation_results, "124", "html")
    26772708        def _check_html(res):
    2678             self.failUnlessIn("Objects Checked: <span>10</span>", res)
    2679 
    2680             self.failUnlessIn("Objects Healthy (before repair): <span>10</span>", res)
     2709            self.failUnlessIn("Objects Checked: <span>11</span>", res)
     2710
     2711            self.failUnlessIn("Objects Healthy (before repair): <span>11</span>", res)
    26812712            self.failUnlessIn("Objects Unhealthy (before repair): <span>0</span>", res)
    26822713            self.failUnlessIn("Corrupt Shares (before repair): <span>0</span>", res)
     
    26862717            self.failUnlessIn("Repairs Unsuccessful: <span>0</span>", res)
    26872718
    2688             self.failUnlessIn("Objects Healthy (after repair): <span>10</span>", res)
     2719            self.failUnlessIn("Objects Healthy (after repair): <span>11</span>", res)
    26892720            self.failUnlessIn("Objects Unhealthy (after repair): <span>0</span>", res)
    26902721            self.failUnlessIn("Corrupt Shares (after repair): <span>0</span>", res)
     
    36793710
    36803711    def test_PUT_NEWFILEURL_bad_format(self):
    3681        new_contents = self.NEWFILE_CONTENTS * 300000
    3682        return self.shouldHTTPError("PUT_NEWFILEURL_bad_format",
    3683                                    400, "Bad Request", "Unknown format: foo",
    3684                                    self.PUT, self.public_url + \
    3685                                    "/foo/foo.txt?format=foo",
    3686                                    new_contents)
     3712        new_contents = self.NEWFILE_CONTENTS * 300000
     3713        return self.shouldHTTPError("PUT_NEWFILEURL_bad_format",
     3714                                    400, "Bad Request", "Unknown format: foo",
     3715                                    self.PUT, self.public_url + \
     3716                                    "/foo/foo.txt?format=foo",
     3717                                    new_contents)
    36873718
    36883719    def test_PUT_NEWFILEURL_uri_replace(self):
  • TabularUnified src/allmydata/web/directory.py

    r05d0b8b r1df7f11  
    77from twisted.internet.interfaces import IPushProducer
    88from twisted.python.failure import Failure
    9 from twisted.web import http, html
     9from twisted.web import http
    1010from nevow import url, rend, inevow, tags as T
    1111from nevow.inevow import IRequest
     
    751751            dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, nameurl)
    752752
    753             ctx.fillSlots("filename",
    754                           T.a(href=dlurl)[html.escape(name)])
     753            ctx.fillSlots("filename", T.a(href=dlurl)[name])
    755754            ctx.fillSlots("type", "SSK")
    756755
     
    762761            dlurl = "%s/file/%s/@@named=/%s" % (root, quoted_uri, nameurl)
    763762
    764             ctx.fillSlots("filename",
    765                           T.a(href=dlurl)[html.escape(name)])
     763            ctx.fillSlots("filename", T.a(href=dlurl)[name])
    766764            ctx.fillSlots("type", "FILE")
    767765
     
    773771            # directory
    774772            uri_link = "%s/uri/%s/" % (root, urllib.quote(target_uri))
    775             ctx.fillSlots("filename",
    776                           T.a(href=uri_link)[html.escape(name)])
     773            ctx.fillSlots("filename", T.a(href=uri_link)[name])
    777774            if not target.is_mutable():
    778775                dirtype = "DIR-IMM"
     
    798795        else:
    799796            # unknown
    800             ctx.fillSlots("filename", html.escape(name))
     797            ctx.fillSlots("filename", name)
    801798            if target.get_write_uri() is not None:
    802799                unknowntype = "?"
Note: See TracChangeset for help on using the changeset viewer.