fix: prevent ambiguous TOML closing quotes when body ends with " (#2113) (#2115)

* fix: prevent ambiguous TOML closing quotes when body ends with `"` (#2113)

_render_toml_string placed the closing `"""` inline with content, so
a body ending with `"` produced `""""` (four consecutive quotes).
While technically valid TOML 1.0, this breaks stricter parsers such as
Gemini CLI v0.27.2.

Insert a newline before the closing delimiter when the body ends with a
quote character. Same treatment for the single-quote (`'''`) fallback.

Adds both a positive test (body ending with `"` must not produce
`""""`) and a negative test (safe bodies keep the inline delimiter).

* fix: use line-ending backslash instead of newline for TOML closing delimiters

Address PR review feedback:
- Replace sep=newline with TOML line-ending backslash so the parsed
  value does not gain a trailing newline when body ends with a quote.
- For literal string (''') fallback, skip to escaped basic string when
  value ends with single quote instead of inserting a newline.
- Make test body multiline so it exercises the """ rendering path,
  and assert no trailing newline in parsed value.

* test: cover escaped basic-string fallback when body has triple-quotes and ends with single-quote

Addresses review feedback from PR #2115: adds test for the branch
where the body contains '"""' and ends with "'", which forces
_render_toml_string() through the escaped basic-string fallback
instead of the '''...''' literal-string path (since ''''  would
produce the same ambiguous-closing-delimiter problem).
This commit is contained in:
Manfred Riem
2026-04-07 12:58:43 -05:00
committed by GitHub
parent 6536bc4102
commit 40fb276023
2 changed files with 86 additions and 1 deletions

View File

@@ -597,8 +597,10 @@ class TomlIntegration(IntegrationBase):
escaped = value.replace("\\", "\\\\")
if '"""' not in escaped:
if escaped.endswith('"'):
return '"""\n' + escaped + '\\\n"""'
return '"""\n' + escaped + '"""'
if "'''" not in value:
if "'''" not in value and not value.endswith("'"):
return "'''\n" + value + "'''"
return '"' + (