Ruiqi Dong created CSV-328:
------------------------------

             Summary: CSVFormat.Builder#setNullString(...) builds 
quotedNullString with literal "null" when quote is disabled first
                 Key: CSV-328
                 URL: https://issues.apache.org/jira/browse/CSV-328
             Project: Commons CSV
          Issue Type: Bug
            Reporter: Ruiqi Dong


*Summary*

The latest `master` fixed one ordering of the quoted-null-string state update: 
if a builder first sets a null string and then disables the quote character, 
printing `null` with `QuoteMode.ALL` still writes `"NULL"`.

The reverse builder order is still broken. If the quote character is disabled 
first and the null string is set afterwards, `setNullString(...)` concatenates 
the nullable `quoteCharacter` field directly and produces `nullNULLnull`.
 
*Affected code*

File: `src/main/java/org/apache/commons/csv/CSVFormat.java`
{code:java}
public Builder setNullString(final String nullString) {
    this.nullString = nullString;
    this.quotedNullString = quoteCharacter + nullString + quoteCharacter;
    return this;
} {code}
`setQuote(...)` already applies a fallback quote character when 
`quoteCharacter` is `null`, but `setNullString(...)` does not:
{code:java}
public Builder setQuote(final Character quoteCharacter) {
    ...
    this.quoteCharacter = quoteCharacter;
    final Character quote = quoteCharacter != null ? quoteCharacter : 
Constants.DOUBLE_QUOTE_CHAR;
    this.quotedNullString = quote + nullString + quote;
    return this;
} {code}
*Reproducer*
Add this test to `src/test/java/org/apache/commons/csv/CSVFormatTest.java`:
{code:java}
@Test
void testQuotedNullStringTracksQuoteCharacterWhenNullStringIsSetLast() throws 
IOException {
    final StringBuilder out = new StringBuilder();
    final CSVFormat format = CSVFormat.DEFAULT.builder()
            .setQuoteMode(QuoteMode.ALL)
            .setQuote((Character) null)
            .setNullString("NULL")
            .get();

    format.print(null, out, true);
    assertEquals("\"NULL\"", out.toString());
} {code}
Run:
{code:java}
mvn -q 
-Dtest=org.apache.commons.csv.CSVFormatTest#testQuotedNullStringTracksQuoteCharacterWhenNullStringIsSetLast
 test {code}
Observed behavior
The test fails:
{code:java}
expected: <"NULL"> but was: <nullNULLnull> {code}
*Expected behavior* 
The builder should produce the same `quotedNullString` state regardless of 
whether callers configure `setQuote(null)` before or after 
`setNullString("NULL")`. This is consistent with the existing upstream test 
that expects `setQuote(null)` after `setNullString("NULL")` to print `"NULL"` 
with `QuoteMode.ALL`.
 
Both builder call orders describe the same final configuration, but one order 
produces an invalid quoted null literal containing Java's `"null"` string 
instead of quote characters.
 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to