From 1cd41dd84ae8171744f85d4705d82a8f935e3b19 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Dec 01 2016 14:11:35 +0000 Subject: [PATCH 1/4] Add a new method to add content to a file in a repo during the tests --- diff --git a/tests/__init__.py b/tests/__init__.py index 395d2e3..02ac3f3 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -558,6 +558,57 @@ def add_commit_git_repo(folder, ncommits=10, filename='sources'): shutil.rmtree(newfolder) +def add_content_to_git(folder, filename='sources', content='foo'): + """ Create some more commits for the specified git repo. """ + if not os.path.exists(folder): + os.makedirs(folder) + brepo = pygit2.init_repository(folder, bare=True) + + newfolder = tempfile.mkdtemp(prefix='pagure-tests') + repo = pygit2.clone_repository(folder, newfolder) + + # Create a file in that git repo + with open(os.path.join(newfolder, filename), 'a') as stream: + stream.write('%s\n' % content) + repo.index.add(filename) + repo.index.write() + + parents = [] + commit = None + try: + commit = repo.revparse_single('HEAD') + except KeyError: + pass + if commit: + parents = [commit.oid.hex] + + # Commits the files added + tree = repo.index.write_tree() + author = pygit2.Signature( + 'Alice Author', 'alice@authors.tld') + committer = pygit2.Signature( + 'Cecil Committer', 'cecil@committers.tld') + repo.create_commit( + 'refs/heads/master', # the name of the reference to update + author, + committer, + 'Add content to file %s' % (filename), + # binary string representing the tree object ID + tree, + # list of binary strings representing parents of the new commit + parents, + ) + + # Push to origin + ori_remote = repo.remotes[0] + master_ref = repo.lookup_reference('HEAD').resolve() + refname = '%s:%s' % (master_ref.name, master_ref.name) + + PagureRepo.push(ori_remote, refname) + + shutil.rmtree(newfolder) + + def add_binary_git_repo(folder, filename): """ Create a fake image file for the specified git repo. """ if not os.path.exists(folder): From e3f6fec5f81fedcbeadb1fce51df15e03e03a395 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Dec 01 2016 14:11:35 +0000 Subject: [PATCH 2/4] Fix blaming files containing non-ascii characters The error was reported by email on a certain file of the linux kernel repo that is also present in staging. The added unit-test allows to replicate the issue and the fix of the filter actually fixes it. --- diff --git a/pagure/ui/filters.py b/pagure/ui/filters.py index 45f32f6..478e080 100644 --- a/pagure/ui/filters.py +++ b/pagure/ui/filters.py @@ -268,6 +268,8 @@ def blame_loc(loc, repo, username, blame): ] for idx, line in enumerate(loc.split('\n')): + line = line.decode('utf-8') + if line == '': break diff --git a/tests/test_pagure_flask_ui_repo.py b/tests/test_pagure_flask_ui_repo.py index edc5322..1079b22 100644 --- a/tests/test_pagure_flask_ui_repo.py +++ b/tests/test_pagure_flask_ui_repo.py @@ -1701,6 +1701,9 @@ class PagureFlaskRepotests(tests.Modeltests): tests.add_commit_git_repo( os.path.join(self.path, 'forks', 'pingou', 'test3.git'), ncommits=10) + tests.add_content_to_git( + os.path.join(self.path, 'forks', 'pingou', 'test3.git'), + content='foö\bbáßðáz') output = self.app.get('/fork/pingou/test3/blame/sources') self.assertEqual(output.status_code, 200) From a3b01a2dc1457fa644861bbeb6f8e593ec720823 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Dec 01 2016 14:29:00 +0000 Subject: [PATCH 3/4] Handle the situation where the repo's head is unborned Fixes an error reported by email --- diff --git a/pagure/ui/repo.py b/pagure/ui/repo.py index 2e2c676..b22e5df 100644 --- a/pagure/ui/repo.py +++ b/pagure/ui/repo.py @@ -694,7 +694,7 @@ def view_blame_file(repo, filename, username=None, namespace=None): branchname = flask.request.args.get('identifier', 'master') - if repo_obj.is_empty: + if repo_obj.is_empty or repo_obj.head_is_unborn: flask.abort(404, 'Empty repo cannot have a file') commit = repo_obj[repo_obj.head.target] From 00ab2313e1dbe5485d31f41aa9765e3cdbf37114 Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Dec 01 2016 21:37:22 +0000 Subject: [PATCH 4/4] Decode the blamed file before rendering the template This also adds an explicit check to the blame_loc filter to ensure the loc is unicode. Signed-off-by: Jeremy Cline --- diff --git a/pagure/ui/filters.py b/pagure/ui/filters.py index 478e080..1226d22 100644 --- a/pagure/ui/filters.py +++ b/pagure/ui/filters.py @@ -20,6 +20,7 @@ import urlparse import arrow import flask import md5 +import six from pygments import highlight from pygments.lexers.text import DiffLexer @@ -250,7 +251,7 @@ def blame_loc(loc, repo, username, blame): and convert it into a html table displayed to the user with the git blame information (user, commit, commit date). - :arg loc: a text object of the lines of code to display (in this case, + :arg loc: a unicode object of the lines of code to display (in this case, most likely the content of a file). :arg repo: the name of the repo in which this file is. :arg username: the user name of the user whose repo this is, if the repo @@ -262,14 +263,15 @@ def blame_loc(loc, repo, username, blame): if loc is None: return + if not isinstance(loc, six.text_type): + raise ValueError('"loc" must be a unicode string, not ' + str(type(loc))) + output = [ '
', '' ] for idx, line in enumerate(loc.split('\n')): - line = line.decode('utf-8') - if line == '': break diff --git a/pagure/ui/repo.py b/pagure/ui/repo.py index b22e5df..096aa97 100644 --- a/pagure/ui/repo.py +++ b/pagure/ui/repo.py @@ -708,7 +708,7 @@ def view_blame_file(repo, filename, username=None, namespace=None): if is_binary_string(content.data): flask.abort(400, 'Binary files cannot be blamed') - content = ktc.to_bytes(content.data) + content = encoding_utils.decode(content.data) blame = repo_obj.blame(filename) return flask.render_template( diff --git a/tests/test_pagure_flask_ui_repo.py b/tests/test_pagure_flask_ui_repo.py index 1079b22..9a2d9ae 100644 --- a/tests/test_pagure_flask_ui_repo.py +++ b/tests/test_pagure_flask_ui_repo.py @@ -1637,7 +1637,7 @@ class PagureFlaskRepotests(tests.Modeltests): self.assertIn(b'
', output.data) self.assertIn( b'', output.data) + b'data-line-number="1">', output.data) self.assertIn( b'', output.data) @@ -1703,7 +1703,7 @@ class PagureFlaskRepotests(tests.Modeltests): ncommits=10) tests.add_content_to_git( os.path.join(self.path, 'forks', 'pingou', 'test3.git'), - content='foö\bbáßðáz') + content=u'✨☃🍰☃✨'.encode('utf-8')) output = self.app.get('/fork/pingou/test3/blame/sources') self.assertEqual(output.status_code, 200)
 bar