mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
### What does this PR do?
Fixes #23489
The YAML parser was incorrectly treating `...` inside double-quoted
strings as document end markers, causing parse errors for strings
containing ellipsis, particularly affecting internationalized text.
### Example of the bug:
```yaml
balance: "👛 لا تمتلك محفظة... !"
```
This would fail with: `error: Unexpected document end`
### Root cause:
The bug was introduced in commit fcbd57ac48 which attempted to optimize
document marker detection by using `self.line_indent == .none` instead
of tracking newlines with a local flag. However, this check was
incomplete - it didn't track whether we had just processed a newline
character.
### The fix:
Restored the `nl` (newline) flag pattern from the single-quoted scanner
and combined it with the `line_indent` check. Document markers `...` and
`---` are now only recognized when **all** of these conditions are met:
1. We're after a newline (`nl == true`)
2. We're at column 0 (`self.line_indent == .none`)
3. Followed by whitespace or EOF
This allows `...` to appear freely in double-quoted strings while still
correctly recognizing actual document end markers at the start of lines.
### How did you verify your code works?
1. Reproduced the original issue from #23489
2. Applied the fix and verified all test cases pass:
- Original Arabic text with emoji: `"👛 لا تمتلك محفظة... !"`
- Various `...` positions: start, middle, end
- Both single and double quotes
- Multiline strings with indented `...` (issue #22392)
3. Created regression test in `test/regression/issue/23489.test.ts`
4. Verified existing YAML tests still pass (514 pass, up from 513)
cc @dylan-conway for review
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
59 lines
1.8 KiB
TypeScript
59 lines
1.8 KiB
TypeScript
import { YAML } from "bun";
|
|
import { expect, test } from "bun:test";
|
|
import { bunEnv, bunExe, tempDir } from "harness";
|
|
|
|
test("YAML double-quoted strings with ... should not trigger document end error - issue #23489", () => {
|
|
// Test the original failing case with Arabic text and emoji
|
|
const yaml1 = 'balance_dont_have_wallet: "👛 لا تمتلك محفظة... !"';
|
|
const result1 = YAML.parse(yaml1);
|
|
expect(result1).toEqual({
|
|
balance_dont_have_wallet: "👛 لا تمتلك محفظة... !",
|
|
});
|
|
|
|
// Test various patterns of ... in double-quoted strings
|
|
const yaml2 = `test1: "this has ... dots"
|
|
test2: "... at start"
|
|
test3: "at end ..."
|
|
test4: "👛 ... with emoji"`;
|
|
const result2 = YAML.parse(yaml2);
|
|
expect(result2).toEqual({
|
|
test1: "this has ... dots",
|
|
test2: "... at start",
|
|
test3: "at end ...",
|
|
test4: "👛 ... with emoji",
|
|
});
|
|
|
|
// Test that both single and double quotes work
|
|
const yaml3 = `single: 'this has ... dots'
|
|
double: "this has ... dots"`;
|
|
const result3 = YAML.parse(yaml3);
|
|
expect(result3).toEqual({
|
|
single: "this has ... dots",
|
|
double: "this has ... dots",
|
|
});
|
|
});
|
|
|
|
test("YAML import with double-quoted strings containing ... - issue #23489", async () => {
|
|
using dir = tempDir("yaml-ellipsis", {
|
|
"test.yml": 'balance: "👛 لا تمتلك محفظة... !"',
|
|
"test.ts": `
|
|
import yaml from "./test.yml";
|
|
console.log(JSON.stringify(yaml));
|
|
`,
|
|
});
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [bunExe(), "test.ts"],
|
|
env: bunEnv,
|
|
cwd: String(dir),
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
|
|
|
expect(stderr).not.toContain("Unexpected document end");
|
|
expect(exitCode).toBe(0);
|
|
expect(stdout.trim()).toBe('{"balance":"👛 لا تمتلك محفظة... !"}');
|
|
});
|