@@ -569,6 +569,57 @@ void testEscapeBackslash5() throws IOException {
569569 assertEquals ("\\ \\ " , sw .toString ());
570570 }
571571
572+ @ Test
573+ void testEscapeCommentMarkerFirstChar () throws IOException {
574+ // No quoting available in escape mode, so a leading comment marker must be escaped or the
575+ // record reads back as a comment and is dropped. Mirrors the quoting fix for QuoteMode.MINIMAL.
576+ final CSVFormat format = CSVFormat .DEFAULT .builder ().setQuote (null ).setEscape ('\\' ).setCommentMarker (';' ).get ();
577+ final StringWriter sw = new StringWriter ();
578+ final String col1 = ";comment-like" ;
579+ try (CSVPrinter printer = new CSVPrinter (sw , format )) {
580+ printer .printRecord (col1 , "b" );
581+ printer .printRecord (new StringReader (col1 ), new StringReader ("b" ));
582+ // The marker past the first character does not start a comment and is left alone.
583+ printer .printRecord ("a;b" , ";c" );
584+ }
585+ final String string = sw .toString ();
586+ assertEquals ("\\ ;comment-like,b" + RECORD_SEPARATOR +
587+ "\\ ;comment-like,b" + RECORD_SEPARATOR +
588+ "a;b,\\ ;c" + RECORD_SEPARATOR , string );
589+ // The emitted records must read back as the original values, none parsed as a comment.
590+ try (CSVParser parser = CSVParser .parse (string , format )) {
591+ final List <CSVRecord > records = parser .getRecords ();
592+ assertEquals (3 , records .size ());
593+ assertEquals (col1 , records .get (0 ).get (0 ));
594+ assertEquals ("b" , records .get (0 ).get (1 ));
595+ assertEquals (col1 , records .get (1 ).get (0 ));
596+ assertEquals ("b" , records .get (1 ).get (1 ));
597+ assertEquals ("a;b" , records .get (2 ).get (0 ));
598+ assertEquals (";c" , records .get (2 ).get (1 ));
599+ }
600+ }
601+
602+ @ Test
603+ void testEscapeCommentMarkerFirstCharWithQuoteModeNone () throws IOException {
604+ final CSVFormat format = CSVFormat .DEFAULT .builder ().setEscape ('\\' ).setQuoteMode (QuoteMode .NONE ).setCommentMarker (';' ).get ();
605+ final StringWriter sw = new StringWriter ();
606+ final String col1 = ";bar" ;
607+ try (CSVPrinter printer = new CSVPrinter (sw , format )) {
608+ printer .printRecord (col1 , "b" );
609+ printer .printRecord (new StringReader (col1 ), new StringReader ("b" ));
610+ }
611+ final String string = sw .toString ();
612+ assertEquals ("\\ ;bar,b" + RECORD_SEPARATOR + "\\ ;bar,b" + RECORD_SEPARATOR , string );
613+ try (CSVParser parser = CSVParser .parse (string , format )) {
614+ final List <CSVRecord > records = parser .getRecords ();
615+ assertEquals (2 , records .size ());
616+ for (final CSVRecord record : records ) {
617+ assertEquals (col1 , record .get (0 ));
618+ assertEquals ("b" , record .get (1 ));
619+ }
620+ }
621+ }
622+
572623 @ Test
573624 void testEscapeNull1 () throws IOException {
574625 final StringWriter sw = new StringWriter ();
0 commit comments