admin: don't mangle numeric CSV cells with the formula-injection guard
csvCell() prefixed an apostrophe to any cell whose *string* form starts with =, +, - or @, applied to every column including numeric ones. transactions.total_cents is legitimately negative for a net-Pfand-refund transaction (more deposit returned than drinks bought) — a refund exported as '-600 in that column, which Excel/LibreOffice import as text, so SUM() over the column silently skips it. Whoever reconciles the till against the CSV gets a total too high by the sum of all refunds, exactly the direction that makes a short drawer look correct. Numbers now bypass both the injection guard and the quote-escaping below it — the guard exists for free-text columns that could carry a formula payload, and numbers never contain the characters the escaping handles anyway.
This commit is contained in:
parent
22aa069b35
commit
6d88d34291
1 changed files with 8 additions and 0 deletions
|
|
@ -569,6 +569,14 @@ export function registerAdminRoutes(app: FastifyInstance, db: DB) {
|
|||
|
||||
function csvCell(v: unknown): string {
|
||||
if (v === null || v === undefined) return '';
|
||||
// Numbers (e.g. a negative total_cents from a net-Pfand-refund
|
||||
// transaction) skip both the formula-injection guard and the quote
|
||||
// escaping below — the guard exists for free-text columns that could
|
||||
// contain a formula-injection payload; a real negative number should
|
||||
// stay a real number, not get coerced into text a spreadsheet can no
|
||||
// longer SUM(). Numbers also never contain `,`/`"`/`\n`, so escaping is
|
||||
// moot for them anyway.
|
||||
if (typeof v === 'number') return String(v);
|
||||
let s = String(v);
|
||||
// Neutralise spreadsheet formula injection: a cell starting with one of
|
||||
// these characters is interpreted as a formula by Excel/LibreOffice when
|
||||
|
|
|
|||
Loading…
Reference in a new issue