Skip to content

fix(csv-stringify): preserve field contents when quoting is disabled - #558

Merged
wdavidw merged 2 commits into
adaltas:masterfrom
asssslay:fix/stringify-disabled-quote
Nov 3, 2026
Merged

wdavidw merged 2 commits into
adaltas:masterfrom
asssslay:fix/stringify-disabled-quote

Conversation

@asssslay

@asssslay asssslay commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Disabling quoting can still change field contents. If a delimiter, newline or quoting selector sets shouldQuote, escape characters are doubled even though the field is surrounded by an empty quote string. This contradicts the documented disabled-quoting behavior and the type declaration's promise to preserve the original field.

Reproduces on csv-stringify 6.9.0 and the parent revision, including this delimiter-free case:

import { stringify } from "csv-stringify/sync";

stringify([['say "hi"']], { quote: false, quoted: true });
// Before: 'say ""hi""\n'
// After:  'say "hi"\n'

Only double escape characters when the normalized quote string is nonempty. This also preserves custom escape characters and quotes supplied by a cast that sets { quote: false } for an individual field.

All six new regressions fail before the fix and pass afterward. They cover false and empty-string quote settings, delimiters and line breaks, quoting selectors, field-level cast options, custom escapes and callback output. Generated distributions were rebuilt and checked, and are left to the release build process.

Related to #516, which moves the character checks after formula-prefix insertion while retaining this escape-doubling condition. This change adds the missing disabled-quote guard to that condition.

@wdavidw
wdavidw merged commit 4dcb75e into adaltas:master Nov 3, 2026
@wdavidw

wdavidw commented Nov 5, 2026

Copy link
Copy Markdown
Member

I am having second though about this feature. As such, I will revert the changes.

  1. It goes agains RFC 4180 in Section 2, rule 5, which states “If fields are not enclosed with double quotes, then double quotes may not appear inside the fields.”. Note, RFC 4180 is the IETF memo for CSV and may be considered as a reference while being only "informational".

  2. Accepting it breaks the reverse compatibility with csv parse. Basically, the following shall be true:

parse(stringify(parse(text, options), options), options).should.eql(parse(text, options))
  1. The generated output is structurally different from its input. For example, in the test "preserves special characters when quoting is disabled", the input contains 2 records when the output contains 3 records.

I am open for an alternative solution :

  1. It must respect point 3 and preserve the structure
  2. It must be activated with the same option relax_quotes as in the parser

@wdavidw

wdavidw commented Nov 5, 2026

Copy link
Copy Markdown
Member

@asssslay I just noticed your new PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants