From 28fc3f9e21118812a9cecd04b2af5071a87a0c80 Mon Sep 17 00:00:00 2001 From: sokol Date: Fri, 20 Feb 2026 16:55:34 +0300 Subject: [PATCH] fix: improved JSON validation for comments and placeholders --- src/componets/content/ConfigTemplate.tsx | 58 ++++++++++++++++++++---- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/src/componets/content/ConfigTemplate.tsx b/src/componets/content/ConfigTemplate.tsx index 4324ea3..262b04d 100644 --- a/src/componets/content/ConfigTemplate.tsx +++ b/src/componets/content/ConfigTemplate.tsx @@ -40,14 +40,56 @@ export function ConfigTemplateEditor({ config, onSaved }: ConfigTemplateEditorPr setJsonError(null); return true; } - - // Strip comments (// single-line and /* */ multi-line) and placeholders - const sanitizedValue = value - .replace(/\/\*[\s\S]*?\*\//g, '') // Remove /* */ comments - .replace(/\/\/.*$/gm, '') // Remove // comments - .replace(/@[^@]+@/g, '1'); // Replace placeholders - - JSON.parse(sanitizedValue); + + // Step 1: Remove /* */ multi-line comments (safe, can't appear in strings) + let sanitized = value.replace(/\/\*[\s\S]*?\*\//g, ''); + + // Step 2: Process line by line to handle // comments and placeholders + // Only remove // comments that are OUTSIDE of quoted strings + const lines = sanitized.split('\n'); + const processedLines = lines.map(line => { + // Find // that's outside quotes + // Strategy: split by quotes, only process odd-indexed segments (outside quotes) + let result = ''; + let inQuote = false; + let quoteChar = ''; + + for (let i = 0; i < line.length; i++) { + const char = line[i]; + const prevChar = i > 0 ? line[i - 1] : ''; + + // Check for quote start/end (not escaped) + if ((char === '"' || char === "'") && prevChar !== '\\') { + if (!inQuote) { + inQuote = true; + quoteChar = char; + } else if (char === quoteChar) { + inQuote = false; + quoteChar = ''; + } + result += char; + } + // Check for // comment start (only outside quotes) + else if (!inQuote && char === '/' && line[i + 1] === '/') { + // Rest of line is comment, stop processing + break; + } + else { + result += char; + } + } + + return result; + }); + + sanitized = processedLines.join('\n'); + + // Step 3: Replace unquoted @placeholders@ with dummy values + // Placeholders in JSON values are typically quoted: "@param@" + // We replace all @param@ with 1 (works for both quoted and unquoted) + sanitized = sanitized.replace(/@[^@]+@/g, '1'); + + JSON.parse(sanitized); setJsonError(null); return true; } catch (e) {