Skip to content

Commit 2cf50f1

Browse files
nahzzknownasilya
authored andcommitted
fix: backslash value not escaped properly (#202) (#204)
1 parent 8fd7aaf commit 2cf50f1

File tree

7 files changed

+53
-8
lines changed

7 files changed

+53
-8
lines changed

lib/json2csv.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ function createColumnContent(params, str) {
257257
}
258258

259259
if (typeof val === 'object') {
260-
// In some cases (e.g. val is a Date), stringifiedElement is already a quoted string.
260+
// In some cases (e.g. val is a Date), stringifiedElement is already a quoted string.
261261
// Strip the leading and trailing quotes if so, so we don't end up double-quoting it
262262
stringifiedElement = replaceQuotationMarks(stringifiedElement, '');
263263

@@ -278,6 +278,10 @@ function createColumnContent(params, str) {
278278
stringifiedElement = '"="' + stringifiedElement + '""';
279279
}
280280

281+
//Replace single quotes with double quotes. Single quotes are preceeded by
282+
//a backslash, and it's not at the end of the stringifiedElement.
283+
stringifiedElement = stringifiedElement.replace(/(\\")(?=.)/g, params.doubleQuotes);
284+
281285
line += stringifiedElement;
282286
}
283287

@@ -286,13 +290,10 @@ function createColumnContent(params, str) {
286290

287291
//remove last delimeter by its length
288292
line = line.substring(0, line.length - params.del.length);
289-
//Replace single quotes with double quotes. Single quotes are preceeded by
290-
//a backslash. Be careful not to remove backslash content from the string.
291-
line = line.split('\\\\').map(function (portion) {
292-
return portion.replace(/\\"/g, params.doubleQuotes);
293-
}).join('\\\\');
293+
294294
//Remove the final excess backslashes from the stringified value.
295-
line = line.replace(/\\\\/g, '\\');
295+
line = line.replace(/\\\\/g,'\\');
296+
296297
//If header exists, add it, otherwise, print only content
297298
if (str !== '') {
298299
str += eol + line + params.eol;

test/fixtures/csv/backslashAtEnd.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"a string"
2+
"with a description"
3+
"with a description and ""quotes and backslash\"
4+
"with a description and ""quotes and backslash\"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"uuid","title","id"
2+
"xxxx-yyyy","$25 something $50 \","someId"
3+
"xxxx-yyyy","$25 something $50 \","someId"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[
2+
{"a string": "with a description"},
3+
{"a string": "with a description and \"quotes and backslash\\"},
4+
{"a string": "with a description and \"quotes and backslash\\\\"}
5+
]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[
2+
{"uuid": "xxxx-yyyy", "title": "$25 something $50 \\", "id":"someId"},
3+
{"uuid": "xxxx-yyyy", "title": "$25 something $50 \\\\", "id":"someId"}
4+
]

test/helpers/load-fixtures.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ var fixtures = [
99
'withoutQuotes',
1010
'withNotExistField',
1111
'quotes',
12+
'backslashAtEnd',
13+
'backslashAtEndInMiddleColumn',
1214
'date',
1315
'selected',
1416
'reversed',

test/index.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ var parseLdJson = require('../lib/parse-ldjson');
77
var loadFixtures = require('./helpers/load-fixtures');
88
var jsonDefault = require('./fixtures/json/default');
99
var jsonQuotes = require('./fixtures/json/quotes');
10+
var backslashAtEnd = require('./fixtures/json/backslashAtEnd');
11+
var backslashAtEndInMiddleColumn = require('./fixtures/json/backslashAtEndInMiddleColumn');
1012
var jsonNested = require('./fixtures/json/nested');
1113
var jsonDefaultValue = require('./fixtures/json/defaultValue');
1214
var jsonDefaultValueEmpty = require('./fixtures/json/defaultValueEmpty');
@@ -198,6 +200,30 @@ async.parallel(loadFixtures(csvFixtures), function (err) {
198200
});
199201
});
200202

203+
204+
test('should not escape quotes with double quotes, when there is a backslah in the end', function (t) {
205+
json2csv({
206+
data: backslashAtEnd,
207+
fields: ['a string']
208+
}, function (error, csv) {
209+
t.error(error);
210+
t.equal(csv, csvFixtures.backslashAtEnd);
211+
t.end();
212+
});
213+
});
214+
215+
216+
test('should not escape quotes with double quotes, when there is a backslah in the end, and its not the last column', function (t) {
217+
json2csv({
218+
data: backslashAtEndInMiddleColumn,
219+
fields: ['uuid','title','id']
220+
}, function (error, csv) {
221+
t.error(error);
222+
t.equal(csv, csvFixtures.backslashAtEndInMiddleColumn);
223+
t.end();
224+
});
225+
});
226+
201227
test('should use a custom delimiter when \'quotes\' property is present', function (t) {
202228
json2csv({
203229
data: jsonDefault,
@@ -466,7 +492,7 @@ async.parallel(loadFixtures(csvFixtures), function (err) {
466492
newLine: '\n'
467493
}, function (error, csv){
468494
t.error(error);
469-
t.equal(csv, '"field"\n"\\""');
495+
t.equal(csv, '"field"\n"\\"""');
470496
t.end();
471497
});
472498
});

0 commit comments

Comments
 (0)