diff --git a/docs/docs.html b/docs/docs.html
index c2d82bd..cf198a5 100644
--- a/docs/docs.html
+++ b/docs/docs.html
@@ -343,7 +343,7 @@
escapeFormulae
- If true , field values that begin with = , + , - , or @ , will be prepended with a ' to defend against injection attacks, because Excel and LibreOffice will automatically parse such cells as formulae.
+ If true , field values that begin with = , + , - , @ , \t , or \r , will be prepended with a ' to defend against injection attacks, because Excel and LibreOffice will automatically parse such cells as formulae. You can override those values by setting this option to a regular expression
|
diff --git a/papaparse.js b/papaparse.js
index 057a16c..91de82f 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -367,11 +367,11 @@ License: MIT
_escapedQuote = _config.escapeChar + _quoteChar;
}
- if (typeof _config.escapeFormulae === 'boolean')
- _escapeFormulae = _config.escapeFormulae;
+ if (typeof _config.escapeFormulae === 'boolean' || _config.escapeFormulae instanceof RegExp) {
+ _escapeFormulae = _config.escapeFormulae instanceof RegExp ? _config.escapeFormulae : /^[=+\-@\t\r].*$/;
+ }
}
-
/** The double for loop that iterates the data and writes out a CSV string including header row */
function serialize(fields, data, skipEmptyLines)
{
@@ -444,13 +444,17 @@ License: MIT
if (str.constructor === Date)
return JSON.stringify(str).slice(1, 25);
- if (_escapeFormulae === true && typeof str === "string" && (str.match(/^[=+\-@].*$/) !== null)) {
+ var needsQuotes = false;
+
+ if (_escapeFormulae && typeof str === "string" && _escapeFormulae.test(str)) {
str = "'" + str;
+ needsQuotes = true;
}
var escapedQuoteStr = str.toString().replace(quoteCharRegex, _escapedQuote);
- var needsQuotes = (typeof _quotes === 'boolean' && _quotes)
+ needsQuotes = needsQuotes
+ || _quotes === true
|| (typeof _quotes === 'function' && _quotes(str, col))
|| (Array.isArray(_quotes) && _quotes[col])
|| hasAny(escapedQuoteStr, Papa.BAD_DELIMITERS)
diff --git a/tests/test-cases.js b/tests/test-cases.js
index 0c3a62d..ab806ba 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -1881,7 +1881,7 @@ var UNPARSE_TESTS = [
description: "Escape formulae",
input: [{ "Col1": "=danger", "Col2": "@danger", "Col3": "safe" }, { "Col1": "safe=safe", "Col2": "+danger", "Col3": "-danger, danger" }, { "Col1": "'+safe", "Col2": "'@safe", "Col3": "safe, safe" }],
config: { escapeFormulae: true },
- expected: 'Col1,Col2,Col3\r\n\'=danger,\'@danger,safe\r\nsafe=safe,\'+danger,"\'-danger, danger"\r\n\'+safe,\'@safe,"safe, safe"'
+ expected: 'Col1,Col2,Col3\r\n"\'=danger","\'@danger",safe\r\nsafe=safe,"\'+danger","\'-danger, danger"\r\n\'+safe,\'@safe,"safe, safe"'
},
{
description: "Don't escape formulae by default",
@@ -1898,7 +1898,7 @@ var UNPARSE_TESTS = [
description: "Escape formulae with single-quote quoteChar and escapeChar",
input: [{ "Col1": "=danger", "Col2": "@danger", "Col3": "safe" }, { "Col1": "safe=safe", "Col2": "+danger", "Col3": "-danger, danger" }, { "Col1": "'+safe", "Col2": "'@safe", "Col3": "safe, safe" }],
config: { escapeFormulae: true, quoteChar: "'", escapeChar: "'" },
- expected: 'Col1,Col2,Col3\r\n\'\'=danger,\'\'@danger,safe\r\nsafe=safe,\'\'+danger,\'\'\'-danger, danger\'\r\n\'\'+safe,\'\'@safe,\'safe, safe\''
+ expected: 'Col1,Col2,Col3\r\n\'\'\'=danger\',\'\'\'@danger\',safe\r\nsafe=safe,\'\'\'+danger\',\'\'\'-danger, danger\'\r\n\'\'+safe,\'\'@safe,\'safe, safe\''
},
{
description: "Escape formulae with single-quote quoteChar and escapeChar and forced quotes",
@@ -1906,6 +1906,31 @@ var UNPARSE_TESTS = [
config: { escapeFormulae: true, quotes: true, quoteChar: "'", escapeChar: "'" },
expected: '\'Col1\',\'Col2\',\'Col3\'\r\n\'\'\'=danger\',\'\'\'@danger\',\'safe\'\r\n\'safe=safe\',\'\'\'+danger\',\'\'\'-danger, danger\'\r\n\'\'\'+safe\',\'\'\'@safe\',\'safe, safe\''
},
+ // new escapeFormulae values:
+ {
+ description: "Escape formulae with tab and carriage-return",
+ input: [{ "Col1": "\tdanger", "Col2": "\rdanger,", "Col3": "safe\t\r" }],
+ config: { escapeFormulae: true },
+ expected: 'Col1,Col2,Col3\r\n"\'\tdanger","\'\rdanger,","safe\t\r"'
+ },
+ {
+ description: "Escape formulae with tab and carriage-return, with forced quotes",
+ input: [{ "Col1": " danger", "Col2": "\rdanger,", "Col3": "safe\t\r" }],
+ config: { escapeFormulae: true, quotes: true },
+ expected: '"Col1","Col2","Col3"\r\n"\'\tdanger","\'\rdanger,","safe\t\r"'
+ },
+ {
+ description: "Escape formulae with tab and carriage-return, with single-quote quoteChar and escapeChar",
+ input: [{ "Col1": " danger", "Col2": "\rdanger,", "Col3": "safe, \t\r" }],
+ config: { escapeFormulae: true, quoteChar: "'", escapeChar: "'" },
+ expected: 'Col1,Col2,Col3\r\n\'\'\'\tdanger\',\'\'\'\rdanger,\',\'safe, \t\r\''
+ },
+ {
+ description: "Escape formulae with tab and carriage-return, with single-quote quoteChar and escapeChar and forced quotes",
+ input: [{ "Col1": " danger", "Col2": "\rdanger,", "Col3": "safe, \t\r" }],
+ config: { escapeFormulae: true, quotes: true, quoteChar: "'", escapeChar: "'" },
+ expected: '\'Col1\',\'Col2\',\'Col3\'\r\n\'\'\'\tdanger\',\'\'\'\rdanger,\',\'safe, \t\r\''
+ },
];
describe('Unparse Tests', function() {