chore: Improve CSV output sanitization (#8682)

This commit is contained in:
Tom Moor
2025-03-12 20:23:48 -04:00
committed by GitHub
parent 8041d9c3bd
commit 6ea4ce72ec
3 changed files with 65 additions and 1 deletions
+32
View File
@@ -0,0 +1,32 @@
import { CSVHelper } from "./csv";
describe("CSVHelper", () => {
describe("sanitizeValue", () => {
it("should leave a value unchanged", () => {
const value = "Hello, World!";
const sanitizedValue = CSVHelper.sanitizeValue(value);
expect(sanitizedValue).toBe(value);
});
it("should escape formula trigger character", () => {
expect(CSVHelper.sanitizeValue("@1x2")).toBe(`'@1x2`);
expect(CSVHelper.sanitizeValue("=1x2")).toBe(`'=1x2`);
expect(CSVHelper.sanitizeValue("1x2")).toBe(`'1x2`);
expect(CSVHelper.sanitizeValue("≠1x2")).toBe(`'≠1x2`);
expect(CSVHelper.sanitizeValue("+1x2")).toBe(`'+1x2`);
expect(CSVHelper.sanitizeValue("∑1x2")).toBe(`'∑1x2`);
});
it("should remove control characters", () => {
expect(CSVHelper.sanitizeValue("\t1x2")).toBe(`1x2`);
});
it("should remove zero-width characters", () => {
expect(CSVHelper.sanitizeValue("\u200B1x2")).toBe(`1x2`);
});
it("should remove whitespace characters", () => {
expect(CSVHelper.sanitizeValue("\u200B1x2")).toBe(`1x2`);
});
});
});
+31
View File
@@ -0,0 +1,31 @@
/* eslint-disable no-control-regex */
/**
* Helper class for CSV operations.
*/
export class CSVHelper {
/**
* Sanitizes a value for CSV output.
*
* @param value The value to sanitize.
* @returns The sanitized value.
*/
public static sanitizeValue(value: string): string {
if (!value) {
return "";
}
return (
value
.toString()
// Formula triggers
.replace(/^([+\-=@<>±÷×])/u, "'$1")
// Control characters
.replace(/[\u0000-\u001F\u007F-\u009F]/gu, "")
// Zero-width spaces
.replace(/[\u200B-\u200D\uFEFF]/g, "")
// Bidirectional control
.replace(/[\u202A-\u202E\u2066-\u2069]/g, "")
);
}
}