ef28746fa743

assert PB-26-314 as an expected-failure trip-wire and skip web-accessible-resource assertions when build artifacts are absent (v5.0.106)

time
2026-09-05 05:49 UTC · 1 month ago
machine
koh2
agent
hy4-preview
session
close PB-26-314 test and findings register
parent
c083a658d3e6
2 files scripts/ci.ts+7 −4scripts/web-accessible-resources.test.ts+55 −19
scripts/ci.ts+7 −4
@@ -42,10 +42,6 @@4242     cmd: ['npm', 'run', 'lint'],4343   },4444   {45-    name: 'Tests',46-    cmd: ['npm', 'test', '--', '--reporter=verbose'],47-  },48-  {4945     // PB-26-003: rebuild the Noise WASM from crypto-core and fail if the5046     // committed blob drifts — "reviewed source → shipped binary" enforced.5147     name: 'Noise WASM provenance',@@ -58,6 +54,13 @@5854   {5955     name: 'Firefox build',6056     cmd: ['npm', 'run', 'build:firefox'],57+  },58+  {59+    // Runs after both builds: the web-accessible-resource assertions read the60+    // shipped dist-chrome/ and dist-firefox/ manifests, so a Tests step ahead61+    // of the builds would skip them on a clean checkout.62+    name: 'Tests',63+    cmd: ['npm', 'test', '--', '--reporter=verbose'],6164   },6265   ...(RUN_FIREFOX_SENDER_ONLY6366     ? [{

view file

scripts/web-accessible-resources.test.ts+55 −19
@@ -1,4 +1,4 @@1-import { readFileSync } from "node:fs";1+import { existsSync, readFileSync } from "node:fs";22 import { resolve } from "node:path";33 import { describe, expect, it } from "vitest";44 @@ -12,29 +12,65 @@1212   web_accessible_resources?: WebAccessibleResource[];1313 };1414 15+// dist-chrome/ and dist-firefox/ are kohignored build outputs, so a clean16+// checkout has no manifest to read. scripts/ci.ts builds both targets before17+// the test step; with no artifacts present these suites skip instead of18+// throwing ENOENT and passing/failing on nothing.19+function manifestPath(target: "chrome" | "firefox"): string {20+  return resolve(process.cwd(), `dist-${target}`, "manifest.json");21+}22+1523 function readManifest(target: "chrome" | "firefox"): ExtensionManifest {16-  const directory = target === "chrome" ? "dist-chrome" : "dist-firefox";1724   return JSON.parse(18-    readFileSync(resolve(process.cwd(), directory, "manifest.json"), "utf8"),25+    readFileSync(manifestPath(target), "utf8"),1926   ) as ExtensionManifest;2027 }2128 22-describe("shipped web-accessible resources", () => {23-  it("allows Chrome content-script chunks from stable extension URLs", () => {24-    const resources = readManifest("chrome").web_accessible_resources ?? [];29+const HASHED_ASSET = /^assets\/[^/]+-[A-Za-z0-9_-]+\.(?:js|css)$/;2530 26-    expect(resources).toHaveLength(1);27-    expect(resources[0]?.use_dynamic_url).toBe(false);28-    expect(resources[0]?.matches).toEqual(["<all_urls>"]);29-    expect(resources[0]?.resources.length).toBeGreaterThan(0);30-  });31+describe.skipIf(!existsSync(manifestPath("chrome")))(32+  "shipped Chrome web-accessible resources",33+  () => {34+    it("scopes page-reachable resources to content-hashed asset chunks", () => {35+      const resources = readManifest("chrome").web_accessible_resources ?? [];3136 32-  it("keeps Firefox resources limited to content-script chunks with content hashes", () => {33-    const resources = readManifest("firefox").web_accessible_resources ?? [];34-    const files = resources.flatMap((entry) => entry.resources);37+      expect(resources).toHaveLength(1);38+      expect(resources[0]?.matches).toEqual(["<all_urls>"]);39+      expect(resources[0]?.resources.length).toBeGreaterThan(0);40+      expect(41+        resources[0]?.resources.every((file) => HASHED_ASSET.test(file)),42+      ).toBe(true);43+    });3544 36-    expect(files.length).toBeGreaterThan(0);37-    expect(files.every((file) => /^assets\/[^/]+-[A-Za-z0-9_-]+\.(?:js|css)$/.test(file))).toBe(true);38-    expect(files.every((file) => !file.includes("<dynamic_resource>"))).toBe(true);39-  });40-});45+    // PB-26-314 is OPEN, not accepted. use_dynamic_url was enabled once and46+    // reverted at v5.0.100 (save e1c5043e4311) because Chrome then denied the47+    // dependent content-script chunks from page contexts, breaking the form48+    // icons. This stays an expected failure so that enabling the flag turns49+    // the suite red instead of silently shipping the finding.50+    it.fails(51+      "PB-26-314 (OPEN): Chrome serves web-accessible resources from a per-install dynamic URL",52+      () => {53+        const resources =54+          readManifest("chrome").web_accessible_resources ?? [];55+56+        expect(resources[0]?.use_dynamic_url).toBe(true);57+      },58+    );59+  },60+);61+62+describe.skipIf(!existsSync(manifestPath("firefox")))(63+  "shipped Firefox web-accessible resources",64+  () => {65+    it("keeps Firefox resources limited to content-script chunks with content hashes", () => {66+      const resources = readManifest("firefox").web_accessible_resources ?? [];67+      const files = resources.flatMap((entry) => entry.resources);68+69+      expect(files.length).toBeGreaterThan(0);70+      expect(files.every((file) => HASHED_ASSET.test(file))).toBe(true);71+      expect(files.every((file) => !file.includes("<dynamic_resource>"))).toBe(72+        true,73+      );74+    });75+  },76+);

view file