Skip to content

Commit 525dca2

Browse files
authored
Merge pull request apache#610 from rootvector2/quote-comment-marker-first-char
Quote value starting with comment marker in minimal quote mode
2 parents 411d3a3 + 3c2291c commit 525dca2

2 files changed

Lines changed: 30 additions & 2 deletions

File tree

src/main/java/org/apache/commons/csv/CSVFormat.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,10 +2454,11 @@ private void printWithQuotes(final Object object, final CharSequence charSeq, fi
24542454
}
24552455
} else {
24562456
char c = charSeq.charAt(pos);
2457-
if (c <= Constants.COMMENT) {
2457+
if (c <= Constants.COMMENT || isCommentMarkerSet() && c == commentMarker.charValue()) {
24582458
// Some other chars at the start of a value caused the parser to fail, so for now
24592459
// encapsulate if we start in anything less than '#'. We are being conservative
2460-
// by including the default comment char too.
2460+
// by including the default comment char and any configured comment marker too,
2461+
// which the parser would otherwise read back as a comment line.
24612462
quote = true;
24622463
} else {
24632464
while (pos < len) {

src/test/java/org/apache/commons/csv/CSVPrinterTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,6 +1829,33 @@ void testQuoteCommaFirstChar() throws IOException {
18291829
}
18301830
}
18311831

1832+
@Test
1833+
void testQuoteCommentMarkerFirstChar() throws IOException {
1834+
final CSVFormat format = CSVFormat.DEFAULT.builder().setCommentMarker(';').get();
1835+
final StringWriter sw = new StringWriter();
1836+
final String col1 = ";comment-like";
1837+
try (CSVPrinter printer = new CSVPrinter(sw, format)) {
1838+
// A real comment is written with the marker, unquoted.
1839+
printer.printComment("a real comment");
1840+
// A value starting with the marker is quoted, so it does not read back as a comment.
1841+
printer.printRecord(col1, "b");
1842+
// The marker past the first character does not start a comment, so only the leading-marker value is quoted.
1843+
printer.printRecord("a;b", ";c");
1844+
}
1845+
assertEquals("; a real comment" + RECORD_SEPARATOR +
1846+
"\";comment-like\",b" + RECORD_SEPARATOR +
1847+
"a;b,\";c\"" + RECORD_SEPARATOR, sw.toString());
1848+
// The comment is dropped on read; both data records survive intact.
1849+
try (CSVParser parser = CSVParser.parse(sw.toString(), format)) {
1850+
final List<CSVRecord> records = parser.getRecords();
1851+
assertEquals(2, records.size());
1852+
assertEquals(col1, records.get(0).get(0));
1853+
assertEquals("b", records.get(0).get(1));
1854+
assertEquals("a;b", records.get(1).get(0));
1855+
assertEquals(";c", records.get(1).get(1));
1856+
}
1857+
}
1858+
18321859
@Test
18331860
void testQuoteNonNumeric() throws IOException {
18341861
final StringWriter sw = new StringWriter();

0 commit comments

Comments
 (0)