Skip to content

Commit 6cf25a8

Browse files
committed
test(security): prove UTF-16 truncation boundaries
1 parent 6a94d23 commit 6cf25a8

3 files changed

Lines changed: 65 additions & 68 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Covers bounded, untrusted channel metadata construction.
2+
import { describe, expect, it } from "vitest";
3+
import { buildUntrustedChannelMetadata } from "./channel-metadata.js";
4+
5+
function normalizeMarkerIds(value: string): string {
6+
return value.replace(/id="[a-f0-9]{16}"/g, 'id="<id>"');
7+
}
8+
9+
function wrapExpected(content: string): string {
10+
return [
11+
"",
12+
'<<<EXTERNAL_UNTRUSTED_CONTENT id="<id>">>>',
13+
"Source: Channel metadata",
14+
"---",
15+
content,
16+
'<<<END_EXTERNAL_UNTRUSTED_CONTENT id="<id>">>>',
17+
].join("\n");
18+
}
19+
20+
describe("buildUntrustedChannelMetadata", () => {
21+
it("keeps per-entry truncation UTF-16 safe", () => {
22+
const entryPrefix = "a".repeat(396);
23+
const result = buildUntrustedChannelMetadata({
24+
source: "test",
25+
label: "Test channel",
26+
entries: [`${entryPrefix}🎉tail`],
27+
});
28+
29+
expect(normalizeMarkerIds(result ?? "")).toBe(
30+
wrapExpected(`UNTRUSTED channel metadata (test)\nTest channel:\n${entryPrefix}...`),
31+
);
32+
});
33+
34+
it("keeps the combined metadata limit UTF-16 safe", () => {
35+
const header = "UNTRUSTED channel metadata (test)\nTest channel:\n";
36+
const entryPrefix = "short";
37+
const result = buildUntrustedChannelMetadata({
38+
source: "test",
39+
label: "Test channel",
40+
entries: [`${entryPrefix}🎉tail`],
41+
maxChars: header.length + entryPrefix.length + 4,
42+
});
43+
44+
expect(normalizeMarkerIds(result ?? "")).toBe(wrapExpected(`${header}${entryPrefix}...`));
45+
});
46+
});

src/security/install-policy.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,25 @@ describe("runInstallPolicy", () => {
355355
expect(warnings.join("\n")).toContain("blocked by install policy");
356356
});
357357

358+
it("keeps truncated operator block reasons UTF-16 safe", async () => {
359+
const reasonPrefix = "r".repeat(999);
360+
const result = await runInstallPolicy({
361+
config: configWithPolicy(scriptPath, {
362+
POLICY_RESPONSE: JSON.stringify({
363+
protocolVersion: 1,
364+
decision: "block",
365+
reason: `${reasonPrefix}🎉tail`,
366+
}),
367+
}),
368+
request: baseRequest(sourceDir),
369+
});
370+
371+
expect(result?.blocked).toEqual({
372+
code: "security_scan_blocked",
373+
reason: `blocked by install policy: ${reasonPrefix}...`,
374+
});
375+
});
376+
358377
it("preserves allow findings without file or line", async () => {
359378
const result = await runInstallPolicy({
360379
config: configWithPolicy(scriptPath, {

test/security/channel-metadata.test.ts

Lines changed: 0 additions & 68 deletions
This file was deleted.

0 commit comments

Comments
 (0)