From da5cf13644f2f8843cfdf3f53681ac685720c5a8 Mon Sep 17 00:00:00 2001 From: Alex Iribarren Date: Mar 11 2021 18:17:36 +0000 Subject: [PATCH 1/4] Show VCS and DistURL tags as links when appropriate --- diff --git a/tests/test_www/test_util.py b/tests/test_www/test_util.py index 0ead026..0f7c918 100644 --- a/tests/test_www/test_util.py +++ b/tests/test_www/test_util.py @@ -1,6 +1,6 @@ import unittest -from kojiweb.util import formatMode +from kojiweb.util import formatMode, formatLink class TestFormatMode(unittest.TestCase): def test_format_mode(self): @@ -16,3 +16,21 @@ class TestFormatMode(unittest.TestCase): for s, mode in formats: self.assertEqual(formatMode(mode), s) + + def test_format_link(self): + formats = ( + ('test me', 'test me'), + (' test ', 'test'), + ('', '<script>hack</script>'), + ('not://valid', 'not://valid'), + ('https://foo.com', 'https://foo.com'), + ('http://bar.com/', 'http://bar.com/'), + ('HTtP://BaR.CoM/', 'HTtP://BaR.CoM/'), + ('https://baz.com/baz&t=1', 'https://baz.com/baz&t=1'), + ('ssh://git@pagure.io/foo', 'ssh://git@pagure.io/foo'), + ('git://git@pagure.io/foo', 'git://git@pagure.io/foo'), + ('obs://build.opensuse.org/foo', 'obs://build.opensuse.org/foo'), + ) + + for input, output in formats: + self.assertEqual(formatLink(input), output) diff --git a/www/kojiweb/buildinfo.chtml b/www/kojiweb/buildinfo.chtml index 1198e07..c164c07 100644 --- a/www/kojiweb/buildinfo.chtml +++ b/www/kojiweb/buildinfo.chtml @@ -52,12 +52,12 @@ #end if #if $vcs - $util.escapeHTML($vcs) + $util.formatLink($vcs) #end if #if $disturl - DistURL$util.escapeHTML($disturl) + DistURL$util.formatLink($disturl) #end if diff --git a/www/kojiweb/rpminfo.chtml b/www/kojiweb/rpminfo.chtml index fe2c714..f2313f3 100644 --- a/www/kojiweb/rpminfo.chtml +++ b/www/kojiweb/rpminfo.chtml @@ -70,12 +70,12 @@ #if $vcs - $util.escapeHTML($vcs) + $util.formatLink($vcs) #end if #if $disturl - DistURL$util.escapeHTML($disturl) + DistURL$util.formatLink($disturl) #end if #end if diff --git a/www/lib/kojiweb/util.py b/www/lib/kojiweb/util.py index 301fd92..1dc2a56 100644 --- a/www/lib/kojiweb/util.py +++ b/www/lib/kojiweb/util.py @@ -534,6 +534,16 @@ def formatThousands(value): return '{:,}'.format(value) +def formatLink(url): + """Turn a string into an HTML link if it looks vaguely like a URL. + If it doesn't, just return it properly escaped.""" + url = escapeHTML(url.strip()) + m = re.match(r'(https?|ssh|git|obs)://.*', url, flags=re.IGNORECASE) + if m: + return '{}'.format(url, url) + + return url + def rowToggle(template): """If the value of template._rowNum is even, return 'row-even'; if it is odd, return 'row-odd'. Increment the value before checking it. From c12cdcfb54385a567d6bb8b41006b4a6f6aa8374 Mon Sep 17 00:00:00 2001 From: Alex Iribarren Date: Mar 12 2021 12:30:00 +0000 Subject: [PATCH 2/4] Escape single and double quotes as well, plus add test --- diff --git a/tests/test_www/test_util.py b/tests/test_www/test_util.py index 0f7c918..0c8e019 100644 --- a/tests/test_www/test_util.py +++ b/tests/test_www/test_util.py @@ -1,6 +1,6 @@ import unittest -from kojiweb.util import formatMode, formatLink +from kojiweb.util import formatMode, formatLink, escapeHTML class TestFormatMode(unittest.TestCase): def test_format_mode(self): @@ -34,3 +34,14 @@ class TestFormatMode(unittest.TestCase): for input, output in formats: self.assertEqual(formatLink(input), output) + + def test_escape_html(self): + tests = ( + ('test me', 'test me'), + ('test ', 'test <danger>'), + ('test ', 'test <danger="true">'), + ("test ", 'test <danger='true'>'), + ) + + for input, output in tests: + self.assertEqual(escapeHTML(input), output) diff --git a/www/lib/kojiweb/util.py b/www/lib/kojiweb/util.py index 1dc2a56..8091f6f 100644 --- a/www/lib/kojiweb/util.py +++ b/www/lib/kojiweb/util.py @@ -604,6 +604,8 @@ def escapeHTML(value): < : < > : > & : & + " : " + ' : ' """ if not value: return value @@ -611,7 +613,9 @@ def escapeHTML(value): value = koji.fixEncoding(value) return value.replace('&', '&').\ replace('<', '<').\ - replace('>', '>') + replace('>', '>').\ + replace('"', '"').\ + replace("'", ''') def authToken(template, first=False, form=False): From 5e95e701c99ae293922d3a80aeea9f0f45420b6b Mon Sep 17 00:00:00 2001 From: Alex Iribarren Date: Mar 12 2021 18:06:12 +0000 Subject: [PATCH 3/4] Don't encode already encoded entities --- diff --git a/tests/test_www/test_util.py b/tests/test_www/test_util.py index 0c8e019..b6b9c57 100644 --- a/tests/test_www/test_util.py +++ b/tests/test_www/test_util.py @@ -41,6 +41,8 @@ class TestFormatMode(unittest.TestCase): ('test ', 'test <danger>'), ('test ', 'test <danger="true">'), ("test ", 'test <danger='true'>'), + ('test&test', 'test&test'), + ('test&test', 'test&test'), ) for input, output in tests: diff --git a/www/lib/kojiweb/util.py b/www/lib/kojiweb/util.py index 8091f6f..abd161d 100644 --- a/www/lib/kojiweb/util.py +++ b/www/lib/kojiweb/util.py @@ -117,12 +117,7 @@ class DecodeUTF8(Cheetah.Filters.Filter): class XHTMLFilter(DecodeUTF8): def filter(self, *args, **kw): result = super(XHTMLFilter, self).filter(*args, **kw) - result = result.replace('&', '&') - result = result.replace('&amp;', '&') - result = result.replace('&nbsp;', ' ') - result = result.replace('&lt;', '<') - result = result.replace('&gt;', '>') - return result + return re.sub(r'&(?![a-zA-Z0-9#]+;)', '&', result) TEMPLATES = {} @@ -611,7 +606,7 @@ def escapeHTML(value): return value value = koji.fixEncoding(value) - return value.replace('&', '&').\ + return re.sub(r'&(?![a-zA-Z0-9#]+;)', '&', value).\ replace('<', '<').\ replace('>', '>').\ replace('"', '"').\ From 3a59389f7cb90761912d585600a34a7a6ad2914e Mon Sep 17 00:00:00 2001 From: Alex Iribarren Date: Mar 15 2021 13:39:38 +0000 Subject: [PATCH 4/4] Make flake8 happy --- diff --git a/www/lib/kojiweb/util.py b/www/lib/kojiweb/util.py index abd161d..a49c639 100644 --- a/www/lib/kojiweb/util.py +++ b/www/lib/kojiweb/util.py @@ -539,6 +539,7 @@ def formatLink(url): return url + def rowToggle(template): """If the value of template._rowNum is even, return 'row-even'; if it is odd, return 'row-odd'. Increment the value before checking it.