Gospel x Internet CSV export: a value starting with TAB or CR is neutralised too, and the model check asserts it
This commit is contained in:
parent
56b53c2a92
commit
d247ec9d1b
2 changed files with 9 additions and 1 deletions
|
|
@ -111,6 +111,12 @@ const csv = M.buildCsv(
|
|||
const lines = csv.split('\r\n')
|
||||
ok(lines[0] === 'A,B' && lines[lines.length - 1].startsWith('# test') && (POISON ? false : true), 'CSV header first, provenance last')
|
||||
ok(lines[1].startsWith('"\'=HYPERLINK') && lines[1].endsWith('"Arabic, Mesopotamian"'), 'CSV neutralises = and quotes an embedded comma')
|
||||
// A spreadsheet can strip a leading TAB or CR and then read the = after it as a formula (OWASP's list), so those
|
||||
// two lead characters are neutralised too, the same as the library's useCsvExport.
|
||||
const tabCell = M.buildCsv([{ a: '\t=cmd' }], [{ key: 'a', header: 'A' }]).split('\r\n')[1]
|
||||
ok(tabCell === "'\t=cmd", `CSV neutralises a leading TAB (got ${JSON.stringify(tabCell)})`)
|
||||
const crCell = M.buildCsv([{ a: '\r=cmd' }], [{ key: 'a', header: 'A' }]).slice('A\r\n'.length)
|
||||
ok(crCell === '"\'\r=cmd"', `CSV neutralises a leading CR, then quotes it (got ${JSON.stringify(crCell)})`)
|
||||
|
||||
// 9. platforms: the preset is "nothing in own language, 60%+ online" (the 220), and the app chart counts
|
||||
// each COUNTRY once, with countries outside Apple's feed kept as "not measured", never dropped
|
||||
|
|
|
|||
|
|
@ -301,7 +301,9 @@ export function sortRows(rows, { key, dir = 1 } = {}) {
|
|||
export function buildCsv(rows, columns, { provenance = '' } = {}) {
|
||||
const esc = (v) => {
|
||||
let s = v === null || v === undefined ? '' : String(v)
|
||||
if (/^[=+\-@]/.test(s)) s = "'" + s
|
||||
// A leading = + - @ TAB or CR is neutralised: a spreadsheet can strip a leading TAB/CR and then read the =
|
||||
// after it as a formula (OWASP's list). The same guard as the library's useCsvExport.
|
||||
if (/^[=+\-@\t\r]/.test(s)) s = "'" + s
|
||||
if (/[",\n\r]/.test(s)) s = '"' + s.replace(/"/g, '""') + '"'
|
||||
return s
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue