From 91dafafa152d50b21ed7a8447e4aeadd60c8bc09 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 13 2015 09:48:28 +0000 Subject: [PATCH 1/3] Move the logic to get sym-linked files from a tree to __get_file_in_tree This allows benefiting from this change in all places (front-page, showing the content of a file, editing a file) --- diff --git a/pagure/__init__.py b/pagure/__init__.py index 8eed220..695aec8 100644 --- a/pagure/__init__.py +++ b/pagure/__init__.py @@ -314,13 +314,28 @@ def __get_file_in_tree(repo_obj, tree, filepath): ''' Retrieve the entry corresponding to the provided filename in a given tree. ''' + filename = filepath[0] if isinstance(tree, pygit2.Blob): return for entry in tree: if entry.name == filename: if len(filepath) == 1: - return repo_obj[entry.oid] + blob = repo_obj[entry.oid] + content = blob.data + # If it's a (sane) symlink, we try a single-level dereference + if entry.filemode == pygit2.GIT_FILEMODE_LINK \ + and os.path.normpath(content) == content \ + and not os.path.isabs(content): + try: + dereferenced = tree[content] + except KeyError: + pass + else: + if dereferenced.filemode == pygit2.GIT_FILEMODE_BLOB: + blob = repo_obj[dereferenced.oid] + + return blob else: return __get_file_in_tree( repo_obj, repo_obj[entry.oid], filepath[1:]) diff --git a/pagure/ui/repo.py b/pagure/ui/repo.py index 50ff49b..4efb6db 100644 --- a/pagure/ui/repo.py +++ b/pagure/ui/repo.py @@ -88,18 +88,9 @@ def view_repo(repo, username=None): for i in tree: name, ext = os.path.splitext(i.name) if name == 'README': - content = repo_obj[i.oid].data - # If it's a (sane) symlink, we try a single-level dereference - if i.filemode == pygit2.GIT_FILEMODE_LINK \ - and os.path.normpath(content) == content \ - and not os.path.isabs(content): - try: - dereferenced = last_commits[0].tree[content] - except KeyError: - pass - else: - if dereferenced.filemode == pygit2.GIT_FILEMODE_BLOB: - content = repo_obj[dereferenced.oid].data + content = __get_file_in_tree( + repo_obj, last_commits[0].tree, [i.name]).data + readme, safe = pagure.doc_utils.convert_readme( content, ext, view_file_url=flask.url_for( From fd8afd61d092d9f1fe3b9946b361c4e9f6cbde6d Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 13 2015 09:53:49 +0000 Subject: [PATCH 2/3] Converting .rst may sometime fail, in which case return the text --- diff --git a/pagure/doc_utils.py b/pagure/doc_utils.py index 3b6914b..d2c5b58 100644 --- a/pagure/doc_utils.py +++ b/pagure/doc_utils.py @@ -71,17 +71,22 @@ def convert_doc(rst_string, view_file_url=None): rst = modify_rst(rst_string, view_file_url) overrides = {'report_level': 'quiet'} - html = docutils.core.publish_parts( - source=rst, - writer_name='html', - settings_overrides=overrides) + try: + html = docutils.core.publish_parts( + source=rst, + writer_name='html', + settings_overrides=overrides) + except: + return '
%s
' % rst + + else: - html_string = html['html_body'] + html_string = html['html_body'] - html_string = modify_html(html_string) + html_string = modify_html(html_string) - html_string = markupsafe.Markup(html_string) - return html_string + html_string = markupsafe.Markup(html_string) + return html_string def convert_readme(content, ext, view_file_url=None): From 5eec56b0aeed6ee181419b3eff0dc9543f919d36 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 13 2015 10:04:58 +0000 Subject: [PATCH 3/3] Cover the situation where we can a tree instead of the expected blob Fixes the unit-tests --- diff --git a/pagure/__init__.py b/pagure/__init__.py index 695aec8..f462636 100644 --- a/pagure/__init__.py +++ b/pagure/__init__.py @@ -310,7 +310,7 @@ def auth_logout(): # pragma: no cover return flask.redirect(return_point) -def __get_file_in_tree(repo_obj, tree, filepath): +def __get_file_in_tree(repo_obj, tree, filepath, bail_on_tree=False): ''' Retrieve the entry corresponding to the provided filename in a given tree. ''' @@ -322,6 +322,9 @@ def __get_file_in_tree(repo_obj, tree, filepath): if entry.name == filename: if len(filepath) == 1: blob = repo_obj[entry.oid] + # If we get a tree instead of a blob, let's escape + if isinstance(tree, pygit2.Tree) and bail_on_tree: + return blob content = blob.data # If it's a (sane) symlink, we try a single-level dereference if entry.filemode == pygit2.GIT_FILEMODE_LINK \ diff --git a/pagure/ui/issues.py b/pagure/ui/issues.py index 909b524..bde3335 100644 --- a/pagure/ui/issues.py +++ b/pagure/ui/issues.py @@ -722,7 +722,7 @@ def view_issue_raw_file(repo, filename=None, username=None): encoding = None content = __get_file_in_tree( - repo_obj, commit.tree, filename.split('/')) + repo_obj, commit.tree, filename.split('/'), bail_on_tree=True) if not content or isinstance(content, pygit2.Tree): flask.abort(404, 'File not found') diff --git a/pagure/ui/repo.py b/pagure/ui/repo.py index 4efb6db..ba46e52 100644 --- a/pagure/ui/repo.py +++ b/pagure/ui/repo.py @@ -373,7 +373,7 @@ def view_file(repo, identifier, filename, username=None): if commit and not isinstance(commit, pygit2.Blob): content = __get_file_in_tree( - repo_obj, commit.tree, filename.split('/')) + repo_obj, commit.tree, filename.split('/'), bail_on_tree=True) if not content: flask.abort(404, 'File not found') content = repo_obj[content.oid] @@ -472,7 +472,7 @@ def view_raw_file(repo, identifier, filename=None, username=None): encoding = None if filename: content = __get_file_in_tree( - repo_obj, commit.tree, filename.split('/')) + repo_obj, commit.tree, filename.split('/'), bail_on_tree=True) if not content or isinstance(content, pygit2.Tree): flask.abort(404, 'File not found')