diff --git a/lib/parser/parser.js b/lib/parser/parser.js index ea6875ce..b50a809c 100644 --- a/lib/parser/parser.js +++ b/lib/parser/parser.js @@ -143,10 +143,11 @@ function createParser(options) { } function getNextToken(line, cursor) { - var token, nextIndex, subStr = line.substr(cursor); + var token, tokenLen, nextIndex, subStr = line.substr(cursor); if ((nextIndex = subStr.search(NEXT_TOKEN_REGEXP)) !== -1) { - token = line[cursor += nextIndex]; - cursor += subStr.match(NEXT_TOKEN_REGEXP)[1].length - 1; + tokenLen = subStr.match(NEXT_TOKEN_REGEXP)[1].length; + token = line.substr(cursor + nextIndex, tokenLen); + cursor += nextIndex + tokenLen - 1; } return {token: token, cursor: cursor}; } @@ -167,6 +168,11 @@ function createParser(options) { items = []; lastLineI = i; } else { + // if ends with CR and there is more data, keep unparsed due to possible coming LF in CRLF + if (token === '\r' && hasMoreData) { + i = lastLineI; + cursor = null; + } break; } } else if (hasComments && token === COMMENT) { diff --git a/test/issues.test.js b/test/issues.test.js index 3f186e3c..91f28217 100644 --- a/test/issues.test.js +++ b/test/issues.test.js @@ -239,4 +239,16 @@ it.describe("github issues", function (it) { }); }); }); + + it.describe("#150", function (it) { + it.should("not parse a row if a new line is ambiguous and there is more data", function () { + var data = "first_name,last_name,email_address\r"; + var myParser = parser({delimiter: ","}); + var parsedData = myParser(data, true); + assert.deepEqual(parsedData, { + "line": "first_name,last_name,email_address\r", + "rows": [] + }); + }); + }); }); diff --git a/test/parser.test.js b/test/parser.test.js index 13fddbe8..ba078054 100644 --- a/test/parser.test.js +++ b/test/parser.test.js @@ -319,7 +319,7 @@ it.describe("fast-csv parser", function (it) { }); it.should("parse a block of CSV text with a trailing delimiter", function () { - var data = "first_name,last_name,email_address,empty\nFirst1,Last1,email1@email.com,\n"; + var data = "first_name,last_name,email_address,empty\rFirst1,Last1,email1@email.com,\r"; var myParser = parser({delimiter: ","}); assert.deepEqual(myParser(data, false), { "line": "", "rows": [ @@ -330,7 +330,7 @@ it.describe("fast-csv parser", function (it) { }); it.should("parse a block of CSV text with a trailing delimiter followed by a space", function() { - var data = "first_name,last_name,email_address,empty\nFirst1,Last1,email1@email.com, \n"; + var data = "first_name,last_name,email_address,empty\nFirst1,Last1,email1@email.com, \r"; var myParser = parser({ delimiter: "," }); assert.deepEqual(myParser(data, false), { "line": "", "rows": [ @@ -341,7 +341,7 @@ it.describe("fast-csv parser", function (it) { }); it.should("parse a block of Space Separated Value text with a trailing delimiter", function() { - var data = "first_name last_name email_address empty\nFirst1 Last1 email1@email.com \n"; + var data = "first_name last_name email_address empty\rFirst1 Last1 email1@email.com \r"; var myParser = parser({ delimiter: " " }); assert.deepEqual(myParser(data, false), { "line": "", "rows": [ @@ -400,15 +400,13 @@ it.describe("fast-csv parser", function (it) { }); }); - it.should("parse a row if a new line is found and there is more data", function () { + it.should("not parse a row if an ambiguous new line is found and there is more data", function () { var data = "first_name,last_name,email_address\r"; var myParser = parser({delimiter: ","}); var parsedData = myParser(data, true); assert.deepEqual(parsedData, { - "line": "", - "rows": [ - ["first_name", "last_name", "email_address"] - ] + "line": "first_name,last_name,email_address\r", + "rows": [] }); }); @@ -532,15 +530,13 @@ it.describe("fast-csv parser", function (it) { }); }); - it.should("parse a row if a new line is found and there is more data", function () { + it.should("not parse a row if an ambiguous new line is found and there is more data", function () { var data = '"first_name","last_name","email_address"\r'; var myParser = parser({delimiter: ","}); var parsedData = myParser(data, true); assert.deepEqual(parsedData, { - "line": "", - "rows": [ - ["first_name", "last_name", "email_address"] - ] + "line": '"first_name","last_name","email_address"\r', + "rows": [] }); }); }); @@ -614,6 +610,16 @@ it.describe("fast-csv parser", function (it) { }); }); + it.should("not parse a row if a new line is incomplete and there is more data", function () { + var data = "first_name,last_name,email_address\r"; + var myParser = parser({delimiter: ","}); + var parsedData = myParser(data, true); + assert.deepEqual(parsedData, { + "line": "first_name,last_name,email_address\r", + "rows": [] + }); + }); + it.should("not parse a row if there is a trailing delimiter and there is more data", function () { var data = "first_name,last_name,email_address,"; var myParser = parser({delimiter: ","});