security: escape formula-like price csv cells

This commit is contained in:
2026-09-06 16:38:46 +03:00
parent 2bdc89286c
commit 529556fd17
2 changed files with 12 additions and 2 deletions
+7 -2
View File
@@ -6,6 +6,11 @@ import { itemStats } from '../../services/analytics';
import confetti from 'canvas-confetti';
const formatPrice = (n) => n == null || !Number.isFinite(Number(n)) ? '—' : Number(n).toLocaleString('tr-TR', {minimumFractionDigits:2, maximumFractionDigits:2}) + ' ₺';
const csvCell = value => {
const text = String(value ?? '');
const safe = /^[=+\-@]/.test(text) ? `'${text}` : text;
return `"${safe.replace(/"/g, '""')}"`;
};
export const PriceAnalysis = () => {
const { tenders } = useApp();
@@ -37,8 +42,8 @@ export const PriceAnalysis = () => {
if (!items.length) return;
const headers = ['Kalem', 'Birim', 'Adet(kayıt)', 'Min', 'Medyan', 'Ortalama', 'Maks'];
const rows = items.map((i) => [
`"${(i.ad || '').replace(/"/g, '""')}"`, i.birim || '', i.count,
i.min.toFixed(2), i.median.toFixed(2), i.avg.toFixed(2), i.max.toFixed(2),
csvCell(i.ad), csvCell(i.birim), csvCell(i.count),
csvCell(i.min.toFixed(2)), csvCell(i.median.toFixed(2)), csvCell(i.avg.toFixed(2)), csvCell(i.max.toFixed(2)),
]);
const csv = 'data:text/csv;charset=utf-8,' + [headers.join(','), ...rows.map((r) => r.join(','))].join('\n');
const link = document.createElement('a');