fix: implement type-aware sanitization for thinking blocks (#27825)
- Add sanitizePayload() with structural traversal - Bypass sanitization for signed thinking blocks - Preserve normal sanitization for other content - Config-driven toggle for flexible deployment - Replace runtime patching with clean code solution Supersedes #27965
This commit is contained in:
parent
4c60956d8e
commit
26c9562e3c
47
lib/utils/sanitizePayload.js
Normal file
47
lib/utils/sanitizePayload.js
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Type-Aware Sanitization for OpenClaw Issue #27825
|
||||
* Prevents sanitizeSurrogates() from corrupting signed Anthropic thinking blocks
|
||||
*/
|
||||
|
||||
import { sanitizeSurrogates } from './surrogate-sanitizer.js';
|
||||
|
||||
/**
|
||||
* Sanitizes payload while preserving thinking blocks with valid signatures
|
||||
* @param {any} payload - The payload to sanitize
|
||||
* @param {Object} options - Configuration options
|
||||
* @param {boolean} options.preserveThinkingBlocks - Whether to bypass thinking block sanitization
|
||||
* @returns {any} Sanitized payload
|
||||
*/
|
||||
export function sanitizePayload(payload, options = {}) {
|
||||
const { preserveThinkingBlocks = false } = options;
|
||||
|
||||
function traverseAndSanitize(node) {
|
||||
// Bypass thinking blocks if preservation is enabled
|
||||
if (preserveThinkingBlocks && node?.type === 'thinking' && node?.signature) {
|
||||
return node;
|
||||
}
|
||||
|
||||
// Sanitize strings
|
||||
if (typeof node === 'string') {
|
||||
return sanitizeSurrogates(node);
|
||||
}
|
||||
|
||||
// Handle arrays
|
||||
if (Array.isArray(node)) {
|
||||
return node.map(traverseAndSanitize);
|
||||
}
|
||||
|
||||
// Handle objects
|
||||
if (node && typeof node === 'object') {
|
||||
const result = {};
|
||||
for (const key of Object.keys(node)) {
|
||||
result[key] = traverseAndSanitize(node[key]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
return traverseAndSanitize(payload);
|
||||
}
|
||||
1
openclaw-2026-03-19.log
Normal file
1
openclaw-2026-03-19.log
Normal file
@ -0,0 +1 @@
|
||||
{"0":"{\"module\":\"cron\",\"storePath\":\"/home/botty/.openclaw/cron/jobs.json\"}","1":{"nextAt":1774015543327,"delayMs":60000,"clamped":true},"2":"cron: timer armed","_meta":{"runtime":"node","runtimeVersion":"24.14.0","hostname":"unknown","name":"{\"module\":\"cron\",\"storePath\":\"/home/botty/.openclaw/cron/jobs.json\"}","parentNames":["openclaw"],"date":"2026-03-20T14:02:04.887Z","logLevelId":2,"logLevelName":"DEBUG","path":{"fullFilePath":"file:///home/botty/.npm-global/lib/node_modules/openclaw/dist/gateway-cli-CuZs0RlJ.js:6006:17","fileName":"gateway-cli-CuZs0RlJ.js","fileNameWithLine":"gateway-cli-CuZs0RlJ.js:6006","fileColumn":"17","fileLine":"6006","filePath":".npm-global/lib/node_modules/openclaw/dist/gateway-cli-CuZs0RlJ.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/gateway-cli-CuZs0RlJ.js:6006","method":"armTimer"}},"time":"2026-03-20T15:02:04.888+01:00"}
|
||||
2
openclaw-2026-03-20.log
Normal file
2
openclaw-2026-03-20.log
Normal file
@ -0,0 +1,2 @@
|
||||
{"0":"{\"subsystem\":\"agents/tool-images\"}","1":{"label":"session:history","sourceMimeType":"image/png","sourceWidth":1447,"sourceHeight":407,"sourceBytes":39664,"maxBytes":5242880,"maxDimensionPx":1200,"triggerOverBytes":false,"triggerOverDimensions":true,"outputMimeType":"image/jpeg","outputBytes":42856,"outputQuality":85,"outputMaxSide":1200,"byteReductionPct":-8},"2":"Image resized to fit limits: 1447x407px 38.7KB -> 41.9KB (--8%)","_meta":{"runtime":"node","runtimeVersion":"24.14.0","hostname":"unknown","name":"{\"subsystem\":\"agents/tool-images\"}","parentNames":["openclaw"],"date":"2026-03-20T14:02:14.245Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"file:///home/botty/.npm-global/lib/node_modules/openclaw/dist/subsystem-BDbeCphF.js:1118:51","fileName":"subsystem-BDbeCphF.js","fileNameWithLine":"subsystem-BDbeCphF.js:1118","fileColumn":"51","fileLine":"1118","filePath":".npm-global/lib/node_modules/openclaw/dist/subsystem-BDbeCphF.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/subsystem-BDbeCphF.js:1118","method":"logToFile"}},"time":"2026-03-20T15:02:14.245+01:00"}
|
||||
{"0":"{\"subsystem\":\"agents/tool-images\"}","1":{"label":"session:history","sourceMimeType":"image/png","sourceWidth":1341,"sourceHeight":366,"sourceBytes":29177,"maxBytes":5242880,"maxDimensionPx":1200,"triggerOverBytes":false,"triggerOverDimensions":true,"outputMimeType":"image/jpeg","outputBytes":35088,"outputQuality":85,"outputMaxSide":1200,"byteReductionPct":-20.3},"2":"Image resized to fit limits: 1341x366px 28.5KB -> 34.3KB (--20.3%)","_meta":{"runtime":"node","runtimeVersion":"24.14.0","hostname":"unknown","name":"{\"subsystem\":\"agents/tool-images\"}","parentNames":["openclaw"],"date":"2026-03-20T14:02:14.287Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"file:///home/botty/.npm-global/lib/node_modules/openclaw/dist/subsystem-BDbeCphF.js:1118:51","fileName":"subsystem-BDbeCphF.js","fileNameWithLine":"subsystem-BDbeCphF.js:1118","fileColumn":"51","fileLine":"1118","filePath":".npm-global/lib/node_modules/openclaw/dist/subsystem-BDbeCphF.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/subsystem-BDbeCphF.js:1118","method":"logToFile"}},"time":"2026-03-20T15:02:14.287+01:00"}
|
||||
Loading…
x
Reference in New Issue
Block a user