Skip to content

Commit a423734

Browse files
committed
[CSV-263] Print from Reader with embedded quotes generates incorrect
output. - Resolve conflicts from PR apache#78 by Jason A. Guild. - Don't use depreacted methods. - Javadoc. - Use final.
1 parent 3dad2ee commit a423734

4 files changed

Lines changed: 81 additions & 3 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
<action type="fix" dev="ggregory" due-to="Gary Gregory">Update CSVParser.parse(File, Charset, CSVFormat) from IO to NIO.</action>
6060
<action issue="CSV-271" type="fix" dev="ggregory" due-to="Amar Prakash Pandey">Missing separator with print(object) followed by printRecord(Object[]) #157.</action>
6161
<action issue="CSV-158" type="fix" dev="ggregory" due-to="Alexander Bondarev, Benedikt Ritter, Gary Gregory, Chen">Fix EOL checking for read array in ExtendedBufferedReader #5.</action>
62+
<action issue="CSV-263" type="fix" dev="ggregory" due-to="Jason A. Guild, Gary Gregory">Print from Reader with embedded quotes generates incorrect output #78.</action>
6263
<!-- ADD -->
6364
<action issue="CSV-275" type="add" dev="ggregory" due-to="Michael Wyraz, Gary Gregory">Make CSVRecord#toList() public.</action>
6465
<action type="add" dev="ggregory" due-to="Gary Gregory">Add CSVRecord#stream().</action>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,7 @@ public CSVPrinter print(final File out, final Charset charset) throws IOExceptio
17471747

17481748
/**
17491749
* Prints the {@code value} as the next value on the line to {@code out}. The value will be escaped or encapsulated as needed. Useful when one wants to
1750-
* avoid creating CSVPrinters. Trims the value if {@link #getTrim()} is true
1750+
* avoid creating CSVPrinters. Trims the value if {@link #getTrim()} is true.
17511751
*
17521752
* @param value value to output.
17531753
* @param out where to print the value.
@@ -2120,11 +2120,11 @@ private void printWithQuotes(final Reader reader, final Appendable appendable) t
21202120
// write out segment up until this char
21212121
if (pos > 0) {
21222122
append(builder.substring(0, pos), appendable);
2123+
append(quote, appendable);
21232124
builder.setLength(0);
21242125
pos = -1;
21252126
}
21262127

2127-
append(quote, appendable);
21282128
append((char) c, appendable);
21292129
}
21302130
pos++;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ public void testPrintWithQuotes() throws IOException {
971971
final Appendable out = new StringBuilder();
972972
final CSVFormat format = CSVFormat.RFC4180.withDelimiter(',').withQuote('"').withEscape('?').withQuoteMode(QuoteMode.NON_NUMERIC);
973973
format.print(in, out, true);
974-
assertEquals("\"\"\"\"a,b,c\r\nx,y,z\"", out.toString());
974+
assertEquals("\"\"\"a,b,c\r\nx,y,z\"", out.toString());
975975
}
976976

977977
@Test
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.commons.csv.issues;
19+
20+
import static org.junit.jupiter.api.Assertions.assertEquals;
21+
22+
import java.io.IOException;
23+
import java.io.Reader;
24+
import java.io.StringReader;
25+
26+
import org.apache.commons.csv.CSVFormat;
27+
import org.apache.commons.csv.QuoteMode;
28+
import org.junit.jupiter.api.Test;
29+
30+
/**
31+
* Tests [CSV-263] Print from Reader with embedded quotes generates incorrect output.
32+
*/
33+
public class JiraCsv263Test {
34+
35+
@Test
36+
public void testPrintFromReaderWithQuotes() throws IOException {
37+
// @formatter:off
38+
final CSVFormat format = CSVFormat.RFC4180.builder()
39+
.setDelimiter(',')
40+
.setQuote('"')
41+
.setEscape('?')
42+
.setQuoteMode(QuoteMode.NON_NUMERIC)
43+
.build();
44+
// @formatter:on
45+
final StringBuilder out = new StringBuilder();
46+
47+
final Reader atStartOnly = new StringReader("\"a,b,c\r\nx,y,z");
48+
format.print(atStartOnly, out, true);
49+
assertEquals("\"\"\"a,b,c\r\nx,y,z\"", out.toString());
50+
51+
final Reader atEndOnly = new StringReader("a,b,c\r\nx,y,z\"");
52+
out.setLength(0);
53+
format.print(atEndOnly, out, true);
54+
assertEquals("\"a,b,c\r\nx,y,z\"\"\"", out.toString());
55+
56+
final Reader atBeginEnd = new StringReader("\"a,b,c\r\nx,y,z\"");
57+
out.setLength(0);
58+
format.print(atBeginEnd, out, true);
59+
assertEquals("\"\"\"a,b,c\r\nx,y,z\"\"\"", out.toString());
60+
61+
final Reader embeddedBeginMiddle = new StringReader("\"a\",b,c\r\nx,\"y\",z");
62+
out.setLength(0);
63+
format.print(embeddedBeginMiddle, out, true);
64+
assertEquals("\"\"\"a\"\",b,c\r\nx,\"\"y\"\",z\"", out.toString());
65+
66+
final Reader embeddedMiddleEnd = new StringReader("a,\"b\",c\r\nx,y,\"z\"");
67+
out.setLength(0);
68+
format.print(embeddedMiddleEnd, out, true);
69+
assertEquals("\"a,\"\"b\"\",c\r\nx,y,\"\"z\"\"\"", out.toString());
70+
71+
final Reader nested = new StringReader("a,\"b \"and\" c\",d");
72+
out.setLength(0);
73+
format.print(nested, out, true);
74+
assertEquals("\"a,\"\"b \"\"and\"\" c\"\",d\"", out.toString());
75+
}
76+
77+
}

0 commit comments

Comments
 (0)