Mercurial > p > roundup > code
changeset 6103:af16c135fb98
url's with javascript scheme should not be links in reST
A javascript url in a reStructuredText document should not be
displayed as a link. So:
javascript:nastyJavascriptCode
should be displayed as text and not a link.
We do this by stripping the scheme from the schemes array in
docutils.utils.urischemes. We set a property on the
StringHTMLProperty to hold the list of schemes we want to disable so
the user can choose to change it if they want.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Tue, 25 Feb 2020 22:48:17 -0500 |
| parents | 0a82437a2930 |
| children | a1fd9551d416 |
| files | roundup/cgi/templating.py test/test_templating.py |
| diffstat | 2 files changed, 32 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/roundup/cgi/templating.py Tue Feb 25 16:36:18 2020 +0000 +++ b/roundup/cgi/templating.py Tue Feb 25 22:48:17 2020 -0500 @@ -1499,6 +1499,12 @@ 'raw_enabled': 0, '_disable_config': 1} + # List of schemes that are not rendered as links in rst. + # Could also be used to disable links for other processors: + # e.g. stext or markdown. If we can figure out how to do it. + disable_schemes = [ 'javascript' ] + valid_schemes = { } + def _hyper_repl(self, match): if match.group('url'): return self._hyper_repl_url(match, '<a href="%s" rel="nofollow noopener">%s</a>%s') @@ -1661,6 +1667,27 @@ s = self.plain(escape=0, hyperlink=0) if hyperlink: s = self.hyper_re.sub(self._hyper_repl_rst, s) + + # disable javascript and possibly other url schemes from working + from docutils.utils.urischemes import schemes + for sch in self.disable_schemes: + # I catch KeyError but reraise if scheme didn't exist. + # Safer to fail if a disabled scheme isn't found. It may + # be a typo that keeps a bad scheme enabled. But this + # function can be called multiple times. On the first call + # the key will be deleted. On the second call the schemes + # variable isn't re-initialized so the key is missing + # causing a KeyError. So see if we removed it (and entered + # it into valid_schemes). If we didn't raise KeyError. + try: + del(schemes[sch]) + self.valid_schemes[sch] = True + except KeyError: + if sch in self.valid_schemes: + pass + else: + raise + return u2s(ReStructuredText(s, writer_name="html", settings_overrides=self.rst_defaults)["html_body"])
--- a/test/test_templating.py Tue Feb 25 16:36:18 2020 +0000 +++ b/test/test_templating.py Tue Feb 25 22:48:17 2020 -0500 @@ -281,9 +281,14 @@ </div> </div> ''' + # test case to make sure javascript url's aren't turned into links + s = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'<badtag>\njavascript:badcode')) + s_result = '<div class="document">\n<p><badtag>\njavascript:badcode</p>\n</div>\n' + self.assertEqual(p.rst(), u2s(u'<div class="document">\n<p>A string with <a class="reference external" href="mailto:cmeerw@example.com">cmeerw@example.com</a> <em>embedded</em> \u00df</p>\n</div>\n')) self.assertEqual(q.rst(), u2s(q_result)) self.assertEqual(r.rst(), u2s(r_result)) + self.assertEqual(s.rst(), u2s(s_result)) @skip_stext def test_string_stext(self):
