mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 03:14:00 +00:00
fix: check only own properties when validating tool arguments
Inherited names such as constructor, toString and __proto__ passed as declared properties despite additionalProperties: false, and a schema-valued additionalProperties was accepted but never enforced. Validation now uses own properties, and definitions must give additionalProperties as a boolean.
This commit is contained in:
1 parent
c4a4247f70
commit
6a45a8f6a2
2 files changed
+40
-2
No files matched your search
@@ -203,3 +203,32 @@ test('the validator checks every supported keyword', () => {
|
|||||||
'arguments.n must be a number',
|
'arguments.n must be a number',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('inherited names are not declared properties, and schema-valued additionalProperties is refused', () => {
|
||||||
|
const schema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: { name: { type: 'string' } },
|
||||||
|
additionalProperties: false,
|
||||||
|
};
|
||||||
|
for (const name of ['constructor', 'toString', '__proto__'])
|
||||||
|
assert.deepEqual(validateValue(schema, JSON.parse(`{"${name}": 1}`)), [
|
||||||
|
`arguments has unknown property ${name}`,
|
||||||
|
]);
|
||||||
|
assert.deepEqual(validateValue({ ...schema, required: ['toString'] }, {}), [
|
||||||
|
'arguments is missing toString',
|
||||||
|
]);
|
||||||
|
assert.throws(
|
||||||
|
() =>
|
||||||
|
defineTool({
|
||||||
|
name: 'loose',
|
||||||
|
title: 'Loose',
|
||||||
|
description: 'Promises checks it cannot make.',
|
||||||
|
inputSchema: {
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: { type: 'string' },
|
||||||
|
},
|
||||||
|
run: async () => ({ summary: '', data: {} }),
|
||||||
|
}),
|
||||||
|
/additionalProperties must be true or false/,
|
||||||
|
);
|
||||||
|
});
|
||||||
+11
-2
@@ -44,6 +44,12 @@ export function assertSupportedSchema(schema, path = 'schema') {
|
|||||||
if (!TYPES.has(schema.type))
|
if (!TYPES.has(schema.type))
|
||||||
throw new TypeError(`${path} has unsupported type ${schema.type}`);
|
throw new TypeError(`${path} has unsupported type ${schema.type}`);
|
||||||
if (schema.pattern !== undefined) new RegExp(schema.pattern, 'u');
|
if (schema.pattern !== undefined) new RegExp(schema.pattern, 'u');
|
||||||
|
// Only the boolean form is checked; a schema here would go unenforced.
|
||||||
|
if (
|
||||||
|
schema.additionalProperties !== undefined &&
|
||||||
|
typeof schema.additionalProperties !== 'boolean'
|
||||||
|
)
|
||||||
|
throw new TypeError(`${path}.additionalProperties must be true or false`);
|
||||||
for (const [name, child] of Object.entries(schema.properties || {}))
|
for (const [name, child] of Object.entries(schema.properties || {}))
|
||||||
assertSupportedSchema(child, `${path}.${name}`);
|
assertSupportedSchema(child, `${path}.${name}`);
|
||||||
if (schema.items) assertSupportedSchema(schema.items, `${path}[]`);
|
if (schema.items) assertSupportedSchema(schema.items, `${path}[]`);
|
||||||
@@ -63,11 +69,14 @@ export function validateValue(schema, value, path = 'arguments') {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (const name of schema.required || []) {
|
for (const name of schema.required || []) {
|
||||||
if (value[name] === undefined) fail(`is missing ${name}`);
|
if (!Object.hasOwn(value, name) || value[name] === undefined)
|
||||||
|
fail(`is missing ${name}`);
|
||||||
}
|
}
|
||||||
|
// Own properties only, so names such as constructor or __proto__ are
|
||||||
|
// not mistaken for declared ones.
|
||||||
const properties = schema.properties || {};
|
const properties = schema.properties || {};
|
||||||
for (const [name, child] of Object.entries(value)) {
|
for (const [name, child] of Object.entries(value)) {
|
||||||
if (properties[name])
|
if (Object.hasOwn(properties, name))
|
||||||
problems.push(
|
problems.push(
|
||||||
...validateValue(properties[name], child, `${path}.${name}`),
|
...validateValue(properties[name], child, `${path}.${name}`),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in new issue
Block a user