From 0ee1887cee4b55527427caf06ee60041dc67213c Mon Sep 17 00:00:00 2001 From: imperosol Date: Wed, 18 Dec 2024 17:11:20 +0100 Subject: [PATCH] fix sanitisation of the csv content --- core/static/bundled/utils/csv.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/core/static/bundled/utils/csv.ts b/core/static/bundled/utils/csv.ts index b4420345f..5f839732a 100644 --- a/core/static/bundled/utils/csv.ts +++ b/core/static/bundled/utils/csv.ts @@ -19,6 +19,16 @@ 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 sanitiseCell(content: string): string { + return `"${content.replace(/"/g, '""')}"`; +} + export const csv = { stringify: (objs: T[], options?: StringifyOptions) => { const columns = options.columns; @@ -26,10 +36,7 @@ export const csv = { .map((obj) => { return columns .map((col) => { - return (getNested(obj, col) ?? "") - .toString() - .replace(/,/g, ",") - .replace(/\n/g, " "); + return sanitiseCell((getNested(obj, col) ?? "").toString()); }) .join(","); }) @@ -37,7 +44,7 @@ export const csv = { if (!options.titleRow) { return content; } - const firstRow = options.titleRow.map((s) => s.replace(/,/g, ",")).join(","); + const firstRow = options.titleRow.map(sanitiseCell).join(","); return `${firstRow}\n${content}`; }, };