test(ui): pin CRLF source slices to the index line numbering (CG-42)
A CRLF file must come back with the graph's own line numbers and without a trailing carriage return on every line — the case a Windows checkout with core.autocrlf produces. It is decided by bytes rather than by the OS, so it is covered here rather than only on the VM. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
951ba3678a
commit
e7288ffa36
@@ -192,6 +192,15 @@ ${callers}
|
||||
`
|
||||
);
|
||||
|
||||
// CRLF on purpose: tree-sitter numbers rows by `\n`, so a CRLF file must come
|
||||
// back with the same line numbers the graph recorded — and without the stray
|
||||
// `\r` rendering at the end of every line. This is what a Windows checkout
|
||||
// with core.autocrlf looks like, and it is decided by bytes, not by the OS.
|
||||
fs.writeFileSync(
|
||||
path.join(srcDir, 'crlf.ts'),
|
||||
['export function windowsStyle(n: number): number {', ' return n + 1;', '}', ''].join('\r\n')
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(testsDir, 'service.test.ts'),
|
||||
`import { Service } from '../src/service';
|
||||
@@ -613,6 +622,27 @@ describe('GET /api/source', () => {
|
||||
expect(body.lines).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('keeps a CRLF file on the index line numbering, without the stray carriage returns', async () => {
|
||||
const node = await getJson(`/api/node/${await idOf('windowsStyle', 'function')}`);
|
||||
expect(node.node.file).toBe('src/crlf.ts');
|
||||
|
||||
const body = await getJson('/api/source?file=src/crlf.ts');
|
||||
expect(body.drift).toBe(false);
|
||||
expect(body.totalLines).toBe(3);
|
||||
expect(body.lines).toEqual([
|
||||
'export function windowsStyle(n: number): number {',
|
||||
' return n + 1;',
|
||||
'}',
|
||||
]);
|
||||
expect(body.lines.some((l: string) => l.includes('\r'))).toBe(false);
|
||||
|
||||
// The symbol's indexed range still names its own body.
|
||||
const slice = await getJson(
|
||||
`/api/source?file=src/crlf.ts&from=${node.node.line}&to=${node.node.endLine}`
|
||||
);
|
||||
expect(slice.lines[0]).toContain('windowsStyle');
|
||||
});
|
||||
|
||||
it('refuses a path that escapes the project', async () => {
|
||||
const traversal = await getStatusAndJson(
|
||||
'/api/source?file=' + encodeURIComponent('../../../etc/passwd')
|
||||
|
||||
Reference in New Issue
Block a user