From 6953eaa9d06b9fa82fb986a974e27d7478287b32 Mon Sep 17 00:00:00 2001 From: imperosol Date: Wed, 18 Dec 2024 17:11:20 +0100 Subject: [PATCH] fix sanitization of the csv content --- core/static/bundled/utils/csv.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/core/static/bundled/utils/csv.ts b/core/static/bundled/utils/csv.ts index b4420345..df1a5ebf 100644 --- a/core/static/bundled/utils/csv.ts +++ b/core/static/bundled/utils/csv.ts @@ -19,6 +19,15 @@ function getNested(obj: T, key: NestedKeyOf) { return res; } +/** + * Convert the content the string to make sure it won't break + * the resulting csv. + * cf. https://en.wikipedia.org/wiki/Comma-separated_values#Basic_rules + */ +function sanitizeCell(content: string): string { + return `"${content.replace(/"/g, '""')}"`; +} + export const csv = { stringify: (objs: T[], options?: StringifyOptions) => { const columns = options.columns; @@ -26,10 +35,7 @@ export const csv = { .map((obj) => { return columns .map((col) => { - return (getNested(obj, col) ?? "") - .toString() - .replace(/,/g, ",") - .replace(/\n/g, " "); + return sanitizeCell((getNested(obj, col) ?? "").toString()); }) .join(","); }) @@ -37,7 +43,7 @@ export const csv = { if (!options.titleRow) { return content; } - const firstRow = options.titleRow.map((s) => s.replace(/,/g, ",")).join(","); + const firstRow = options.titleRow.map(sanitizeCell).join(","); return `${firstRow}\n${content}`; }, };