From 2b4b892dc0353b294385b8455f213f6d2151b5a5 Mon Sep 17 00:00:00 2001 From: Ebil Jacob Date: Mon, 24 Aug 2026 08:32:21 +0000 Subject: [PATCH 1/3] Added vscode dev container setup file to repo --- .devcontainer/devcontainer.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..5f09ee21 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,4 @@ +{ + "name": "Opencode", + "image": "oven/bun:1.3.0" +} \ No newline at end of file From 2a44327239cea71e6a597f742993117b54372449 Mon Sep 17 00:00:00 2001 From: Ebil Jacob Date: Mon, 31 Aug 2026 19:34:13 +0000 Subject: [PATCH 2/3] Refactored long ternary chain into a Record lookup. Removed a dead code path checking regex output. --- packages/app/src/context/file/path.ts | 36 +++++++++------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/packages/app/src/context/file/path.ts b/packages/app/src/context/file/path.ts index 2bc4bde5..b93e5e16 100644 --- a/packages/app/src/context/file/path.ts +++ b/packages/app/src/context/file/path.ts @@ -21,6 +21,16 @@ export function unquoteGitPath(input: string) { if (!input.endsWith('"')) return input const body = input.slice(1, -1) const bytes: number[] = [] + const ESCAPE_MAP: Record = { + "n": "\n", + "r": "\r", + "t": "\t", + "b": "\b", + "f": "\f", + "v": "\v", + "\\": "\\", + '"': '"', + }; for (let i = 0; i < body.length; i++) { const char = body[i]! @@ -37,35 +47,13 @@ export function unquoteGitPath(input: string) { if (next >= "0" && next <= "7") { const chunk = body.slice(i + 1, i + 4) - const match = chunk.match(/^[0-7]{1,3}/) - if (!match) { - bytes.push(next.charCodeAt(0)) - i++ - continue - } + const match = chunk.match(/^[0-7]{1,3}/)! bytes.push(parseInt(match[0], 8)) i += match[0].length continue } - const escaped = - next === "n" - ? "\n" - : next === "r" - ? "\r" - : next === "t" - ? "\t" - : next === "b" - ? "\b" - : next === "f" - ? "\f" - : next === "v" - ? "\v" - : next === "\\" || next === '"' - ? next - : undefined - - bytes.push((escaped ?? next).charCodeAt(0)) + bytes.push((ESCAPE_MAP[next] ?? next).charCodeAt(0)) i++ } From bc42b164e9a11cbd3ce6ebbf37c4fe06a77a955b Mon Sep 17 00:00:00 2001 From: Ebil Jacob Date: Mon, 31 Aug 2026 19:34:52 +0000 Subject: [PATCH 3/3] Added comprehensive testing for updated unquoteGitPath() function. Achieves 100% function coverage. --- packages/app/src/context/file/path.test.ts | 55 +++++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/packages/app/src/context/file/path.test.ts b/packages/app/src/context/file/path.test.ts index 99dd88ae..fd0d67bd 100644 --- a/packages/app/src/context/file/path.test.ts +++ b/packages/app/src/context/file/path.test.ts @@ -50,10 +50,61 @@ describe("file path helpers", () => { expect(stripQueryAndHash("a/b.ts")).toBe("a/b.ts") }) + test("unquotes all named escape sequences", () => { + expect(unquoteGitPath('"new\\nline"')).toBe("new\nline") + expect(unquoteGitPath('"tab\\tend"')).toBe("tab\tend") + expect(unquoteGitPath('"cr\\rend"')).toBe("cr\rend") + expect(unquoteGitPath('"backspace\\bend"')).toBe("backspace\bend") + expect(unquoteGitPath('"formfeed\\fend"')).toBe("formfeed\fend") + expect(unquoteGitPath('"vtab\\vend"')).toBe("vtab\vend") + expect(unquoteGitPath('"back\\\\slash"')).toBe("back\\slash") + expect(unquoteGitPath('"quo\\"te"')).toBe('quo"te') + }) + + test("returns input unchanged when not fully wrapped in quotes", () => { + expect(unquoteGitPath('"unterminated')).toBe('"unterminated') + expect(unquoteGitPath('unwrapped"')).toBe('unwrapped"') + expect(unquoteGitPath("a/b/c.ts")).toBe("a/b/c.ts") + }) + + test("preserves a trailing lone backslash", () => { + expect(unquoteGitPath('"trailing\\"')).toBe("trailing\\") + }) + test("unquotes git escaped octal path strings", () => { expect(unquoteGitPath('"a/\\303\\251.txt"')).toBe("a/\u00e9.txt") - expect(unquoteGitPath('"plain\\nname"')).toBe("plain\nname") - expect(unquoteGitPath("a/b/c.ts")).toBe("a/b/c.ts") + }) + + test("unquotes single and double digit octal escapes", () => { + expect(unquoteGitPath('"\\7"')).toBe("\u0007") + expect(unquoteGitPath('"\\41"')).toBe("!") + }) + + test("unquotes multiple octal escapes in one string", () => { + expect(unquoteGitPath('"\\303\\251\\303\\251.txt"')).toBe("\u00e9\u00e9.txt") + }) + + test("stops octal match at a non-octal digit", () => { + // "8" is not a valid octal digit, so \18 should decode \1 as octal + // and then treat "8" as a separate literal character + expect(unquoteGitPath('"\\18"')).toBe("\u00018") + }) + + test("returns the literal character for unrecognized escape sequences", () => { + expect(unquoteGitPath('"foo\\xbar"')).toBe("fooxbar") + }) + + test("returns the literal character for unrecognized escape sequences with digits outside octal range", () => { + expect(unquoteGitPath('"foo\\8bar"')).toBe("foo8bar") + expect(unquoteGitPath('"foo\\9bar"')).toBe("foo9bar") + }) + + test("preserves a trailing lone backslash", () => { + expect(unquoteGitPath('"trailing\\"')).toBe("trailing\\") + }) + + test("preserves a trailing lone backslash after other content", () => { + expect(unquoteGitPath('"a\\\\b\\"')).toBe("a\\b\\") }) })