namespace SharepointToolbox.Services.Export; /// /// CSV field sanitization. Adds RFC 4180 quoting plus formula-injection /// protection: Excel and other spreadsheet apps treat cells starting with /// '=', '+', '-', '@', tab, or CR as formulas. Prefixing with a single /// quote neutralizes the formula while remaining readable. /// internal static class CsvSanitizer { /// /// Escapes a value for inclusion in a CSV row. Always wraps in double /// quotes. Doubles internal quotes per RFC 4180. Prepends an apostrophe /// when the value begins with a character a spreadsheet would evaluate. /// public static string Escape(string? value) { if (string.IsNullOrEmpty(value)) return "\"\""; var safe = NeutralizeFormulaPrefix(value).Replace("\"", "\"\""); return $"\"{safe}\""; } /// /// Minimal quoting variant: only wraps in quotes when the value contains /// a delimiter, quote, or newline. Still guards against formula injection. /// public static string EscapeMinimal(string? value) { if (string.IsNullOrEmpty(value)) return string.Empty; var safe = NeutralizeFormulaPrefix(value); if (safe.Contains(',') || safe.Contains('"') || safe.Contains('\n') || safe.Contains('\r')) return $"\"{safe.Replace("\"", "\"\"")}\""; return safe; } private static string NeutralizeFormulaPrefix(string value) { if (value.Length == 0) return value; char first = value[0]; if (first == '=' || first == '+' || first == '-' || first == '@' || first == '\t' || first == '\r') { return "'" + value; } return value; } }