# HG changeset patch # User dfraser # Date 1237366217 0 # Node ID f3bf55de8a349def02007faa9dd9e10a3d83574d # Parent ab49420891909e511cdab000fe6ff5931b5bb071 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 diff --git a/bitten/tests/web_ui.py b/bitten/tests/web_ui.py --- a/bitten/tests/web_ui.py +++ b/bitten/tests/web_ui.py @@ -162,6 +162,25 @@ self.assertEqual('error in ' 'foo/bar.c: 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, diff --git a/bitten/web_ui.py b/bitten/web_ui.py --- a/bitten/web_ui.py +++ b/bitten/web_ui.py @@ -612,7 +612,7 @@ implements(ILogFormatter) - _fileref_re = re.compile('(?P[\w.-]+(?:/[\w.-]+)+)(?P(:\d+))?') + _fileref_re = re.compile('(?P-[A-Za-z])?(?P[\w.-]+(?:/[\w.-]+)+)(?P(:\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: