Files
gstack/test/osv-config-wiring.test.ts
Garry Tanandcapy-ai[bot] 9dea818e34 v1.91.122.0 fix(deps): clear the 2026-11-30 OSV suppressions, replace #3228, exempt dependabot from Version Gate rule 1 (#3239)
* fix(deps): clear the OSV suppressions that expire on 2026-11-30

Delete the hono, @anthropic-ai/sdk (#2754) and sprintf-js ignores, which the
lockfiles no longer match. Override image-size to 2.0.4 (#2753) and chokidar
to 4.0.3 in lib/diagram-render (drops braces), and delete those ignores.
Re-date katex to 2027-01-31: its fix is outside mermaid 11's range
(mermaid-js/mermaid#8388).

html-to-docx 1.8.0 bundles its own image-size 1.x, which the override cannot
reach and whose ICNS parser loops forever. make-pdf --to docx now hands it
only PNG, JPEG, GIF, WebP or SVG bytes. A golden docx test proves the Word
output is unchanged.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* build(deps-dev): @types/bun 1.4.3, prettier 3.9.10; hold the Anthropic SDKs to patches

Replaces dependabot #3228 without its agent-sdk 0.3 and sdk 0.133 bumps,
which break typecheck:test and overlay-sdk-cancel-eof. Their 0.x breaking
releases are semver-minor to dependabot, so the ignore covers minor and major.
@types/bun 1.4.3 retires 18 test type diagnostics; the baseline locks that in.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(ci): exempt dependabot dependency-manifest PRs from Version Gate rule 1

Dependabot never edits VERSION, so hard rule 1 failed every package.json PR
it opened. The workflow now passes the PR author and changed-file list; the
gate skips rule 1 only for dependabot[bot] when every file is a package.json,
bun.lock(b) or .github/dependabot.yml. A failed file lookup keeps the rule.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(make-pdf): guard every html-to-docx sizing path, keep non-ICNS formats

Review found three spellings that got past the regex guard and still hung
--to docx: a data-src decoy, a percent-encoded separator, and an unquoted
encoded colon. html-to-docx sizes images on three paths, and buildImage
URI-decodes the whole src first. The guard now mirrors all three, drops ICNS
(the only input its bundled image-size routes to the looping parser) instead
of allowlisting formats, so BMP and TIFF embed as before, and re-parses the
result with html-to-docx's own html-to-vdom to fail closed on anything the
regex misreads. The golden test tolerates CRLF checkouts on Windows.

Version Gate treats a failed file lookup as an empty list, so a partial
paginated result cannot decide the exemption.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* chore(release): stamp v1.91.121.0

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* chore(release): restamp v1.91.122.0

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-17 16:47:50 +00:00

62 lines
3.0 KiB
TypeScript

/**
* OSV scanner config wiring (#2679-wave / v1.78.0.0).
*
* The suppression file was inert from v1.65.0.0 to v1.78.0.0: OSV-Scanner
* only auto-discovers configs named `osv-scanner.toml` (no leading dot) and
* applies them PER-DIRECTORY — a repo-root config never covers
* lib/diagram-render/bun.lock. The workflow must therefore pass an explicit
* global `--config` naming the file that actually exists. These tests pin
* that three-way agreement (workflow flag ↔ file on disk ↔ entry hygiene) so
* the filename and the flag can never drift apart silently again.
*/
import { describe, expect, test } from "bun:test";
import * as fs from "node:fs";
import * as path from "node:path";
const ROOT = path.resolve(import.meta.dir, "..");
const WORKFLOW = path.join(ROOT, ".github", "workflows", "osv-scanner.yml");
const CONFIG = path.join(ROOT, ".osv-scanner.toml");
describe("osv-scanner config wiring", () => {
test("workflow passes an explicit --config (auto-discovery never covers nested lockfiles)", () => {
const wf = fs.readFileSync(WORKFLOW, "utf-8");
const m = wf.match(/--config=(\S+)/);
expect(m).not.toBeNull();
// The flag must name a file that exists at repo root.
expect(fs.existsSync(path.join(ROOT, m![1]))).toBe(true);
});
test("every IgnoredVulns entry has id, reason, and an ignoreUntil expiry", () => {
const cfg = fs.readFileSync(CONFIG, "utf-8");
const entries = cfg.split("[[IgnoredVulns]]").slice(1);
expect(entries.length).toBeGreaterThan(0);
for (const entry of entries) {
expect(entry).toMatch(/^id = "GHSA-/m);
expect(entry).toMatch(/^reason = ".{20,}/m);
// Suppressions must expire — a permanent exception is a silent hole.
expect(entry).toMatch(/^ignoreUntil = \d{4}-\d{2}-\d{2}/m);
}
});
test("ignoreUntil dates are TOML datetimes the scanner can parse (not strings)", () => {
const cfg = fs.readFileSync(CONFIG, "utf-8");
// TOML datetime is unquoted; a quoted date silently parses as a string
// and (depending on scanner version) may be ignored.
expect(cfg).not.toMatch(/ignoreUntil = "/);
});
test("the braces ignore stays true: the shipped diagram-render page carries no chokidar/braces code", () => {
const toml = fs.readFileSync(path.join(ROOT, ".osv-scanner.toml"), "utf8");
if (!toml.includes('id = "GHSA-vfj7-8cjw-p6xm"')) return;
const page = fs.readFileSync(path.join(ROOT, "lib", "diagram-render", "dist", "diagram-render.html"), "utf8");
expect(page).not.toMatch(/chokidar|FSWatcher/);
});
test("the chokidar override keeps braces (GHSA-vfj7-8cjw-p6xm, no fixed release) out of lib/diagram-render", () => {
const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, "lib", "diagram-render", "package.json"), "utf8"));
expect(pkg.overrides.chokidar).toMatch(/^4\./);
const lock = fs.readFileSync(path.join(ROOT, "lib", "diagram-render", "bun.lock"), "utf8");
expect(lock).toMatch(/"chokidar": \["chokidar@4\.\d+\.\d+"/);
expect(lock).not.toMatch(/"braces": \["braces@/);
});
});