fix(validators): isSchemaKind no longer accepts inherited prototype keys (#14)

'value in schemas' walks the prototype chain, so inherited keys like
"toString" passed assertSchemaKind and then crashed ajv.compile with a
misleading 'schema must be object or boolean' error (e.g. via the CLI).
Use Object.hasOwn for an own-property check.

Adds unit tests rejecting prototype keys and asserting every real
schema kind still passes.

Fixes #13
This commit is contained in:
6D0N9 2026-06-12 06:06:18 +02:00 committed by GitHub
parent 73e2464b30
commit 3d4345b665
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 19 additions and 2 deletions

View file

@ -2,7 +2,8 @@ import { readFileSync } from "node:fs";
import { dirname, resolve } from "node:path"; import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { parseDocument, validate } from "./index.js"; import { assertSchemaKind, parseDocument, schemas, validate } from "./index.js";
import { isSchemaKind } from "./schemas.js";
describe("LogicSRC validators", () => { describe("LogicSRC validators", () => {
it("validates the task fixture", () => { it("validates the task fixture", () => {
@ -49,3 +50,19 @@ describe("LogicSRC validators", () => {
expect(result.ok).toBe(false); expect(result.ok).toBe(false);
}); });
}); });
describe("isSchemaKind / assertSchemaKind prototype safety", () => {
it("rejects inherited Object.prototype keys", () => {
for (const key of ["toString", "constructor", "valueOf", "hasOwnProperty"]) {
expect(isSchemaKind(key)).toBe(false);
expect(() => assertSchemaKind(key)).toThrow(/Unknown schema kind/);
}
});
it("still accepts every real schema kind", () => {
for (const key of Object.keys(schemas)) {
expect(isSchemaKind(key)).toBe(true);
expect(assertSchemaKind(key)).toBe(key);
}
});
});

View file

@ -41,5 +41,5 @@ export const schemas = {
export type SchemaKind = keyof typeof schemas; export type SchemaKind = keyof typeof schemas;
export function isSchemaKind(value: string): value is SchemaKind { export function isSchemaKind(value: string): value is SchemaKind {
return value in schemas; return Object.hasOwn(schemas, value);
} }