fix(preview): improve file content handling
Refined how file content is displayed in the preview, distinguishing and safely handling text, Markdown, and image files. Introduced proper escaping for non-Markdown text files to prevent potential security issues.
This commit is contained in:
parent
a179e2999f
commit
dce9c4d3b0
2 changed files with 18 additions and 7 deletions
|
@ -5,6 +5,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
import base64
|
import base64
|
||||||
import mimetypes
|
import mimetypes
|
||||||
|
import html
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -164,9 +165,15 @@ def preview_file(owner: str, repo: str, file_path: str):
|
||||||
file_content = git.get_file_content(file_path)
|
file_content = git.get_file_content(file_path)
|
||||||
|
|
||||||
content_type, _ = mimetypes.guess_type(file_path)
|
content_type, _ = mimetypes.guess_type(file_path)
|
||||||
is_text = content_type and content_type.startswith("text")
|
|
||||||
|
try:
|
||||||
|
file_content.decode("utf-8")
|
||||||
|
is_text = True
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
is_text = False
|
||||||
|
|
||||||
is_image = content_type and content_type.startswith("image")
|
is_image = content_type and content_type.startswith("image")
|
||||||
is_safe = False
|
is_raw = True
|
||||||
|
|
||||||
if content_type == "text/markdown":
|
if content_type == "text/markdown":
|
||||||
base_url = f"/{owner}/{repo}/raw/main/{'/'.join(file_path.split('/')[:-1])}".rstrip(
|
base_url = f"/{owner}/{repo}/raw/main/{'/'.join(file_path.split('/')[:-1])}".rstrip(
|
||||||
|
@ -175,7 +182,11 @@ def preview_file(owner: str, repo: str, file_path: str):
|
||||||
file_content = RelativeURLRewriter(base_url).convert(
|
file_content = RelativeURLRewriter(base_url).convert(
|
||||||
file_content.decode("utf-8")
|
file_content.decode("utf-8")
|
||||||
)
|
)
|
||||||
is_safe = True
|
is_raw = False
|
||||||
|
|
||||||
|
elif is_text:
|
||||||
|
file_content = file_content.decode("utf-8")
|
||||||
|
file_content = html.escape(file_content)
|
||||||
|
|
||||||
if is_image:
|
if is_image:
|
||||||
file_content = base64.b64encode(file_content).decode("utf-8")
|
file_content = base64.b64encode(file_content).decode("utf-8")
|
||||||
|
@ -188,7 +199,7 @@ def preview_file(owner: str, repo: str, file_path: str):
|
||||||
file_content=file_content,
|
file_content=file_content,
|
||||||
is_text=is_text,
|
is_text=is_text,
|
||||||
is_image=is_image,
|
is_image=is_image,
|
||||||
is_safe=is_safe,
|
is_raw=is_raw,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error previewing file {file_path} in {owner}/{repo}: {e}")
|
logger.error(f"Error previewing file {file_path} in {owner}/{repo}: {e}")
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{% if is_text %}
|
{% if is_text %}
|
||||||
{% if is_safe %}
|
{% if is_raw %}
|
||||||
<div>{{ file_content | safe }}</div>
|
<pre>{{ file_content | safe }}</pre>
|
||||||
{% else %}
|
{% else %}
|
||||||
<pre>{{ file_content }}</pre>
|
<div>{{ file_content | safe }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% elif is_image %}
|
{% elif is_image %}
|
||||||
<img src="data:image/png;base64,{{ file_content }}" class="img-fluid" alt="{{ file_path }}">
|
<img src="data:image/png;base64,{{ file_content }}" class="img-fluid" alt="{{ file_path }}">
|
||||||
|
|
Loading…
Reference in a new issue