mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-20 03:42:24 +02:00
* feat(cso): add verified audits and replayable repair bundles * fix(cso): harden qualification and setup boundaries * fix(cso): assemble security canaries at runtime * fix(cso): bound release proof and maintenance work Co-Authored-By: OpenAI Codex <noreply@openai.com> * fix(cso): require complete evaluation reports Co-Authored-By: OpenAI Codex <noreply@openai.com> * fix(cso): replay expired snapshots from supplied source Co-Authored-By: OpenAI Codex <noreply@openai.com> * test(cso): synchronize DNS cancellation assertion Co-Authored-By: OpenAI Codex <noreply@openai.com> * chore(ship): exempt repository owner from liveness proof Co-Authored-By: OpenAI Codex <noreply@openai.com> * test(cso): make recheck retention overlap deterministic Co-Authored-By: OpenAI Codex <noreply@openai.com> * chore: bump version and changelog (v1.85.0.0) Co-Authored-By: OpenAI Codex <noreply@openai.com> * fix(cso): pass native release gates Co-Authored-By: OpenAI Codex <noreply@openai.com> * chore: move release to v1.86.0.0 Co-Authored-By: OpenAI Codex <noreply@openai.com> * fix(cso): resolve rechecks by finding Co-Authored-By: OpenAI Codex <noreply@openai.com> * chore: move release to v1.87.0.0 Co-Authored-By: OpenAI Codex <noreply@openai.com> * fix(cso): pass macOS and Windows release gates Normalize BSD wc output, compare Windows paths by filesystem identity, preserve portable snapshot race coverage, and narrow POSIX-only Windows fixtures. Co-Authored-By: OpenAI Codex <noreply@openai.com> * fix(cso): harden native verification gates * fix(cso): refine Windows native diagnostics * test(cso): isolate Windows Git startup failure * test(cso): stabilize Windows native diagnostics * fix(cso): support hardened Git on Windows * fix(cso): close final verification gaps * test(cso): bound cold Docker fixture setup * fix(cso): restore cross-platform free-suite gates --------- Co-authored-by: OpenAI Codex <noreply@openai.com>
85 lines
3.4 KiB
TypeScript
85 lines
3.4 KiB
TypeScript
/**
|
|
* Regression test for PR #1169 bug #7 — `pdf --from-file` ran JSON.parse on
|
|
* user-supplied file contents with no try/catch. A malformed payload crashed
|
|
* the pdf handler with a raw SyntaxError. Codex flagged that JSON.parse
|
|
* accepts primitives too (numbers, strings, null) and Array.isArray must be
|
|
* checked separately, so the fix added an explicit object-shape gate.
|
|
*
|
|
* Test surface: parsePdfFromFile, exported for tests at meta-commands.ts:139.
|
|
* Fixtures use the system temp directory, which SAFE_DIRECTORIES allows on
|
|
* every supported platform and which keeps transient files out of the repo.
|
|
*/
|
|
import { describe, expect, test, beforeAll, afterAll } from "bun:test";
|
|
import * as fs from "node:fs";
|
|
import * as os from "node:os";
|
|
import * as path from "node:path";
|
|
|
|
import { parsePdfFromFile } from "../src/meta-commands";
|
|
|
|
const FIXTURE_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "pr1169-pdf-"));
|
|
|
|
beforeAll(() => {
|
|
// mkdtempSync already created the dir
|
|
});
|
|
|
|
afterAll(() => {
|
|
fs.rmSync(FIXTURE_DIR, { recursive: true, force: true });
|
|
});
|
|
|
|
function writeFixture(name: string, body: string): string {
|
|
const p = path.join(FIXTURE_DIR, name);
|
|
fs.writeFileSync(p, body);
|
|
return p;
|
|
}
|
|
|
|
describe("parsePdfFromFile — invalid JSON regression (PR #1169 bug #7)", () => {
|
|
test("invalid JSON: throws with file path AND parser detail", () => {
|
|
const p = writeFixture("invalid.json", "{ not-json");
|
|
expect(() => parsePdfFromFile(p)).toThrow(/not valid JSON/);
|
|
expect(() => parsePdfFromFile(p)).toThrow(p);
|
|
});
|
|
|
|
test("empty file: throws JSON-parse style error", () => {
|
|
const p = writeFixture("empty.json", "");
|
|
// Empty string is invalid JSON per ECMA-404.
|
|
expect(() => parsePdfFromFile(p)).toThrow(/not valid JSON/);
|
|
});
|
|
|
|
test("top-level array: throws 'must be a JSON object' with type", () => {
|
|
const p = writeFixture("array.json", JSON.stringify(["a", "b"]));
|
|
expect(() => parsePdfFromFile(p)).toThrow(/must be a JSON object/);
|
|
expect(() => parsePdfFromFile(p)).toThrow(/array/);
|
|
});
|
|
|
|
test("top-level number: throws with 'number' type label", () => {
|
|
const p = writeFixture("number.json", "42");
|
|
expect(() => parsePdfFromFile(p)).toThrow(/must be a JSON object/);
|
|
expect(() => parsePdfFromFile(p)).toThrow(/number/);
|
|
});
|
|
|
|
test("top-level string: throws with 'string' type label", () => {
|
|
const p = writeFixture("string.json", JSON.stringify("hello"));
|
|
expect(() => parsePdfFromFile(p)).toThrow(/must be a JSON object/);
|
|
expect(() => parsePdfFromFile(p)).toThrow(/string/);
|
|
});
|
|
|
|
test("top-level null: throws with 'object' type label (JS null typeof === object)", () => {
|
|
const p = writeFixture("null.json", "null");
|
|
// null passes typeof === 'object' but the fix's `=== null` branch catches it.
|
|
expect(() => parsePdfFromFile(p)).toThrow(/must be a JSON object/);
|
|
});
|
|
|
|
test("top-level boolean: throws with 'boolean' type label", () => {
|
|
const p = writeFixture("bool.json", "true");
|
|
expect(() => parsePdfFromFile(p)).toThrow(/must be a JSON object/);
|
|
expect(() => parsePdfFromFile(p)).toThrow(/boolean/);
|
|
});
|
|
|
|
test("valid object: parses successfully (happy-path regression)", () => {
|
|
const p = writeFixture("valid.json", JSON.stringify({ format: "A4", pageNumbers: true }));
|
|
const result = parsePdfFromFile(p);
|
|
expect(result.format).toBe("A4");
|
|
expect(result.pageNumbers).toBe(true);
|
|
});
|
|
});
|