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 '"' + (

View File

@@ -204,6 +204,89 @@ class TomlIntegrationTests:
assert "scripts:" not in parsed["prompt"]
assert "---" not in parsed["prompt"]
def test_toml_no_ambiguous_closing_quotes(self, tmp_path, monkeypatch):
"""Multiline body ending with `"` must not produce `""""` (#2113)."""
i = get_integration(self.KEY)
template = tmp_path / "sample.md"
template.write_text(
"---\n"
"description: Test\n"
"scripts:\n"
" sh: echo ok\n"
"---\n"
"Check the following:\n"
'- Correct: "Is X clearly specified?"\n',
encoding="utf-8",
)
monkeypatch.setattr(i, "list_command_templates", lambda: [template])
m = IntegrationManifest(self.KEY, tmp_path)
created = i.setup(tmp_path, m)
cmd_files = [f for f in created if "scripts" not in f.parts]
assert len(cmd_files) == 1
raw = cmd_files[0].read_text(encoding="utf-8")
assert '""""' not in raw, "closing delimiter must not merge with body quote"
assert '"""\n' in raw, "body must use multiline basic string"
parsed = tomllib.loads(raw)
assert parsed["prompt"].endswith('specified?"')
assert not parsed["prompt"].endswith("\n"), "parsed value must not gain a trailing newline"
def test_toml_triple_double_and_single_quote_ending(self, tmp_path, monkeypatch):
"""Body containing `\"\"\"` and ending with `'` falls back to escaped basic string."""
i = get_integration(self.KEY)
template = tmp_path / "sample.md"
template.write_text(
"---\n"
"description: Test\n"
"scripts:\n"
" sh: echo ok\n"
"---\n"
'Use """triple""" quotes\n'
"and end with 'single'\n",
encoding="utf-8",
)
monkeypatch.setattr(i, "list_command_templates", lambda: [template])
m = IntegrationManifest(self.KEY, tmp_path)
created = i.setup(tmp_path, m)
cmd_files = [f for f in created if "scripts" not in f.parts]
assert len(cmd_files) == 1
raw = cmd_files[0].read_text(encoding="utf-8")
assert "''''" not in raw, "literal string must not produce ambiguous closing quotes"
parsed = tomllib.loads(raw)
assert parsed["prompt"].endswith("'single'")
assert '"""triple"""' in parsed["prompt"]
assert not parsed["prompt"].endswith("\n"), "parsed value must not gain a trailing newline"
def test_toml_closing_delimiter_inline_when_safe(self, tmp_path, monkeypatch):
"""Body NOT ending with `"` keeps closing `\"\"\"` inline (no extra newline)."""
i = get_integration(self.KEY)
template = tmp_path / "sample.md"
template.write_text(
"---\n"
"description: Test\n"
"scripts:\n"
" sh: echo ok\n"
"---\n"
"Line one\n"
"Plain body content\n",
encoding="utf-8",
)
monkeypatch.setattr(i, "list_command_templates", lambda: [template])
m = IntegrationManifest(self.KEY, tmp_path)
created = i.setup(tmp_path, m)
cmd_files = [f for f in created if "scripts" not in f.parts]
assert len(cmd_files) == 1
raw = cmd_files[0].read_text(encoding="utf-8")
parsed = tomllib.loads(raw)
assert parsed["prompt"] == "Line one\nPlain body content"
assert raw.rstrip().endswith('content"""'), \
"closing delimiter should be inline when body does not end with a quote"
def test_toml_is_valid(self, tmp_path):
"""Every generated TOML file must parse without errors."""
i = get_integration(self.KEY)