security: escape formula-like price csv cells
This commit is contained in:
@@ -1365,6 +1365,11 @@ Taslak türü seçicisine erişilebilir ad eklendi. Üretim derlemesi geçti. Ö
|
|||||||
- Fiyat analizi CSV dışa aktarımında min/medyan/ortalama/maksimum değerleri artık yuvarlanıp kuruş kaybetmiyor; iki ondalık basamakla aynı ham istatistikleri taşıyor.
|
- Fiyat analizi CSV dışa aktarımında min/medyan/ortalama/maksimum değerleri artık yuvarlanıp kuruş kaybetmiyor; iki ondalık basamakla aynı ham istatistikleri taşıyor.
|
||||||
- Ekrandaki yuvarlanmış grafik sunumu korunuyor; indirilen rapor hesaplama denetimi için daha hassas değer içeriyor. 283 test ve build başarılı. CSV’nin gerçek tarayıcıda indirilip açılması henüz doğrulanmadı; genel plan açık.
|
- Ekrandaki yuvarlanmış grafik sunumu korunuyor; indirilen rapor hesaplama denetimi için daha hassas değer içeriyor. 283 test ve build başarılı. CSV’nin gerçek tarayıcıda indirilip açılması henüz doğrulanmadı; genel plan açık.
|
||||||
|
|
||||||
|
### 2026-09-06 — Fiyat analizi CSV formül güvenliği
|
||||||
|
|
||||||
|
- CSV dışa aktarımında ürün adı, birim ve diğer hücreler artık Excel formülü başlangıç karakterlerine karşı kaçışlanıyor; `=`, `+`, `-`, `@` ile başlayan kaynak metinler çalışma kitabı formülü olarak çalıştırılmıyor.
|
||||||
|
- Tüm alanlar tırnaklanıp çift tırnaklar kaçışlanıyor; kuruş hassasiyeti korunuyor. 283 test ve build başarılı. CSV’nin gerçek Excel/LibreOffice açılış kabulü henüz yapılmadı; genel plan açık.
|
||||||
|
|
||||||
### 2026-09-06 — Belge son kullanma tarihi doğrulaması
|
### 2026-09-06 — Belge son kullanma tarihi doğrulaması
|
||||||
|
|
||||||
- Belge deposundaki son kullanma tarihi göstergesi artık yalnız geçerli ISO günlerini hesaplıyor. Bozuk veya yuvarlanabilir bir tarih sessizce gün hesabına girmiyor; kullanıcıya “Tarih doğrulanmalı” uyarısı gösteriliyor.
|
- Belge deposundaki son kullanma tarihi göstergesi artık yalnız geçerli ISO günlerini hesaplıyor. Bozuk veya yuvarlanabilir bir tarih sessizce gün hesabına girmiyor; kullanıcıya “Tarih doğrulanmalı” uyarısı gösteriliyor.
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ import { itemStats } from '../../services/analytics';
|
|||||||
import confetti from 'canvas-confetti';
|
import confetti from 'canvas-confetti';
|
||||||
|
|
||||||
const formatPrice = (n) => n == null || !Number.isFinite(Number(n)) ? '—' : Number(n).toLocaleString('tr-TR', {minimumFractionDigits:2, maximumFractionDigits:2}) + ' ₺';
|
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 = () => {
|
export const PriceAnalysis = () => {
|
||||||
const { tenders } = useApp();
|
const { tenders } = useApp();
|
||||||
@@ -37,8 +42,8 @@ export const PriceAnalysis = () => {
|
|||||||
if (!items.length) return;
|
if (!items.length) return;
|
||||||
const headers = ['Kalem', 'Birim', 'Adet(kayıt)', 'Min', 'Medyan', 'Ortalama', 'Maks'];
|
const headers = ['Kalem', 'Birim', 'Adet(kayıt)', 'Min', 'Medyan', 'Ortalama', 'Maks'];
|
||||||
const rows = items.map((i) => [
|
const rows = items.map((i) => [
|
||||||
`"${(i.ad || '').replace(/"/g, '""')}"`, i.birim || '', i.count,
|
csvCell(i.ad), csvCell(i.birim), csvCell(i.count),
|
||||||
i.min.toFixed(2), i.median.toFixed(2), i.avg.toFixed(2), i.max.toFixed(2),
|
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 csv = 'data:text/csv;charset=utf-8,' + [headers.join(','), ...rows.map((r) => r.join(','))].join('\n');
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
|
|||||||
Reference in New Issue
Block a user