Skip to content

Commit e8b4fc7

Browse files
committed
1 parent 8bf52f0 commit e8b4fc7

File tree

16 files changed

+392
-159
lines changed

16 files changed

+392
-159
lines changed

demo/esm/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
### [0.0.7](https://github.com/adaltas/node-csv/compare/[email protected]@0.0.7) (2022-06-29)
7+
8+
**Note:** Version bump only for package csv-demo-esm
9+
10+
11+
12+
13+
614
### [0.0.6](https://github.com/adaltas/node-csv/compare/[email protected]@0.0.6) (2022-06-16)
715

816
**Note:** Version bump only for package csv-demo-esm

demo/esm/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"name": "csv-demo-esm",
3-
"version": "0.0.6",
3+
"version": "0.0.7",
44
"main": "index.js",
55
"license": "MIT",
66
"type": "module",
77
"private": true,
88
"dependencies": {
9-
"csv": "^6.1.3",
10-
"csv-parse": "^5.2.0"
9+
"csv": "^6.1.4",
10+
"csv-parse": "^5.2.1"
1111
},
1212
"devDependencies": {
1313
"coffeescript": "^2.7.0",

demo/issues-esm/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
### [0.0.3](https://github.com/adaltas/node-csv/compare/[email protected]@0.0.3) (2022-06-29)
7+
8+
**Note:** Version bump only for package csv-issues-esm
9+
10+
11+
12+
13+
614
### [0.0.2](https://github.com/adaltas/node-csv/compare/[email protected]@0.0.2) (2022-05-24)
715

816
**Note:** Version bump only for package csv-issues-esm

demo/issues-esm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "csv-issues-esm",
3-
"version": "0.0.2",
3+
"version": "0.0.3",
44
"main": "index.js",
55
"license": "MIT",
66
"type": "module",

packages/csv-parse/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
### [5.2.1](https://github.com/adaltas/node-csv/compare/[email protected]@5.2.1) (2022-06-29)
7+
8+
9+
### Bug Fixes
10+
11+
* **csv-parse:** rtrim encoding support (fix [#349](https://github.com/adaltas/node-csv/issues/349)) ([8bf52f0](https://github.com/adaltas/node-csv/commit/8bf52f0d5c25ee2423cb1629d3e9103534668c83))
12+
13+
14+
615
## [5.2.0](https://github.com/adaltas/node-csv/compare/[email protected]@5.2.0) (2022-06-14)
716

817

packages/csv-parse/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "5.2.0",
2+
"version": "5.2.1",
33
"name": "csv-parse",
44
"description": "CSV parsing implementing the Node.js `stream.Transform` API",
55
"keywords": [

packages/csv/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
### [6.1.4](https://github.com/adaltas/node-csv/compare/[email protected]@6.1.4) (2022-06-29)
7+
8+
**Note:** Version bump only for package csv
9+
10+
11+
12+
13+
614
### [6.1.3](https://github.com/adaltas/node-csv/compare/[email protected]@6.1.3) (2022-06-16)
715

816

packages/csv/dist/cjs/index.cjs

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,16 @@ class ResizeableBuffer{
376376
}
377377
}
378378

379+
// white space characters
380+
// https://en.wikipedia.org/wiki/Whitespace_character
381+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes#Types
382+
// \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff
383+
const np = 12;
384+
const cr$1 = 13; // `\r`, carriage return, 0x0D in hexadécimal, 13 in decimal
385+
const nl$1 = 10; // `\n`, newline, 0x0A in hexadecimal, 10 in decimal
386+
const space = 32;
387+
const tab = 9;
388+
379389
const init_state = function(options){
380390
return {
381391
bomSkipped: false,
@@ -409,7 +419,14 @@ const init_state = function(options){
409419
recordDelimiterMaxLength: options.record_delimiter.length === 0 ? 2 : Math.max(...options.record_delimiter.map((v) => v.length)),
410420
trimChars: [Buffer.from(' ', options.encoding)[0], Buffer.from('\t', options.encoding)[0]],
411421
wasQuoting: false,
412-
wasRowDelimiter: false
422+
wasRowDelimiter: false,
423+
timchars: [
424+
Buffer.from(Buffer.from([cr$1], 'utf8').toString(), options.encoding),
425+
Buffer.from(Buffer.from([nl$1], 'utf8').toString(), options.encoding),
426+
Buffer.from(Buffer.from([np], 'utf8').toString(), options.encoding),
427+
Buffer.from(Buffer.from([space], 'utf8').toString(), options.encoding),
428+
Buffer.from(Buffer.from([tab], 'utf8').toString(), options.encoding),
429+
]
413430
};
414431
};
415432

@@ -832,15 +849,9 @@ const isRecordEmpty = function(record){
832849
return record.every((field) => field == null || field.toString && field.toString().trim() === '');
833850
};
834851

835-
// white space characters
836-
// https://en.wikipedia.org/wiki/Whitespace_character
837-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes#Types
838-
// \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff
839-
const tab = 9;
840-
const nl = 10; // \n, 0x0A in hexadecimal, 10 in decimal
841-
const np = 12;
842-
const cr = 13; // \r, 0x0D in hexadécimal, 13 in decimal
843-
const space = 32;
852+
const cr = 13; // `\r`, carriage return, 0x0D in hexadécimal, 13 in decimal
853+
const nl = 10; // `\n`, newline, 0x0A in hexadecimal, 10 in decimal
854+
844855
const boms = {
845856
// Note, the following are equals:
846857
// Buffer.from("\ufeff")
@@ -985,7 +996,7 @@ const transform$1 = function(original_options = {}) {
985996
if(this.state.commenting === false && this.__isQuote(buf, pos)){
986997
if(this.state.quoting === true){
987998
const nextChr = buf[pos+quote.length];
988-
const isNextChrTrimable = rtrim && this.__isCharTrimable(nextChr);
999+
const isNextChrTrimable = rtrim && this.__isCharTrimable(buf, pos+quote.length);
9891000
const isNextChrComment = comment !== null && this.__compareBytes(comment, buf, pos+quote.length, nextChr);
9901001
const isNextChrDelimiter = this.__isDelimiter(buf, pos+quote.length, nextChr);
9911002
const isNextChrRecordDelimiter = record_delimiter.length === 0 ? this.__autoDiscoverRecordDelimiter(buf, pos+quote.length) : this.__isRecordDelimiter(nextChr, buf, pos+quote.length);
@@ -1095,31 +1106,34 @@ const transform$1 = function(original_options = {}) {
10951106
}
10961107
if(this.state.commenting === false){
10971108
if(max_record_size !== 0 && this.state.record_length + this.state.field.length > max_record_size){
1098-
const err = this.__error(
1109+
return this.__error(
10991110
new CsvError$1('CSV_MAX_RECORD_SIZE', [
11001111
'Max Record Size:',
11011112
'record exceed the maximum number of tolerated bytes',
11021113
`of ${max_record_size}`,
11031114
`at line ${this.info.lines}`,
11041115
], this.options, this.__infoField())
11051116
);
1106-
if(err !== undefined) return err;
11071117
}
11081118
}
1109-
const lappend = ltrim === false || this.state.quoting === true || this.state.field.length !== 0 || !this.__isCharTrimable(chr);
1119+
const lappend = ltrim === false || this.state.quoting === true || this.state.field.length !== 0 || !this.__isCharTrimable(buf, pos);
11101120
// rtrim in non quoting is handle in __onField
11111121
const rappend = rtrim === false || this.state.wasQuoting === false;
11121122
if(lappend === true && rappend === true){
11131123
this.state.field.append(chr);
1114-
}else if(rtrim === true && !this.__isCharTrimable(chr)){
1115-
const err = this.__error(
1124+
}else if(rtrim === true && !this.__isCharTrimable(buf, pos)){
1125+
return this.__error(
11161126
new CsvError$1('CSV_NON_TRIMABLE_CHAR_AFTER_CLOSING_QUOTE', [
11171127
'Invalid Closing Quote:',
11181128
'found non trimable byte after quote',
11191129
`at line ${this.info.lines}`,
11201130
], this.options, this.__infoField())
11211131
);
1122-
if(err !== undefined) return err;
1132+
}else {
1133+
if(lappend === false){
1134+
pos += this.__isCharTrimable(buf, pos) - 1;
1135+
}
1136+
continue;
11231137
}
11241138
}
11251139
if(end === true){
@@ -1376,8 +1390,19 @@ const transform$1 = function(original_options = {}) {
13761390
return [undefined, field];
13771391
},
13781392
// Helper to test if a character is a space or a line delimiter
1379-
__isCharTrimable: function(chr){
1380-
return chr === space || chr === tab || chr === cr || chr === nl || chr === np;
1393+
__isCharTrimable: function(buf, pos){
1394+
const isTrim = (buf, pos) => {
1395+
const {timchars} = this.state;
1396+
loop1: for(let i = 0; i < timchars.length; i++){
1397+
const timchar = timchars[i];
1398+
for(let j = 0; j < timchar.length; j++){
1399+
if(timchar[j] !== buf[pos+j]) continue loop1;
1400+
}
1401+
return timchar.length;
1402+
}
1403+
return 0;
1404+
};
1405+
return isTrim(buf, pos);
13811406
},
13821407
// Keep it in case we implement the `cast_int` option
13831408
// __isInt(value){

packages/csv/dist/cjs/sync.cjs

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,16 @@ class ResizeableBuffer{
373373
}
374374
}
375375

376+
// white space characters
377+
// https://en.wikipedia.org/wiki/Whitespace_character
378+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes#Types
379+
// \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff
380+
const np = 12;
381+
const cr$1 = 13; // `\r`, carriage return, 0x0D in hexadécimal, 13 in decimal
382+
const nl$1 = 10; // `\n`, newline, 0x0A in hexadecimal, 10 in decimal
383+
const space = 32;
384+
const tab = 9;
385+
376386
const init_state = function(options){
377387
return {
378388
bomSkipped: false,
@@ -406,7 +416,14 @@ const init_state = function(options){
406416
recordDelimiterMaxLength: options.record_delimiter.length === 0 ? 2 : Math.max(...options.record_delimiter.map((v) => v.length)),
407417
trimChars: [Buffer.from(' ', options.encoding)[0], Buffer.from('\t', options.encoding)[0]],
408418
wasQuoting: false,
409-
wasRowDelimiter: false
419+
wasRowDelimiter: false,
420+
timchars: [
421+
Buffer.from(Buffer.from([cr$1], 'utf8').toString(), options.encoding),
422+
Buffer.from(Buffer.from([nl$1], 'utf8').toString(), options.encoding),
423+
Buffer.from(Buffer.from([np], 'utf8').toString(), options.encoding),
424+
Buffer.from(Buffer.from([space], 'utf8').toString(), options.encoding),
425+
Buffer.from(Buffer.from([tab], 'utf8').toString(), options.encoding),
426+
]
410427
};
411428
};
412429

@@ -829,15 +846,9 @@ const isRecordEmpty = function(record){
829846
return record.every((field) => field == null || field.toString && field.toString().trim() === '');
830847
};
831848

832-
// white space characters
833-
// https://en.wikipedia.org/wiki/Whitespace_character
834-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes#Types
835-
// \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff
836-
const tab = 9;
837-
const nl = 10; // \n, 0x0A in hexadecimal, 10 in decimal
838-
const np = 12;
839-
const cr = 13; // \r, 0x0D in hexadécimal, 13 in decimal
840-
const space = 32;
849+
const cr = 13; // `\r`, carriage return, 0x0D in hexadécimal, 13 in decimal
850+
const nl = 10; // `\n`, newline, 0x0A in hexadecimal, 10 in decimal
851+
841852
const boms = {
842853
// Note, the following are equals:
843854
// Buffer.from("\ufeff")
@@ -982,7 +993,7 @@ const transform$1 = function(original_options = {}) {
982993
if(this.state.commenting === false && this.__isQuote(buf, pos)){
983994
if(this.state.quoting === true){
984995
const nextChr = buf[pos+quote.length];
985-
const isNextChrTrimable = rtrim && this.__isCharTrimable(nextChr);
996+
const isNextChrTrimable = rtrim && this.__isCharTrimable(buf, pos+quote.length);
986997
const isNextChrComment = comment !== null && this.__compareBytes(comment, buf, pos+quote.length, nextChr);
987998
const isNextChrDelimiter = this.__isDelimiter(buf, pos+quote.length, nextChr);
988999
const isNextChrRecordDelimiter = record_delimiter.length === 0 ? this.__autoDiscoverRecordDelimiter(buf, pos+quote.length) : this.__isRecordDelimiter(nextChr, buf, pos+quote.length);
@@ -1092,31 +1103,34 @@ const transform$1 = function(original_options = {}) {
10921103
}
10931104
if(this.state.commenting === false){
10941105
if(max_record_size !== 0 && this.state.record_length + this.state.field.length > max_record_size){
1095-
const err = this.__error(
1106+
return this.__error(
10961107
new CsvError$1('CSV_MAX_RECORD_SIZE', [
10971108
'Max Record Size:',
10981109
'record exceed the maximum number of tolerated bytes',
10991110
`of ${max_record_size}`,
11001111
`at line ${this.info.lines}`,
11011112
], this.options, this.__infoField())
11021113
);
1103-
if(err !== undefined) return err;
11041114
}
11051115
}
1106-
const lappend = ltrim === false || this.state.quoting === true || this.state.field.length !== 0 || !this.__isCharTrimable(chr);
1116+
const lappend = ltrim === false || this.state.quoting === true || this.state.field.length !== 0 || !this.__isCharTrimable(buf, pos);
11071117
// rtrim in non quoting is handle in __onField
11081118
const rappend = rtrim === false || this.state.wasQuoting === false;
11091119
if(lappend === true && rappend === true){
11101120
this.state.field.append(chr);
1111-
}else if(rtrim === true && !this.__isCharTrimable(chr)){
1112-
const err = this.__error(
1121+
}else if(rtrim === true && !this.__isCharTrimable(buf, pos)){
1122+
return this.__error(
11131123
new CsvError$1('CSV_NON_TRIMABLE_CHAR_AFTER_CLOSING_QUOTE', [
11141124
'Invalid Closing Quote:',
11151125
'found non trimable byte after quote',
11161126
`at line ${this.info.lines}`,
11171127
], this.options, this.__infoField())
11181128
);
1119-
if(err !== undefined) return err;
1129+
}else {
1130+
if(lappend === false){
1131+
pos += this.__isCharTrimable(buf, pos) - 1;
1132+
}
1133+
continue;
11201134
}
11211135
}
11221136
if(end === true){
@@ -1373,8 +1387,19 @@ const transform$1 = function(original_options = {}) {
13731387
return [undefined, field];
13741388
},
13751389
// Helper to test if a character is a space or a line delimiter
1376-
__isCharTrimable: function(chr){
1377-
return chr === space || chr === tab || chr === cr || chr === nl || chr === np;
1390+
__isCharTrimable: function(buf, pos){
1391+
const isTrim = (buf, pos) => {
1392+
const {timchars} = this.state;
1393+
loop1: for(let i = 0; i < timchars.length; i++){
1394+
const timchar = timchars[i];
1395+
for(let j = 0; j < timchar.length; j++){
1396+
if(timchar[j] !== buf[pos+j]) continue loop1;
1397+
}
1398+
return timchar.length;
1399+
}
1400+
return 0;
1401+
};
1402+
return isTrim(buf, pos);
13781403
},
13791404
// Keep it in case we implement the `cast_int` option
13801405
// __isInt(value){

0 commit comments

Comments
 (0)