Skip to content

Commit a65806a

Browse files
committed
Validation of the format parameters (suggested by Bob Smith in SANDBOX-291)
git-svn-id: https://svn.apache.org/repos/asf/commons/sandbox/csv/trunk@1298234 13f79535-47bb-0310-9956-ffa450edef68
1 parent 72d6e79 commit a65806a

4 files changed

Lines changed: 139 additions & 1 deletion

File tree

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,42 @@ public class CSVFormat implements Cloneable, Serializable {
126126
this.emptyLinesIgnored = emptyLinesIgnored;
127127
}
128128

129+
/**
130+
* Returns true if the given character is a line break character.
131+
*
132+
* @param c the character to check
133+
*
134+
* @return true if <code>c</code> is a line break character
135+
*/
136+
private static boolean isLineBreak(char c) {
137+
return c == '\n' || c == '\r';
138+
}
139+
140+
/**
141+
* Verifies the consistency of the parameters and throws an IllegalArgumentException if necessary.
142+
*/
143+
void validate() throws IllegalArgumentException {
144+
if (delimiter == encapsulator) {
145+
throw new IllegalArgumentException("The encapsulator character and the delimiter cannot be the same (\"" + encapsulator + "\")");
146+
}
147+
148+
if (delimiter == escape) {
149+
throw new IllegalArgumentException("The escape character and the delimiter cannot be the same (\"" + escape + "\")");
150+
}
151+
152+
if (delimiter == commentStart) {
153+
throw new IllegalArgumentException("The comment start character and the delimiter cannot be the same (\"" + commentStart + "\")");
154+
}
155+
156+
if (encapsulator != DISABLED && encapsulator == commentStart) {
157+
throw new IllegalArgumentException("The comment start character and the encapsulator cannot be the same (\"" + commentStart + "\")");
158+
}
159+
160+
if (escape != DISABLED && escape == commentStart) {
161+
throw new IllegalArgumentException("The comment start and the escape character cannot be the same (\"" + commentStart + "\")");
162+
}
163+
}
164+
129165
/**
130166
* Returns the character delimiting the values (typically ';', ',' or '\t').
131167
*
@@ -140,8 +176,13 @@ public char getDelimiter() {
140176
*
141177
* @param delimiter the delimiter character
142178
* @return A copy of this format using the specified delimiter character
179+
* @throws IllegalArgumentException thrown if the specified character is a line break
143180
*/
144181
public CSVFormat withDelimiter(char delimiter) {
182+
if (isLineBreak(delimiter)) {
183+
throw new IllegalArgumentException("The delimiter cannot be a line break");
184+
}
185+
145186
CSVFormat format = clone();
146187
format.delimiter = delimiter;
147188
return format;
@@ -161,8 +202,13 @@ public char getEncapsulator() {
161202
*
162203
* @param encapsulator the encapsulator character
163204
* @return A copy of this format using the specified encapsulator character
205+
* @throws IllegalArgumentException thrown if the specified character is a line break
164206
*/
165207
public CSVFormat withEncapsulator(char encapsulator) {
208+
if (isLineBreak(encapsulator)) {
209+
throw new IllegalArgumentException("The encapsulator cannot be a line break");
210+
}
211+
166212
CSVFormat format = clone();
167213
format.encapsulator = encapsulator;
168214
return format;
@@ -186,8 +232,13 @@ public char getCommentStart() {
186232
*
187233
* @param commentStart the comment start marker
188234
* @return A copy of this format using the specified character as the comment start marker
235+
* @throws IllegalArgumentException thrown if the specified character is a line break
189236
*/
190237
public CSVFormat withCommentStart(char commentStart) {
238+
if (isLineBreak(commentStart)) {
239+
throw new IllegalArgumentException("The comment start character cannot be a line break");
240+
}
241+
191242
CSVFormat format = clone();
192243
format.commentStart = commentStart;
193244
return format;
@@ -216,8 +267,13 @@ public char getEscape() {
216267
*
217268
* @param escape the escape character
218269
* @return A copy of this format using the specified escape character
270+
* @throws IllegalArgumentException thrown if the specified character is a line break
219271
*/
220272
public CSVFormat withEscape(char escape) {
273+
if (isLineBreak(escape)) {
274+
throw new IllegalArgumentException("The escape character cannot be a line break");
275+
}
276+
221277
CSVFormat format = clone();
222278
format.escape = escape;
223279
return format;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public class CSVParser implements Iterable<String[]> {
7676
* CSV parser using the default {@link CSVFormat}.
7777
*
7878
* @param input a Reader containing "csv-formatted" input
79+
* @throws IllegalArgumentException thrown if the parameters of the format are inconsistent
7980
*/
8081
public CSVParser(Reader input) {
8182
this(input, CSVFormat.DEFAULT);
@@ -86,8 +87,11 @@ public CSVParser(Reader input) {
8687
*
8788
* @param input a Reader containing "csv-formatted" input
8889
* @param format the CSVFormat used for CSV parsing
90+
* @throws IllegalArgumentException thrown if the parameters of the format are inconsistent
8991
*/
9092
public CSVParser(Reader input, CSVFormat format) {
93+
format.validate();
94+
9195
if (format.isUnicodeEscapesInterpreted()) {
9296
input = new UnicodeUnescapeReader(input);
9397
}
@@ -100,6 +104,7 @@ public CSVParser(Reader input, CSVFormat format) {
100104
*
101105
* @param input a String containing "csv-formatted" input
102106
* @param format the CSVFormat used for CSV parsing
107+
* @throws IllegalArgumentException thrown if the parameters of the format are inconsistent
103108
*/
104109
public CSVParser(String input, CSVFormat format) {
105110
this(new StringReader(input), format);

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,14 @@ public class CSVPrinter {
3939
* is supported. Hybrid formats (encapsulation and escaping with a different character) are not supported.
4040
*
4141
* @param out stream to which to print.
42-
* @param format describes the CSV variation.
42+
* @param format the CSV format. If null the default format is used ({@link CSVFormat#DEFAULT})
43+
* @throws IllegalArgumentException thrown if the parameters of the format are inconsistent
4344
*/
4445
public CSVPrinter(Appendable out, CSVFormat format) {
4546
this.out = out;
4647
this.format = format == null ? CSVFormat.DEFAULT : format;
48+
49+
this.format.validate();
4750
}
4851

4952
// ======================================================

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

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,78 @@ public void testFormat() {
7070
assertEquals("a,b,c", format.format("a", "b", "c"));
7171
assertEquals("\"x,y\",z", format.format("x,y", "z"));
7272
}
73+
74+
public void testValidation() {
75+
CSVFormat format = CSVFormat.DEFAULT;
76+
77+
try {
78+
format.withDelimiter('\n');
79+
fail();
80+
} catch (IllegalArgumentException e) {
81+
// expected
82+
}
83+
84+
try {
85+
format.withEscape('\r');
86+
fail();
87+
} catch (IllegalArgumentException e) {
88+
// expected
89+
}
90+
91+
try {
92+
format.withEncapsulator('\n');
93+
fail();
94+
} catch (IllegalArgumentException e) {
95+
// expected
96+
}
97+
98+
try {
99+
format.withCommentStart('\r');
100+
fail();
101+
} catch (IllegalArgumentException e) {
102+
// expected
103+
}
104+
105+
try {
106+
format.withDelimiter('!').withEscape('!').validate();
107+
fail();
108+
} catch (IllegalArgumentException e) {
109+
// expected
110+
}
111+
112+
try {
113+
format.withDelimiter('!').withCommentStart('!').validate();
114+
fail();
115+
} catch (IllegalArgumentException e) {
116+
// expected
117+
}
118+
119+
try {
120+
format.withEncapsulator('!').withCommentStart('!').validate();
121+
fail();
122+
} catch (IllegalArgumentException e) {
123+
// expected
124+
}
125+
126+
format.withEncapsulator(CSVFormat.DISABLED).withCommentStart(CSVFormat.DISABLED).validate();
127+
128+
try {
129+
format.withEscape('!').withCommentStart('!').validate();
130+
fail();
131+
} catch (IllegalArgumentException e) {
132+
// expected
133+
}
134+
135+
format.withEscape(CSVFormat.DISABLED).withCommentStart(CSVFormat.DISABLED).validate();
136+
137+
138+
try {
139+
format.withEncapsulator('!').withDelimiter('!').validate();
140+
fail();
141+
} catch (IllegalArgumentException e) {
142+
// expected
143+
}
144+
145+
146+
}
73147
}

0 commit comments

Comments
 (0)