Skip to content

▚▚ fix(jsonc): keep commas inside string values when reading settings - #32

Open
breken-ai wants to merge 1 commit into
zenbu-labs:mainfrom
breken-ai:fix/jsonc-comma-in-string
Open

breken-ai wants to merge 1 commit into
zenbu-labs:mainfrom
breken-ai:fix/jsonc-comma-in-string

Conversation

@breken-ai

Copy link
Copy Markdown

parseJsonc alters string values when it reads a settings, keybindings or theme file: a comma inside a string that happens to sit before } or ] is deleted. A regex setting such as "([^,]+)" comes back as "([^]+)", a glob "**/*.{js,}" as "**/*.{js}", a snippet-style "[a, ]" as "[a ]". tode --import then writes the altered value into the tode profile, and the keybindings / theme readers see it too.

Root cause

parseJsonc (src/jsonc.ts) walks the text once, dropping comments and copying string literals through whole, and then removes trailing commas with out.replace(/,(\s*[}\]])/g, "$1") over the entire result. That regex cannot tell a structural comma from one inside a string, so ,] and ,} sequences inside string literals are rewritten before JSON.parse runs.

Fix

  • src/jsonc.ts: handle the trailing comma during the walk instead of with a regex afterwards. When the walker meets a , outside a string, it looks past whitespace and comments with the existing skipTrivia helper; if the next token is } or ] the comma is dropped, otherwise it is kept. Strings are consumed whole before this branch, so their contents are never touched. The replace call is removed and JSON.parse(out) is used directly.

Tests

  • test/theme.test.js: new test "jsonc reading leaves a comma inside a string alone" feeds an object with "([^,]+)", "[a, ]", "**/*.{js,}" and an array holding "ctrl+," and "x, ]", with real trailing commas after the last value and the last array element. Without the fix it fails with every in-string comma removed; with it the values round-trip and the trailing commas are still stripped.
  • The existing "survives comments and trailing commas" and "handles a keybindings array" tests keep passing, so comma-then-comment-then-close and array trailing commas still behave.
  • Full suite: 119/119; npm run typecheck clean.

Not changed

setKey / readKey / locate already tokenise strings correctly and were not touched. readString still drops the backslash of an escape when building the value it compares keys against; that only affects key lookup for escaped key names and is out of scope here.


▚▚ Shipped by breken — self-healing software. This one's on us. breken.ai

parseJsonc removed trailing commas with a regex over the whole text after
strings had been copied through verbatim, so a comma inside a string that
was followed by `}` or `]` was deleted too: a regex like `[^,]+` in a
setting became `[^]+`, `[a, ]` became `[a ]`, and `**/*.{js,}` became
`**/*.{js}`. Every reader of settings.json, keybindings.json and theme
files (tode --import, removalMasked, foreignBindings, tode --theme) saw
the altered value.

Drop the comma while walking the text instead: a comma is trailing only
when the next token past whitespace and comments closes the container,
and strings never reach that branch because they are consumed whole.
@vercel

vercel Bot commented Sep 14, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the zenbu-labs Team on Vercel.

A member of the Team first needs to authorize it.

This branch has not been deployed

No deployments
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.

1 participant