Skip to content

Commit c388d4a

Browse files
committed
Merge branch '2.11'
2 parents 763b57b + f71a2ac commit c388d4a

File tree

5 files changed

+76
-76
lines changed

5 files changed

+76
-76
lines changed

csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvDecoder.java

+47-23
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public class CsvDecoder {
2525

2626
private final static int INT_CR = '\r';
2727
private final static int INT_LF = '\n';
28-
// private final static int INT_HASH = '#';
2928

3029
/*
3130
/**********************************************************************
@@ -488,43 +487,68 @@ public boolean startNewLine() throws IOException {
488487
* @since 2.10
489488
*/
490489
public boolean skipLinesWhenNeeded() throws IOException {
491-
if (!(_allowComments || _skipBlankLines)) {
490+
if (_allowComments) {
491+
return _skipCommentLines();
492+
}
493+
if (!_skipBlankLines) {
492494
return hasMoreInput();
493495
}
494-
int firstCharacterPtr = _inputPtr;
496+
497+
// only need to skip fully empty lines
495498
while (hasMoreInput()) {
496-
char ch = _inputBuffer[_inputPtr++];
499+
char ch = _inputBuffer[_inputPtr];
497500
if (ch == '\r' || ch == '\n') {
501+
++_inputPtr;
498502
_pendingLF = ch;
499503
_handleLF();
500-
// track the start of the new line
501-
firstCharacterPtr = _inputPtr;
502504
continue;
503505
}
504-
if (ch == ' ') {
506+
if (ch != ' ') {
507+
return true; // processing can go on
508+
}
509+
++_inputPtr;
510+
}
511+
return false; // end of input
512+
}
513+
514+
public boolean _skipCommentLines() throws IOException
515+
{
516+
while ((_inputPtr < _inputEnd) || loadMore()) {
517+
char ch = _inputBuffer[_inputPtr];
518+
switch (ch) {
519+
case '#':
520+
++_inputPtr;
521+
_skipCommentContents();
522+
continue;
523+
case '\r':
524+
case '\n':
525+
++_inputPtr;
526+
_pendingLF = ch;
527+
_handleLF();
528+
continue;
529+
case ' ':
505530
// skip all blanks (in both comments/blanks skip mode)
531+
++_inputPtr;
506532
continue;
533+
default:
534+
return true;
507535
}
508-
if (_allowComments) {
509-
if (_inputBuffer[firstCharacterPtr] == '#') {
510-
// on a commented line, skip everything
511-
continue;
512-
}
513-
if (ch == '#') {
514-
// we reach this point when whitespaces precedes the hash character
515-
// move the firstCharacterPtr to the '#' location in order to skip the line completely
516-
firstCharacterPtr = _inputPtr-1;
517-
continue;
518-
}
519-
}
520-
// we reached a non skippable character, this line needs to be parsed
521-
// rollback the input pointer to the beginning of the line
522-
_inputPtr = firstCharacterPtr;
523-
return true; // processing can go on
524536
}
525537
return false; // end of input
526538
}
527539

540+
private void _skipCommentContents() throws IOException
541+
{
542+
while ((_inputPtr < _inputEnd) || loadMore()) {
543+
char ch = _inputBuffer[_inputPtr++];
544+
if (ch == '\r' || ch == '\n') {
545+
_pendingLF = ch;
546+
_handleLF();
547+
break;
548+
}
549+
}
550+
}
551+
528552
/**
529553
* Method called to blindly skip a single line of content, without considering
530554
* aspects like quoting or escaping. Used currently simply to skip the first

csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/SkipBlankLines15Test.java renamed to csv/src/test/java/com/fasterxml/jackson/dataformat/csv/deser/SkipEmptyLines15Test.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import static org.junit.Assert.assertArrayEquals;
1010

1111
// for [dataformats-text#15]: Allow skipping of empty lines
12-
public class SkipBlankLines15Test extends ModuleTestBase {
12+
public class SkipEmptyLines15Test extends ModuleTestBase {
1313

1414
private static final String CSV_WITH_EMPTY_LINE = "1,\"xyz\"\n\ntrue,\n";
1515
private static final String CSV_WITH_BLANK_LINE = "1,\"xyz\"\n \ntrue,\n";
@@ -129,14 +129,18 @@ public void testCsvWithBlankLineAndCommentSkipBlankLinesFeatureDisabled() throws
129129
), rows);
130130
}
131131

132+
// 14-Apr-2020, tatu: Due to [dataformats-text#191], can not retain leading spaces
133+
// when trimming empty lines and/or comments, so test changed for 2.11
132134
public void testCsvWithBlankLineAndCommentSkipBlankLinesFeatureEnabled() throws Exception {
133135
String[][] rows = mapperForCsvAsArray()
134136
.with(CsvParser.Feature.SKIP_EMPTY_LINES)
135137
.readValue(CSV_WITH_BLANK_LINE_AND_COMMENT);
136138
// blank/empty lines are skipped
137139
assertArrayEquals(expected(
138140
row("1", "xyz"),
139-
row(" #comment"),
141+
// As per: [dataformats-text#191]
142+
// row(" #comment"),
143+
row("#comment"),
140144
row("true", "")
141145
), rows);
142146
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
package com.fasterxml.jackson.dataformat.csv.failing;
1+
package com.fasterxml.jackson.dataformat.csv.deser;
22

3-
import java.io.InputStream;
3+
import java.io.Reader;
4+
import java.io.StringReader;
45
import java.util.List;
56
import java.util.Map;
67

@@ -9,25 +10,26 @@
910
import com.fasterxml.jackson.dataformat.csv.ModuleTestBase;
1011

1112
// [dataformats-text#191]
12-
public class ParserSkipEmpty191Test extends ModuleTestBase {
13+
public class SkipEmptyLines191Test extends ModuleTestBase {
1314

1415
private static String COL_1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1516
private static String COL_2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
1617

1718
// [dataformats-text#191]: IndexArrayOutOfBounds at 4000
18-
public void testBigCsvFile() throws Exception {
19+
public void testBigCsvFile() throws Exception
20+
{
1921
CsvSchema schema = CsvSchema
2022
.emptySchema()
2123
.withHeader()
2224
.withColumnSeparator(';')
2325
.withNullValue("null")
2426
.withComments();
2527

26-
try (InputStream csvFileStream = getClass().getResourceAsStream("/csv/issue-191.csv")) {
28+
try (Reader r = new StringReader(_generate4kDoc())) {
2729
List<Map<String, String>> result = new CsvMapper()
2830
.readerFor(Map.class)
2931
.with(schema)
30-
.<Map<String, String>>readValues(csvFileStream)
32+
.<Map<String, String>>readValues(r)
3133
.readAll();
3234

3335
for (Map<String, String> row : result) {
@@ -36,4 +38,16 @@ public void testBigCsvFile() throws Exception {
3638
}
3739
}
3840
}
39-
}
41+
42+
private String _generate4kDoc() {
43+
StringBuilder sb = new StringBuilder(5000)
44+
.append("COL_1;COL_2\n")
45+
.append("# csv file with a newline at char 4000 (the buffer size) to verify a bug\n")
46+
.append("# LF has to be used for newlines to work\n")
47+
.append("# alignment chars to have the newline as the 4000s char: ----------------\n");
48+
for (int i = 0; i < 40; ++i) {
49+
sb.append("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n");
50+
}
51+
return sb.toString();
52+
}
53+
}

csv/src/test/resources/csv/issue-191.csv

-44
This file was deleted.

release-notes/VERSION-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Modules:
1818
#180: (yaml) YAMLGenerator serializes string with special chars unquoted when
1919
using `MINIMIZE_QUOTES` mode
2020
(reported, fix contributed by Timo R)
21+
#191: (csv) `ArrayIndexOutOfBoundsException` when skipping empty lines, comments
22+
(reported by f-julian@github)
2123

2224
2.10.4 (not yet released)
2325

0 commit comments

Comments
 (0)