fix: Check if binary file in Page Renderers
* Check if binary before rendering using StaticPage resolver * Check if not binary before rendering using TemplatePage resolver
This commit is contained in:
parent
897b8a5b66
commit
9dbaf252f0
3 changed files with 15 additions and 7 deletions
|
|
@ -6,6 +6,7 @@ from werkzeug.wsgi import wrap_file
|
|||
|
||||
import frappe
|
||||
from frappe.website.page_renderers.base_renderer import BaseRenderer
|
||||
from frappe.website.utils import is_binary_file
|
||||
|
||||
UNSUPPORTED_STATIC_PAGE_TYPES = ('html', 'md', 'js', 'xml', 'css', 'txt', 'py', 'json')
|
||||
|
||||
|
|
@ -20,21 +21,20 @@ class StaticPage(BaseRenderer):
|
|||
return
|
||||
for app in frappe.get_installed_apps():
|
||||
file_path = frappe.get_app_path(app, 'www') + '/' + self.path
|
||||
if os.path.isfile(file_path):
|
||||
if os.path.isfile(file_path) and is_binary_file(file_path):
|
||||
self.file_path = file_path
|
||||
|
||||
def can_render(self):
|
||||
return self.is_valid_file_path() and self.file_path
|
||||
|
||||
def is_valid_file_path(self):
|
||||
if ('.' not in self.path):
|
||||
return False
|
||||
extension = self.path.rsplit('.', 1)[-1]
|
||||
if extension in UNSUPPORTED_STATIC_PAGE_TYPES:
|
||||
return False
|
||||
return True
|
||||
|
||||
def render(self):
|
||||
# file descriptor to be left open, closed by middleware
|
||||
f = open(self.file_path, 'rb')
|
||||
response = Response(wrap_file(frappe.local.request.environ, f), direct_passthrough=True)
|
||||
response.mimetype = mimetypes.guess_type(self.file_path)[0] or 'application/octet-stream'
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from frappe.website.router import get_page_info
|
|||
from frappe.website.page_renderers.base_template_page import BaseTemplatePage
|
||||
from frappe.website.router import get_base_template
|
||||
from frappe.website.utils import (extract_comment_tag, extract_title, get_next_link,
|
||||
get_toc, get_frontmatter, cache_html, get_sidebar_items)
|
||||
get_toc, get_frontmatter, is_binary_file, cache_html, get_sidebar_items)
|
||||
|
||||
WEBPAGE_PY_MODULE_PROPERTIES = ("base_template_path", "template", "no_cache", "sitemap", "condition_field")
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ class TemplatePage(BaseTemplatePage):
|
|||
for dirname in folders:
|
||||
search_path = os.path.join(app_path, dirname, self.path)
|
||||
for file_path in self.get_index_path_options(search_path):
|
||||
if os.path.isfile(file_path):
|
||||
if os.path.isfile(file_path) and not is_binary_file(file_path):
|
||||
self.app = app
|
||||
self.app_path = app_path
|
||||
self.file_dir = dirname
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: MIT. See LICENSE
|
||||
import json
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
from functools import wraps
|
||||
from functools import cache, wraps
|
||||
|
||||
import yaml
|
||||
from six import iteritems
|
||||
|
|
@ -511,3 +511,11 @@ def add_preload_headers(response):
|
|||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
@cache
|
||||
def is_binary_file(path):
|
||||
# ref: https://stackoverflow.com/a/7392391/10309266
|
||||
textchars = bytearray({7,8,9,10,12,13,27} | set(range(0x20, 0x100)) - {0x7f})
|
||||
with open(path, 'rb') as f:
|
||||
content = f.read(1024)
|
||||
return bool(content.translate(None, textchars))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue