#5524 Avoid crash resolving symlink in a tree that's not a Tree
Merged by ngompa. Opened by adamwill.
adamwill/pagure readme-symlink-crash  into  master

Download 5524.patch

There's a codepath in ui.repo.view_file where we call
__get_file_in_tree() and pass it a second argument that is not
a pygit2 Tree, it's just a list:

        content = sorted(content, key=lambda x: x.filemode)
...
                readme_file = __get_file_in_tree(
                    repo_obj, content, [i.name]
                ).data

sorted() always produces a list, so the content we pass to
__get_file_in_tree here is a list. But if the file we're trying
to get is a symlink, we wind up in this section of
__get_file_in_tree which implicitly assumes tree (the second
arg) must be a pygit2 Tree, because it tries to index it using
a bytestring.

If tree is actually a list, trying to index it with a bytestring
produces a TypeError not a KeyError, so the simplest fix is
to just catch that exception too.

Signed-off-by: Adam Williamson awilliam@redhat.com

Alternative lines of attack here would be:

  1. try and make view_file actually pass a Tree to __get_file_in_tree() here (but I'm not totally sure of all the possibilities for what content might be before we call sorted() here, so that looks a bit hard - it's a complex function)
  2. have an alternative path which notices when tree is just a list and iterates over it looking for one with the right name, or whatever (but that also looked harder and wouldn't work in the case which is crashing here anyway, I don't think, so I didn't bother)

This bug is causing a 500 when you try and access https://pagure.io/cloud-image-uploader/blob/main/f/fedora-image-uploader , because it contains a README.md which is a symlink. I suspect this bug likely happens any time there's a README that's a symlink.

Oh, forgot, here's the traceback:

 Traceback (most recent call last):
   File "/usr/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
     response = self.full_dispatch_request()
   File "/usr/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
     rv = self.handle_user_exception(e)
   File "/usr/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
     reraise(exc_type, exc_value, tb)
   File "/usr/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
     raise value
   File "/usr/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
     rv = self.dispatch_request()
   File "/usr/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
     return self.view_functions[rule.endpoint](**req.view_args)
   File "/usr/lib/python3.6/site-packages/pagure/ui/repo.py", line 628, in view_file
     repo_obj, content, [i.name]
   File "/usr/lib/python3.6/site-packages/pagure/utils.py", line 430, in __get_file_in_tree
     dereferenced = tree[content]
 TypeError: list indices must be integers or slices, not bytes

:thumbsup:

:thumbsup:

Pull-Request has been merged by ngompa

Metadata