From 34d304d1b8afbb9fb20f4a00a98e4450e2fa4e55 Mon Sep 17 00:00:00 2001 From: Sergey Kurdin Date: Mon, 23 Jun 2025 15:00:53 -0400 Subject: [PATCH] feat: enhance HTML encoding/decoding with input validation - Improved `toHtmlEncode` to validate string input and added sanitization in `toHtmlDecode` --- .../src/lib/text-transforms.ts | 36 +++++++++++++++---- .../src/locales/lang/en/specailCopyPaste.yaml | 1 + .../src/commands/format_converter_commands.rs | 10 +++--- 3 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 packages/pastebar-app-ui/src/locales/lang/en/specailCopyPaste.yaml diff --git a/packages/pastebar-app-ui/src/lib/text-transforms.ts b/packages/pastebar-app-ui/src/lib/text-transforms.ts index 6c7c49a2..88ed05ee 100644 --- a/packages/pastebar-app-ui/src/lib/text-transforms.ts +++ b/packages/pastebar-app-ui/src/lib/text-transforms.ts @@ -3,6 +3,8 @@ * Organized by categories with enable/disable controls */ +import DOMPurify from 'dompurify' + export interface TextTransform { id: string label: string @@ -123,15 +125,35 @@ const toUrlDecode = (text: string): string => { return text } } -const toHtmlEncode = (text: string): string => { - const div = document.createElement('div') - div.textContent = text - return div.innerHTML + +function toHtmlEncode(str: string): string { + // Ensure the input is a string + if (typeof str !== 'string') { + console.warn('Input to encodeHtmlSpecialChars was not a string:', str) + return '' // Or throw an error, depending on desired behavior + } + + return str.replace(/[&<>"']/g, function (char) { + switch (char) { + case '&': + return '&' // Ampersand + case '<': + return '<' // Less than + case '>': + return '>' // Greater than + case '"': + return '"' // Double quote + case "'": + return ''' // Single quote (apostrophe) + default: + return char // Should not happen with the given regex, but good practice + } + }) } + const toHtmlDecode = (text: string): string => { - const div = document.createElement('div') - div.innerHTML = text - return div.textContent || '' + const sanitized = DOMPurify.sanitize(text, { RETURN_DOM: true }) + return sanitized.textContent || '' } // Transform functions for Text Tools diff --git a/packages/pastebar-app-ui/src/locales/lang/en/specailCopyPaste.yaml b/packages/pastebar-app-ui/src/locales/lang/en/specailCopyPaste.yaml new file mode 100644 index 00000000..c7a3bd1c --- /dev/null +++ b/packages/pastebar-app-ui/src/locales/lang/en/specailCopyPaste.yaml @@ -0,0 +1 @@ +Special Settings: Special Settings diff --git a/src-tauri/src/commands/format_converter_commands.rs b/src-tauri/src/commands/format_converter_commands.rs index 27a16d8e..c6fff83e 100644 --- a/src-tauri/src/commands/format_converter_commands.rs +++ b/src-tauri/src/commands/format_converter_commands.rs @@ -347,11 +347,11 @@ pub async fn format_convert(text: String, conversion_type: String) -> Result(), - conversion_type - ); + // eprintln!( + // "Converting {} with type: {}", + // text.chars().take(50).collect::(), + // conversion_type + // ); match conversion_type.as_str() { "csv_to_json" => csv_to_json(&text).map_err(|e| format!("CSV to JSON conversion failed: {}", e)),