From f39737bfabfac43bddc4b58f34f5b671dda38a42 Mon Sep 17 00:00:00 2001 From: Ejaaz Khan Date: Tue, 6 May 2025 16:34:30 +0530 Subject: [PATCH 1/2] fix: don't allow attaching an file invalid url --- frappe/core/doctype/file/file.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index 5cbef2db16..b0bab71e73 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -199,11 +199,17 @@ class File(Document): return frappe.get_all("File", filters={"folder": self.name}, pluck="name") def validate_file_path(self): + full_path = self.get_full_path() if self.is_remote_file: + # Validate whether the file URL is valid by attempting to open it. + try: + open(full_path, mode="rb") + except FileNotFoundError: + frappe.throw("No such file or directory: {}".format(full_path), FileNotFoundError) return base_path = os.path.realpath(get_files_path(is_private=self.is_private)) - if not os.path.realpath(self.get_full_path()).startswith(base_path): + if not os.path.realpath(full_path).startswith(base_path): frappe.throw( _("The File URL you've entered is incorrect"), title=_("Invalid File URL"), From 19959fbf453c3d3b39840bc118bee5389004c30d Mon Sep 17 00:00:00 2001 From: Ejaaz Khan Date: Mon, 12 May 2025 16:14:55 +0530 Subject: [PATCH 2/2] fix: revert python changes and do via js --- frappe/core/doctype/file/file.py | 8 +----- .../js/frappe/file_uploader/FileUploader.vue | 25 ++++++++++++++++++- frappe/www/printview.py | 3 ++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index b0bab71e73..5cbef2db16 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -199,17 +199,11 @@ class File(Document): return frappe.get_all("File", filters={"folder": self.name}, pluck="name") def validate_file_path(self): - full_path = self.get_full_path() if self.is_remote_file: - # Validate whether the file URL is valid by attempting to open it. - try: - open(full_path, mode="rb") - except FileNotFoundError: - frappe.throw("No such file or directory: {}".format(full_path), FileNotFoundError) return base_path = os.path.realpath(get_files_path(is_private=self.is_private)) - if not os.path.realpath(full_path).startswith(base_path): + if not os.path.realpath(self.get_full_path()).startswith(base_path): frappe.throw( _("The File URL you've entered is incorrect"), title=_("Invalid File URL"), diff --git a/frappe/public/js/frappe/file_uploader/FileUploader.vue b/frappe/public/js/frappe/file_uploader/FileUploader.vue index 9d53d9f776..af92f96a5f 100644 --- a/frappe/public/js/frappe/file_uploader/FileUploader.vue +++ b/frappe/public/js/frappe/file_uploader/FileUploader.vue @@ -521,14 +521,37 @@ function upload_via_file_browser() { library_file_name: selected_file.value, }); } -function upload_via_web_link() { + +async function validate_html_url(url) { + try { + let response = await fetch(url, { method: "HEAD" }); + let contentType = response.headers.get("Content-Type"); + + if (contentType && contentType.includes("text/html")) { + return false; + } + } catch (error) { + console.log("Error fetching URL:", error); + } + return true; +} + +async function upload_via_web_link() { let file_url = web_link.value.url; if (!file_url) { frappe.msgprint(__("Invalid URL")); close_dialog.value = true; return Promise.reject(); } + file_url = decodeURI(file_url); + const is_valid = await validate_html_url(file_url); + + if (!is_valid) { + frappe.msgprint(__("Invalid or unsupported URL")); + return Promise.reject(); + } + close_dialog.value = true; return upload_file({ file_url, diff --git a/frappe/www/printview.py b/frappe/www/printview.py index cb973d785e..a1d97d30f4 100644 --- a/frappe/www/printview.py +++ b/frappe/www/printview.py @@ -78,7 +78,8 @@ def get_context(context) -> PrintContext: body = get_html( doctype=frappe.form_dict.doctype, name=frappe.form_dict.name, print_format=print_format.name ) - body += trigger_print_script + if cint(frappe.form_dict.trigger_print): + body += trigger_print_script else: body = get_rendered_template( doc,