// URL Parameter Decoding Test Script // Tests the problematic URL with %B character and various decoding methods console.log("=== URL Parameter Decoding Test ===\n"); // The problematic URL from the user's request const problematicUrl = "https://www.romfast.ro/chatbot_maria.html?message=F:%20Header%20(1)%20sectiune%20Company%20(1)%20sectiune%20BankAccount%20(1)%20eroare%20structura:%20grupul%20%27%BankAccount_choice0%27%20ar%20fi%20trebuit%20sa%20apara%20de%20minimum%201%20ori,%20dar%20apare%20efectiv%20de%200%20ori"; console.log("Problematic URL:"); console.log(problematicUrl); console.log(); // Extract the query string const urlObj = new URL(problematicUrl); const queryString = urlObj.search; const messageParam = queryString.match(/message=([^&]*)/)?.[1] || ''; console.log("Extracted message parameter (raw):"); console.log(messageParam); console.log(); // Test Method 1: URLSearchParams (this should fail with the %B issue) console.log("=== Test 1: URLSearchParams method ==="); try { const searchParams = new URLSearchParams(queryString); const decodedMessage1 = searchParams.get('message'); console.log("✅ SUCCESS with URLSearchParams:"); console.log(decodedMessage1); } catch (error) { console.log("❌ FAILED with URLSearchParams:"); console.log("Error:", error.message); } console.log(); // Test Method 2: decodeURIComponent (this should also fail) console.log("=== Test 2: decodeURIComponent method ==="); try { const decodedMessage2 = decodeURIComponent(messageParam); console.log("✅ SUCCESS with decodeURIComponent:"); console.log(decodedMessage2); } catch (error) { console.log("❌ FAILED with decodeURIComponent:"); console.log("Error:", error.message); } console.log(); // Test Method 3: Manual decoding with character replacement (current fallback method) console.log("=== Test 3: Manual decoding with replacement ==="); try { let manualDecoded = messageParam .replace(/\+/g, ' ') .replace(/%20/g, ' ') .replace(/%27/g, "'") .replace(/%28/g, "(") .replace(/%29/g, ")") .replace(/%3A/g, ":") .replace(/%2C/g, ",") .replace(/%([\dA-Fa-f])/g, '$1') // This line is problematic - replaces %B with B .replace(/%/g, ''); // Removes remaining % console.log("✅ SUCCESS with manual decoding:"); console.log(manualDecoded); console.log("⚠️ NOTE: This method corrupts %B sequences!"); } catch (error) { console.log("❌ FAILED with manual decoding:"); console.log("Error:", error.message); } console.log(); // Test Method 4: Improved manual decoding (recommended fix) console.log("=== Test 4: Improved manual decoding (RECOMMENDED) ==="); try { // First, handle known safe replacements let improvedDecoded = messageParam .replace(/\+/g, ' ') .replace(/%20/g, ' ') .replace(/%27/g, "'") .replace(/%28/g, "(") .replace(/%29/g, ")") .replace(/%3A/g, ":") .replace(/%2C/g, ","); // Then handle invalid sequences by removing them entirely or replacing with safe characters // %B is not a valid URL encoding (should be %0B for vertical tab or something else) improvedDecoded = improvedDecoded .replace(/%[^0-9A-Fa-f]/g, '') // Remove invalid % sequences that don't have valid hex .replace(/%[0-9A-Fa-f]$/g, '') // Remove incomplete % sequences at end .replace(/%([0-9A-Fa-f])(?![0-9A-Fa-f])/g, '$1'); // Convert single hex digit sequences console.log("✅ SUCCESS with improved manual decoding:"); console.log(improvedDecoded); } catch (error) { console.log("❌ FAILED with improved manual decoding:"); console.log("Error:", error.message); } console.log(); // Test Method 5: Safe decoding with chunk processing console.log("=== Test 5: Safe chunk-by-chunk decoding ==="); try { function safeDecodeURIComponent(str) { // Split by % and process each chunk const chunks = str.split('%'); let result = chunks[0]; // First chunk is never encoded for (let i = 1; i < chunks.length; i++) { const chunk = chunks[i]; if (chunk.length >= 2) { const hexCode = chunk.substring(0, 2); const rest = chunk.substring(2); // Check if it's a valid hex code if (/^[0-9A-Fa-f]{2}$/.test(hexCode)) { try { result += decodeURIComponent('%' + hexCode) + rest; } catch (e) { // If decoding fails, keep the original result += '%' + chunk; } } else { // Invalid hex code, keep as is result += '%' + chunk; } } else { // Incomplete code, keep as is result += '%' + chunk; } } return result; } const safeDecoded = safeDecodeURIComponent(messageParam); console.log("✅ SUCCESS with safe chunk decoding:"); console.log(safeDecoded); } catch (error) { console.log("❌ FAILED with safe chunk decoding:"); console.log("Error:", error.message); } console.log(); // Analysis of the %B issue console.log("=== Analysis of the %B issue ==="); console.log("The sequence '%B' in the URL is problematic because:"); console.log("1. It's not a valid URL encoding (missing second hex digit)"); console.log("2. URLSearchParams and decodeURIComponent expect %XX format"); console.log("3. %B should probably be %0B (vertical tab) or %42 (letter B) or escaped as %25B"); console.log(); // Show where the issue occurs in the original message const problemIndex = messageParam.indexOf('%B'); if (problemIndex !== -1) { console.log("The %B sequence appears at position:", problemIndex); console.log("Context around %B:"); const start = Math.max(0, problemIndex - 20); const end = Math.min(messageParam.length, problemIndex + 20); console.log("...", messageParam.substring(start, end), "..."); console.log(" ", " ".repeat(problemIndex - start) + "^^^ HERE"); } console.log(); console.log("=== Recommended Solution ==="); console.log("Update the getUrlParameter function in chatbot_maria.html to use Method 5 (Safe chunk-by-chunk decoding)"); console.log("This will handle invalid URL encoding sequences gracefully without throwing errors.");