fix(ui): jsAttrEsc for inline onclick handlers — apostrophe in product_name broke SKU mapping modal
HTML parser decodes ' back to ' inside onclick="..." before the JS parser
runs, so esc() left inline handlers vulnerable: product names containing an
apostrophe terminated the JS string literal ("missing ) after argument list").
New jsAttrEsc() escapes for JS-string-inside-HTML-attribute (\\, ', \n first;
then &, ", <, >). Applied to all inline onclick sites that interpolate
user-controlled sku/product_name/codmat: shared.js detail modal (lines
879/939), missing_skus.html (4 sites), mappings.js (3 sites).
Cache-bust: shared.js v49→50, mappings.js v17→18.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -109,12 +109,12 @@ function renderTable(mappings, showDeleted) {
|
||||
const inactiveStyle = !m.activ && !m.sters ? 'opacity:0.6;' : '';
|
||||
html += `<div class="flat-row" style="background:var(--surface-raised);font-weight:600;border-top:1px solid var(--border);${inactiveStyle}">
|
||||
<span class="${m.activ ? 'dot dot-green' : 'dot dot-yellow'}" style="cursor:${m.sters ? 'default' : 'pointer'}"
|
||||
${m.sters ? '' : `onclick="event.stopPropagation();toggleActive('${esc(m.sku)}', '${esc(m.codmat)}', ${m.activ})"`}
|
||||
${m.sters ? '' : `onclick="event.stopPropagation();toggleActive('${jsAttrEsc(m.sku)}', '${jsAttrEsc(m.codmat)}', ${m.activ})"`}
|
||||
title="${m.activ ? 'Activ' : 'Inactiv'}"></span>
|
||||
<strong class="me-1 text-nowrap">${esc(m.sku)}</strong>${kitBadge}
|
||||
<span class="grow truncate text-muted" style="font-size:0.875rem">${esc(m.product_name || '')}</span>
|
||||
${m.sters
|
||||
? `<button class="btn btn-sm btn-outline-success" onclick="event.stopPropagation();restoreMapping('${esc(m.sku)}', '${esc(m.codmat)}')" title="Restaureaza" style="padding:0.1rem 0.4rem"><i class="bi bi-arrow-counterclockwise"></i></button>`
|
||||
? `<button class="btn btn-sm btn-outline-success" onclick="event.stopPropagation();restoreMapping('${jsAttrEsc(m.sku)}', '${jsAttrEsc(m.codmat)}')" title="Restaureaza" style="padding:0.1rem 0.4rem"><i class="bi bi-arrow-counterclockwise"></i></button>`
|
||||
: `<button class="context-menu-trigger" data-sku="${esc(m.sku)}" data-codmat="${esc(m.codmat)}" data-cantitate="${m.cantitate_roa}">⋮</button>`
|
||||
}
|
||||
</div>`;
|
||||
@@ -128,7 +128,7 @@ function renderTable(mappings, showDeleted) {
|
||||
<span class="grow truncate text-muted" style="font-size:0.85rem">${esc(m.denumire || '')}</span>
|
||||
<span class="text-nowrap" style="font-size:0.875rem">
|
||||
<span class="${m.sters ? '' : 'editable'}" style="cursor:${m.sters ? 'default' : 'pointer'}"
|
||||
${m.sters ? '' : `onclick="editFlatValue(this, '${esc(m.sku)}', '${esc(m.codmat)}', 'cantitate_roa', ${m.cantitate_roa})"`}>x${m.cantitate_roa}</span>${isKitRow ? kitPriceSlot : inlinePrice}
|
||||
${m.sters ? '' : `onclick="editFlatValue(this, '${jsAttrEsc(m.sku)}', '${jsAttrEsc(m.codmat)}', 'cantitate_roa', ${m.cantitate_roa})"`}>x${m.cantitate_roa}</span>${isKitRow ? kitPriceSlot : inlinePrice}
|
||||
</span>
|
||||
</div>`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user