@@ -113,6 +113,14 @@ private BOMInputStream createBOMInputStream(final String resource) throws IOExce
113113 return new BOMInputStream (ClassLoader .getSystemClassLoader ().getResource (resource ).openStream ());
114114 }
115115
116+ CSVRecord parse (final CSVParser parser , final int failParseRecordNo ) throws IOException {
117+ if (parser .getRecordNumber () + 1 == failParseRecordNo ) {
118+ assertThrows (IOException .class , () -> parser .nextRecord ());
119+ return null ;
120+ }
121+ return parser .nextRecord ();
122+ }
123+
116124 private void parseFully (final CSVParser parser ) {
117125 parser .forEach (Assertions ::assertNotNull );
118126 }
@@ -265,6 +273,109 @@ public void testClose() throws Exception {
265273 assertThrows (NoSuchElementException .class , records ::next );
266274 }
267275
276+ @ Test
277+ public void testCSV141_CSVFormat_DEFAULT () throws Exception {
278+ testCSV141Failure (CSVFormat .DEFAULT , 3 );
279+ }
280+
281+ @ Test
282+ public void testCSV141CSVFormat_INFORMIX_UNLOAD () throws Exception {
283+ testCSV141Failure (CSVFormat .INFORMIX_UNLOAD , 1 );
284+ }
285+
286+ @ Test
287+ public void testCSV141CSVFormat_INFORMIX_UNLOAD_CSV () throws Exception {
288+ testCSV141Failure (CSVFormat .INFORMIX_UNLOAD_CSV , 3 );
289+ }
290+
291+ @ Test
292+ public void testCSV141CSVFormat_ORACLE () throws Exception {
293+ testCSV141Failure (CSVFormat .ORACLE , 2 );
294+ }
295+
296+
297+ @ Test
298+ public void testCSV141CSVFormat_POSTGRESQL_CSV () throws Exception {
299+ testCSV141Failure (CSVFormat .POSTGRESQL_CSV , 3 );
300+ }
301+
302+ @ Test
303+ @ Disabled ("PR 295 does not work" )
304+ public void testCSV141Excel () throws Exception {
305+ testCSV141Ok (CSVFormat .EXCEL );
306+ }
307+
308+ private void testCSV141Failure (final CSVFormat format , final int failParseRecordNo ) throws IOException {
309+ final Path path = Paths .get ("src/test/resources/org/apache/commons/csv/CSV-141/csv-141.csv" );
310+ try (final CSVParser parser = CSVParser .parse (path , StandardCharsets .UTF_8 , format )) {
311+ // row 1
312+ CSVRecord record = parse (parser , failParseRecordNo );
313+ if (record == null ) {
314+ return ; // expected failure
315+ }
316+ assertEquals ("1414770317901" , record .get (0 ));
317+ assertEquals ("android.widget.EditText" , record .get (1 ));
318+ assertEquals ("pass sem1 _84*|*" , record .get (2 ));
319+ assertEquals ("0" , record .get (3 ));
320+ assertEquals ("pass sem1 _8" , record .get (4 ));
321+ assertEquals (5 , record .size ());
322+ // row 2
323+ record = parse (parser , failParseRecordNo );
324+ if (record == null ) {
325+ return ; // expected failure
326+ }
327+ assertEquals ("1414770318470" , record .get (0 ));
328+ assertEquals ("android.widget.EditText" , record .get (1 ));
329+ assertEquals ("pass sem1 _84:|" , record .get (2 ));
330+ assertEquals ("0" , record .get (3 ));
331+ assertEquals ("pass sem1 _84:\\ " , record .get (4 ));
332+ assertEquals (5 , record .size ());
333+ // row 3: Fail for certain
334+ assertThrows (IOException .class , () -> parser .nextRecord ());
335+ }
336+ }
337+
338+ private void testCSV141Ok (final CSVFormat format ) throws IOException {
339+ final Path path = Paths .get ("src/test/resources/org/apache/commons/csv/CSV-141/csv-141.csv" );
340+ try (final CSVParser parser = CSVParser .parse (path , StandardCharsets .UTF_8 , format )) {
341+ // row 1
342+ CSVRecord record = parser .nextRecord ();
343+ assertEquals ("1414770317901" , record .get (0 ));
344+ assertEquals ("android.widget.EditText" , record .get (1 ));
345+ assertEquals ("pass sem1 _84*|*" , record .get (2 ));
346+ assertEquals ("0" , record .get (3 ));
347+ assertEquals ("pass sem1 _8" , record .get (4 ));
348+ assertEquals (5 , record .size ());
349+ // row 2
350+ record = parser .nextRecord ();
351+ assertEquals ("1414770318470" , record .get (0 ));
352+ assertEquals ("android.widget.EditText" , record .get (1 ));
353+ assertEquals ("pass sem1 _84:|" , record .get (2 ));
354+ assertEquals ("0" , record .get (3 ));
355+ assertEquals ("pass sem1 _84:\\ " , record .get (4 ));
356+ assertEquals (5 , record .size ());
357+ // row 3
358+ record = parser .nextRecord ();
359+ assertEquals ("1414770318327" , record .get (0 ));
360+ assertEquals ("android.widget.EditText" , record .get (1 ));
361+ assertEquals ("pass sem1" , record .get (2 ));
362+ assertEquals (3 , record .size ());
363+ // row 4
364+ record = parser .nextRecord ();
365+ assertEquals ("1414770318628" , record .get (0 ));
366+ assertEquals ("android.widget.EditText" , record .get (1 ));
367+ assertEquals ("pass sem1 _84*|*" , record .get (2 ));
368+ assertEquals ("0" , record .get (3 ));
369+ assertEquals ("pass sem1" , record .get (4 ));
370+ assertEquals (5 , record .size ());
371+ }
372+ }
373+
374+ @ Test
375+ public void testCSV141RFC4180 () throws Exception {
376+ testCSV141Failure (CSVFormat .RFC4180 , 3 );
377+ }
378+
268379 @ Test
269380 public void testCSV235 () throws IOException {
270381 final String dqString = "\" aaa\" ,\" b\" \" bb\" ,\" ccc\" " ; // "aaa","b""bb","ccc"
0 commit comments