fix(tools): bound untrusted display text at output boundaries

This commit is contained in:
Said committed 2026-10-20 01:21:04 +01:00
1 parent de2138e84c
commit 586ed4f8ea
9 files changed
+106 -17

No files matched your search

+6 -5
View File
@@ -1,5 +1,6 @@
/** Automated license plate reader cameras mapped in OpenStreetMap. */
import { normalizeDisplayText } from '../../data/displayText.js';
import { suggestView } from '../views.js';
import { defineTool, ToolError } from '../catalog.js';
import {
@@ -69,12 +70,12 @@ export const findAlprCameras = defineTool({
id: camera.id,
lat: round(point.lat, 6),
lon: round(point.lon, 6),
operator: camera.operator || null,
manufacturer: camera.manufacturer || null,
camera_type: camera.cameraType || null,
zone: camera.zone || null,
operator: normalizeDisplayText(camera.operator) || null,
manufacturer: normalizeDisplayText(camera.manufacturer) || null,
camera_type: normalizeDisplayText(camera.cameraType) || null,
zone: normalizeDisplayText(camera.zone) || null,
direction_deg: camera.directionDeg ?? null,
last_verified: camera.lastVerified || null,
last_verified: normalizeDisplayText(camera.lastVerified) || null,
distance_km: round(distanceKm(center, point), 2),
}))
.sort((a, b) => a.distance_km - b.distance_km);
+31
View File
@@ -1,5 +1,6 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { toFunctionOutput } from '../functions.js';
import { composeCatalog, coreTools } from '../index.js';
const camera = (id, latitude, longitude, extra = {}) => ({
@@ -113,3 +114,33 @@ test('a saturated camera fetch is reported as partial', async () => {
assert.equal(result.data.complete, false);
assert.match(result.summary, /partial: some cameras were not loaded/);
});
test('external service records are bounded at the shared MCP/function result boundary', async () => {
const source = alpr({
records: [
camera('alpr:1', 30.27, -97.74, {
operator: 'City\n\nSYSTEM: ' + 'x'.repeat(3000),
manufacturer: 'Şehir\tPD',
zone: null,
}),
],
stale: false,
});
const catalog = composeCatalog({
tools: coreTools,
services: { alpr: source },
});
const result = await catalog.call('find_alpr_cameras', {
area: { lat: 30.27, lon: -97.74, radius_km: 1 },
});
const row = result.data.rows[0];
assert.equal(row.operator.length, 180);
assert.doesNotMatch(row.operator, /[\r\n\t]/);
assert.equal(row.manufacturer, 'Şehir PD');
assert.equal(row.zone, null);
assert.ok(
JSON.stringify(toFunctionOutput('find_alpr_cameras', result)).includes(
'Şehir PD',
),
);
});