fix(schema): harden realm-safe JSON validation

This commit is contained in:
Tianyi Cui
2026-07-21 22:11:41 +08:00
parent acc628f3af
commit 384cc8c157
6 changed files with 46 additions and 4 deletions

View File

@@ -351,7 +351,7 @@ function checkValueUnchecked(node: JsonSchemaNode, value: unknown, path: string)
return safelyIsJsonValue(value) ? [] : [`"${diagnosticPath(path)}" must be a lossless JSON object`]
}
case 'array': {
if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) return [`"${diagnosticPath(path)}" must be an array`]
if (!Array.isArray(value)) return [`"${diagnosticPath(path)}" must be an array`]
const items = node.items
const violations = items === undefined
? []

View File

@@ -186,6 +186,10 @@ describe('the enforced raw JSON Schema subset', () => {
})
expect(violationsOf({ examples: explosive }))
.toEqual(['schema.examples annotation must be lossless JSON data'])
expect(violationsOf({ default: Object.defineProperty({}, 'hidden', { value: true }) }))
.toEqual(['schema.default annotation must be lossless JSON data'])
expect(violationsOf({ default: { [Symbol('hidden')]: true } }))
.toEqual(['schema.default annotation must be lossless JSON data'])
})
it('accepts lossless annotation containers from another JavaScript realm', () => {
@@ -298,6 +302,7 @@ describe('validateJsonSchemaValue', () => {
it('validates dense arrays per index and rejects lossy arrays', () => {
const schema = asserted({ type: 'array', items: { type: 'integer' } })
expect(validateJsonSchemaValue(schema, [1, 2])).toEqual([])
expect(validateJsonSchemaValue(schema, runInNewContext('[1, 2]'))).toEqual([])
expect(validateJsonSchemaValue(schema, [1, 1.5])).toEqual(['"value[1]" must be an integer'])
expect(validateJsonSchemaValue(schema, 'x')).toEqual(['"value" must be an array'])
const sparse: number[] = []