# 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: