~edwargix/git.sr.ht

06d89a7e5e5ef56e8186d0dd02b5b7ef1951fe6e — Armin Weigl 3 years ago b0e6248
Fix 500 on invalid file or directory name

This fixes server errors occuring when displaying a commit or tree, which
contains an non decodeable file or directory name
3 files changed, 23 insertions(+), 22 deletions(-)

M gitsrht/blueprints/api/porcelain.py
M gitsrht/git.py
M gitsrht/templates/utils.html
M gitsrht/blueprints/api/porcelain.py => gitsrht/blueprints/api/porcelain.py +1 -1
@@ 48,7 48,7 @@ def tree_to_dict(t):
        "short_id": t.short_id,
        "entries": [
            {
                "name": e.name,
                "name": e.raw_name.decode("utf-8", "replace"),
                "id": str(e.id),
                "type": (e.type_str if hasattr(e, "type_str") else e.type),
                "mode": e.filemode,

M gitsrht/git.py => gitsrht/git.py +12 -11
@@ 95,7 95,7 @@ class AnnotatedTreeEntry:
        self.commit = None
        if entry is not None:
            self.id = entry.id.hex
            self.name = entry.name
            self.name = entry.raw_name.decode("utf-8", "replace")
            self.type = (entry.type_str
                    if hasattr(entry, "type_str") else entry.type)
            self.filemode = entry.filemode


@@ 143,28 143,29 @@ def annotate_tree(repo, tree, commit):
def _diffstat_name(delta, anchor):
    if delta.status == pygit2.GIT_DELTA_DELETED:
        return Markup(escape(delta.old_file.path))
    if delta.old_file.path == delta.new_file.path:
    if delta.old_file.raw_path == delta.new_file.raw_path:
        return Markup(
                f"<a href='#{escape(anchor)}{escape(delta.old_file.path)}'>" +
                f"{escape(delta.old_file.path)}" +
                f"<a href='#{escape(anchor)}{escape(delta.old_file.raw_path.decode('utf-8', 'replace'))}'>" +
                f"{escape(delta.old_file.raw_path.decode('utf-8', 'replace'))}" +
                f"</a>")
    # Based on git/diff.c
    pfx_length = 0
    old_path = delta.old_file.path
    new_path = delta.new_file.path
    old_path = delta.old_file.raw_path
    new_path = delta.new_file.raw_path
    for i in range(max(len(old_path), len(new_path))):
        if i >= len(old_path) or i >= len(new_path):
            break
        if old_path[i] != new_path[i]:
            break
        if old_path[i] == '/':
        if old_path[i] == b'/'[0]:
            pfx_length = i + 1
    # TODO: detect common suffix
    if pfx_length != 0:
        return (f"{delta.old_file.path[:pfx_length]}{{" +
            f"{delta.old_file.path[pfx_length:]} =&gt; {delta.new_file.path[pfx_length:]}" +
            f"}}")
    return f"{delta.old_file.path} => {delta.new_file.path}"
        return (f"{delta.old_file.raw_path[:pfx_length].decode('utf-8', 'replace')}{{" +
            f"{delta.old_file.raw_path[pfx_length:].decode('utf-8', 'replace')} =&gt; " +
            f"{delta.new_file.raw_path[pfx_length:].decode('utf-8', 'replace')}}}")
    return (f"{delta.old_file.raw_path.decode('utf-8', 'replace')} => " +
            f"{delta.new_file.raw_path.decode('utf-8', 'replace')}")

def _diffstat_line(delta, patch, anchor):
    name = _diffstat_name(delta, anchor)

M gitsrht/templates/utils.html => gitsrht/templates/utils.html +10 -10
@@ 164,24 164,24 @@ endif %}{% endfor %}
      owner=repo.owner.canonical_name,
      repo=repo.name,
      ref=parent.id.hex,
      path=patch.delta.old_file.path)}}"
   id="{{anchor}}{{patch.delta.old_file.path}}"
      path=patch.delta.old_file.raw_path.decode('utf-8', 'replace'))}}"
   id="{{anchor}}{{patch.delta.old_file.raw_path.decode('utf-8', 'replace')}}"
  {% if target_blank %}
  target="_blank"
  {% endif %}
 >{{patch.delta.old_file.path}}</a>{#
 >{{patch.delta.old_file.raw_path.decode('utf-8', 'replace')}}</a>{#
 #}{% endif %} =&gt; {#
 #}<a
   href="{{url_for("repo.tree",
      owner=repo.owner.canonical_name,
      repo=repo.name,
      ref=commit.id.hex,
      path=patch.delta.new_file.path)}}"
   id="{{anchor}}{{patch.delta.new_file.path}}"
      path=patch.delta.new_file.raw_path.decode('utf-8', 'replace'))}}"
   id="{{anchor}}{{patch.delta.new_file.raw_path.decode('utf-8', 'replace')}}"
  {% if target_blank %}
  target="_blank"
  {% endif %}
 >{{patch.delta.new_file.path}}</a>{#
 >{{patch.delta.new_file.raw_path.decode('utf-8', 'replace')}}</a>{#
 #} <span class="pull-right"><span class="text-success">+{{patch.line_stats[1]}}</span>{#
 #} <span class="text-danger">-{{patch.line_stats[2]}}</span></span>{%
    if patch.delta.old_file.mode != patch.delta.new_file.mode %}{#


@@ 198,7 198,7 @@ endif %}{% endfor %}
    owner=repo.owner.canonical_name,
    repo=repo.name,
    ref=parent.id.hex,
    path=patch.delta.old_file.path)}}#L{{hunk.old_start}}"
    path=patch.delta.old_file.raw_path.decode('utf-8', 'replace'))}}#L{{hunk.old_start}}"
  {% if target_blank %}
  target="_blank"
  {% endif %}


@@ 209,7 209,7 @@ endif %}{% endfor %}
    owner=repo.owner.canonical_name,
    repo=repo.name,
    ref=commit.id.hex,
    path=patch.delta.new_file.path)}}#L{{hunk.new_start}}"
    path=patch.delta.new_file.raw_path.decode('utf-8', 'replace'))}}#L{{hunk.new_start}}"
  {% if target_blank %}
  target="_blank"
  {% endif %}


@@ 220,8 220,8 @@ endif %}{% endfor %}
  "+":"text-success",
  "-":"text-danger",
  }).get(line.origin) or ""}}"><a
    href="#{{anchor}}{{patch.delta.old_file.path}}-{{hunk_index}}-{{loop.index}}"
    id="{{anchor}}{{patch.delta.old_file.path}}-{{hunk_index}}-{{loop.index}}"
    href="#{{anchor}}{{patch.delta.old_file.raw_path.decode('utf-8', 'replace')}}-{{hunk_index}}-{{loop.index}}"
    id="{{anchor}}{{patch.delta.old_file.raw_path.decode('utf-8', 'replace')}}-{{hunk_index}}-{{loop.index}}"
    aria-hidden="true"
    class="lineno"
    style="color: inherit"