changeset 528:f3bf55de8a34

Prevent path highlighting from passing non-canonical paths to svn: * ignore prefixes like `-I` (so that `-I../..` does not resolve down to `.`) * Normalize the path before looking in the repository * Check that nothing like `../` will allow the link to point out of the configured repository section * Add a test for the bad links that we could reproduce producing the `is_canonical` crash * Should fix #206
author dfraser
date Wed, 18 Mar 2009 08:50:17 +0000
parents ab4942089190
children ed37b6a02897
files bitten/tests/web_ui.py bitten/web_ui.py
diffstat 2 files changed, 28 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/bitten/tests/web_ui.py
+++ b/bitten/tests/web_ui.py
@@ -162,6 +162,25 @@
         self.assertEqual('error in <a href="/trac/browser/trunk/foo/bar.c">'
                          'foo/bar.c</a>: bad', output)
 
+    def test_format_bad_links(self):
+        BuildConfig(self.env, name='test', path='trunk').insert()
+        build = Build(self.env, config='test', platform=1, rev=123, rev_time=42,
+                      status=Build.SUCCESS, slave='hal')
+        build.insert()
+        step = BuildStep(self.env, build=build.id, name='foo',
+                         status=BuildStep.SUCCESS)
+        step.insert()
+
+        self.repos.get_node = lambda path, rev: (path, rev)
+
+        req = Mock(method='GET', href=Href('/trac'), authname='hal')
+        comp = SourceFileLinkFormatter(self.env)
+        formatter = comp.get_formatter(req, build)
+
+        output = formatter(step, None, None, u'Linking -I../.. with ../libtool')
+        self.assertEqual(Markup, type(output))
+        self.assertEqual('Linking -I../.. with ../libtool', output)
+
     def test_format_simple_link_not_in_repos(self):
         BuildConfig(self.env, name='test', path='trunk').insert()
         build = Build(self.env, config='test', platform=1, rev=123, rev_time=42,
--- a/bitten/web_ui.py
+++ b/bitten/web_ui.py
@@ -612,7 +612,7 @@
 
     implements(ILogFormatter)
 
-    _fileref_re = re.compile('(?P<path>[\w.-]+(?:/[\w.-]+)+)(?P<line>(:\d+))?')
+    _fileref_re = re.compile('(?P<prefix>-[A-Za-z])?(?P<path>[\w.-]+(?:/[\w.-]+)+)(?P<line>(:\d+))?')
 
     def get_formatter(self, req, build):
         """Return the log message formatter function."""
@@ -630,9 +630,14 @@
                     path = posixpath.join(path, part)
                     if path not in cache:
                         try:
-                            repos.get_node(posixpath.join(config.path, path),
-                                           build.rev)
-                            cache[path] = True
+                            full_path = posixpath.join(config.path, path)
+                            full_path = posixpath.normpath(full_path)
+                            if full_path.startswith(config.path + "/") or full_path == config.path:
+                                repos.get_node(full_path,
+                                               build.rev)
+                                cache[path] = True
+                            else:
+                                cache[path] = False
                         except TracError:
                             cache[path] = False
                     if cache[path] is False:
Copyright (C) 2012-2017 Edgewall Software