249 lines
10 KiB
HTML
249 lines
10 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>URL Parameter Decoding Test</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
margin: 20px;
|
|
background: #f5f5f5;
|
|
}
|
|
.test-container {
|
|
background: white;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
margin-bottom: 20px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
}
|
|
.success { color: #28a745; }
|
|
.error { color: #dc3545; }
|
|
.warning { color: #ffc107; }
|
|
.code {
|
|
background: #f8f9fa;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
font-family: monospace;
|
|
border-left: 4px solid #007bff;
|
|
margin: 10px 0;
|
|
}
|
|
.result {
|
|
background: #e9ecef;
|
|
padding: 15px;
|
|
border-radius: 4px;
|
|
margin: 10px 0;
|
|
word-break: break-word;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>URL Parameter Decoding Test</h1>
|
|
<p>Testing the problematic URL with %B character that causes "URI malformed" errors.</p>
|
|
|
|
<div class="test-container">
|
|
<h2>Test URL</h2>
|
|
<div class="code" id="testUrl"></div>
|
|
</div>
|
|
|
|
<div class="test-container">
|
|
<h2>Current Implementation (from chatbot_maria.html)</h2>
|
|
<div id="currentResult"></div>
|
|
</div>
|
|
|
|
<div class="test-container">
|
|
<h2>Improved Implementation (Recommended Fix)</h2>
|
|
<div id="improvedResult"></div>
|
|
</div>
|
|
|
|
<div class="test-container">
|
|
<h2>Comparison</h2>
|
|
<div id="comparison"></div>
|
|
</div>
|
|
|
|
<script>
|
|
// The problematic URL
|
|
const testUrl = "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";
|
|
|
|
document.getElementById('testUrl').textContent = testUrl;
|
|
|
|
// Simulate the URL by setting location.search
|
|
const mockSearch = "?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";
|
|
|
|
// Current implementation (from chatbot_maria.html)
|
|
function getCurrentUrlParameter(name) {
|
|
try {
|
|
// Simulate URLSearchParams test first
|
|
const urlParams = new URLSearchParams(mockSearch);
|
|
const value = urlParams.get(name);
|
|
|
|
if (value === null) {
|
|
return '';
|
|
}
|
|
|
|
console.log("Parametru decodat cu URLSearchParams:", value);
|
|
return value;
|
|
} catch (error) {
|
|
console.error("Eroare cu URLSearchParams:", error);
|
|
|
|
// Fallback la metoda manuală cu curățare agresivă
|
|
try {
|
|
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
|
|
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
|
|
var results = regex.exec(mockSearch);
|
|
|
|
if (results === null) {
|
|
return '';
|
|
}
|
|
|
|
let rawValue = results[1];
|
|
console.log("Valoare brută din URL (fallback):", rawValue);
|
|
|
|
// Înlocuiește secvențele problematice manual
|
|
let cleaned = rawValue
|
|
.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!
|
|
.replace(/%/g, ''); // Elimină orice % rămas
|
|
|
|
console.log("Parametru curățat manual:", cleaned);
|
|
return cleaned;
|
|
} catch (fallbackError) {
|
|
console.error("Eroare și la fallback:", fallbackError);
|
|
return '';
|
|
}
|
|
}
|
|
}
|
|
|
|
// Improved implementation (recommended fix)
|
|
function getImprovedUrlParameter(name) {
|
|
try {
|
|
// First try URLSearchParams
|
|
const urlParams = new URLSearchParams(mockSearch);
|
|
const value = urlParams.get(name);
|
|
|
|
if (value !== null) {
|
|
console.log("SUCCESS with URLSearchParams:", value);
|
|
return value;
|
|
}
|
|
|
|
return '';
|
|
} catch (error) {
|
|
console.log("URLSearchParams failed, using safe fallback:", error.message);
|
|
|
|
// Safe fallback with chunk processing
|
|
try {
|
|
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
|
|
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
|
|
var results = regex.exec(mockSearch);
|
|
|
|
if (results === null) {
|
|
return '';
|
|
}
|
|
|
|
let rawValue = results[1];
|
|
|
|
// Safe decode function
|
|
function safeDecodeURIComponent(str) {
|
|
// First handle common safe replacements
|
|
str = str.replace(/\+/g, ' ');
|
|
|
|
// Then process % sequences chunk by 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 (this handles %B)
|
|
result += '%' + chunk;
|
|
}
|
|
} else {
|
|
// Incomplete code, keep as is
|
|
result += '%' + chunk;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
const decoded = safeDecodeURIComponent(rawValue);
|
|
console.log("Safe decode result:", decoded);
|
|
return decoded;
|
|
|
|
} catch (fallbackError) {
|
|
console.error("Safe fallback also failed:", fallbackError);
|
|
return '';
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test both implementations
|
|
function runTests() {
|
|
const currentResultDiv = document.getElementById('currentResult');
|
|
const improvedResultDiv = document.getElementById('improvedResult');
|
|
const comparisonDiv = document.getElementById('comparison');
|
|
|
|
// Test current implementation
|
|
try {
|
|
const currentResult = getCurrentUrlParameter('message');
|
|
currentResultDiv.innerHTML = `
|
|
<div class="success">✅ Current implementation succeeded</div>
|
|
<div class="result"><strong>Result:</strong><br>${currentResult}</div>
|
|
`;
|
|
} catch (error) {
|
|
currentResultDiv.innerHTML = `
|
|
<div class="error">❌ Current implementation failed</div>
|
|
<div class="result"><strong>Error:</strong><br>${error.message}</div>
|
|
`;
|
|
}
|
|
|
|
// Test improved implementation
|
|
try {
|
|
const improvedResult = getImprovedUrlParameter('message');
|
|
improvedResultDiv.innerHTML = `
|
|
<div class="success">✅ Improved implementation succeeded</div>
|
|
<div class="result"><strong>Result:</strong><br>${improvedResult}</div>
|
|
`;
|
|
} catch (error) {
|
|
improvedResultDiv.innerHTML = `
|
|
<div class="error">❌ Improved implementation failed</div>
|
|
<div class="result"><strong>Error:</strong><br>${error.message}</div>
|
|
`;
|
|
}
|
|
|
|
// Show comparison
|
|
comparisonDiv.innerHTML = `
|
|
<h3>Key Differences:</h3>
|
|
<ul>
|
|
<li><strong>Current:</strong> Uses URLSearchParams first, falls back to aggressive manual replacement that corrupts %B</li>
|
|
<li><strong>Improved:</strong> Uses URLSearchParams first, falls back to safe chunk-by-chunk processing that preserves invalid sequences</li>
|
|
<li><strong>Issue:</strong> The %B in the URL is not valid URL encoding (should be %0B or %42)</li>
|
|
<li><strong>Solution:</strong> The improved version handles invalid sequences gracefully</li>
|
|
</ul>
|
|
<h3>Expected Message Content:</h3>
|
|
<div class="code">F: Header (1) sectiune Company (1) sectiune BankAccount (1) eroare structura: grupul '%BankAccount_choice0' ar fi trebuit sa apara de minimum 1 ori, dar apare efectiv de 0 ori</div>
|
|
`;
|
|
}
|
|
|
|
// Run tests when page loads
|
|
window.addEventListener('load', runTests);
|
|
</script>
|
|
</body>
|
|
</html> |