Skip to content

Commit 76130fd

Browse files
committed
fix: parse tar verbose sizes strictly
1 parent 73168d3 commit 76130fd

2 files changed

Lines changed: 35 additions & 10 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { describe, expect, it } from "vitest";
2+
import { parseTarVerboseMetadata } from "./skills-install-tar-verbose.js";
3+
4+
describe("parseTarVerboseMetadata", () => {
5+
it("parses BSD and GNU tar verbose sizes", () => {
6+
expect(parseTarVerboseMetadata("-rw-r--r-- 0 user group 123 Jan 01 00:00 SKILL.md")).toEqual([
7+
{ type: "File", size: 123 },
8+
]);
9+
expect(parseTarVerboseMetadata("-rw-r--r-- user/group 456 2026-05-28 00:00 SKILL.md")).toEqual([
10+
{ type: "File", size: 456 },
11+
]);
12+
});
13+
14+
it("rejects partial or unsafe tar verbose size tokens", () => {
15+
expect(() =>
16+
parseTarVerboseMetadata("-rw-r--r-- 0 user group 123abc Jan 01 00:00 SKILL.md"),
17+
).toThrow(/unable to parse tar entry size/u);
18+
expect(() =>
19+
parseTarVerboseMetadata("-rw-r--r-- user/group 9007199254740993 2026-05-28 00:00 SKILL.md"),
20+
).toThrow(/unable to parse tar entry size/u);
21+
});
22+
});

src/agents/skills-install-tar-verbose.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,28 @@ function parseTarVerboseSize(line: string): number {
4545

4646
let dateIndex = tokens.findIndex((token) => TAR_VERBOSE_MONTHS.has(token));
4747
if (dateIndex > 0) {
48-
const size = Number.parseInt(tokens[dateIndex - 1] ?? "", 10);
49-
if (!Number.isFinite(size) || size < 0) {
50-
throw new Error(`unable to parse tar entry size: ${line}`);
51-
}
52-
return size;
48+
return parseTarSizeToken(tokens[dateIndex - 1] ?? "", line);
5349
}
5450

5551
dateIndex = tokens.findIndex((token) => ISO_DATE_PATTERN.test(token));
5652
if (dateIndex > 0) {
57-
const size = Number.parseInt(tokens[dateIndex - 1] ?? "", 10);
58-
if (!Number.isFinite(size) || size < 0) {
59-
throw new Error(`unable to parse tar entry size: ${line}`);
60-
}
61-
return size;
53+
return parseTarSizeToken(tokens[dateIndex - 1] ?? "", line);
6254
}
6355

6456
throw new Error(`unable to parse tar verbose metadata: ${line}`);
6557
}
6658

59+
function parseTarSizeToken(raw: string, line: string): number {
60+
if (!/^\d+$/.test(raw)) {
61+
throw new Error(`unable to parse tar entry size: ${line}`);
62+
}
63+
const size = Number(raw);
64+
if (!Number.isSafeInteger(size)) {
65+
throw new Error(`unable to parse tar entry size: ${line}`);
66+
}
67+
return size;
68+
}
69+
6770
export function parseTarVerboseMetadata(stdout: string): Array<{ type: string; size: number }> {
6871
const lines = normalizeStringEntries(stdout.split("\n"));
6972
return lines.map((line) => {

0 commit comments

Comments
 (0)