mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-21 02:54:59 +00:00
fix(feishu): address sixth-round codex bot review feedback
- docx-table-ops: apply MIN/MAX_COLUMN_WIDTH clamping in the empty-table branch so tables with 15+ columns don't produce sub-50 widths that Feishu rejects as invalid column_width values. - docx.ts (data URI branch): validate the ';base64' marker before decoding so plain/URL-encoded data URIs are rejected with a clear error; also validate the payload against the base64 alphabet (same guard already applied in the plain-base64 branch) so malformed inputs fail fast rather than producing opaque downstream Feishu errors.
This commit is contained in:
@@ -105,10 +105,15 @@ export function calculateAdaptiveColumnWidths(
|
||||
}
|
||||
}
|
||||
|
||||
// Handle empty table
|
||||
// Handle empty table: distribute width equally, clamped to [MIN, MAX] so
|
||||
// wide tables (e.g. 15+ columns) don't produce sub-50 widths that Feishu
|
||||
// rejects as invalid column_width values.
|
||||
const totalLength = maxLengths.reduce((a, b) => a + b, 0);
|
||||
if (totalLength === 0) {
|
||||
const equalWidth = Math.floor(totalWidth / column_size);
|
||||
const equalWidth = Math.max(
|
||||
MIN_COLUMN_WIDTH,
|
||||
Math.min(MAX_COLUMN_WIDTH, Math.floor(totalWidth / column_size)),
|
||||
);
|
||||
return new Array(column_size).fill(equalWidth);
|
||||
}
|
||||
|
||||
|
||||
@@ -410,18 +410,38 @@ async function resolveUploadInput(
|
||||
|
||||
// data URI: data:image/png;base64,xxxx
|
||||
if (imageInput?.startsWith("data:")) {
|
||||
const [header, data] = imageInput.split(",");
|
||||
const commaIdx = imageInput.indexOf(",");
|
||||
if (commaIdx === -1) {
|
||||
throw new Error("Invalid data URI: missing comma separator.");
|
||||
}
|
||||
const header = imageInput.slice(0, commaIdx);
|
||||
const data = imageInput.slice(commaIdx + 1);
|
||||
// Only base64-encoded data URIs are supported; reject plain/URL-encoded ones.
|
||||
if (!header.includes(";base64")) {
|
||||
throw new Error(
|
||||
`Invalid data URI: missing ';base64' marker. ` +
|
||||
`Expected format: data:image/png;base64,<base64data>`,
|
||||
);
|
||||
}
|
||||
// Validate the payload is actually base64 before decoding; Node's decoder
|
||||
// is permissive and would silently accept garbage bytes otherwise.
|
||||
const trimmedData = data.trim();
|
||||
if (trimmedData.length === 0 || !/^[A-Za-z0-9+/]+=*$/.test(trimmedData)) {
|
||||
throw new Error(
|
||||
`Invalid data URI: base64 payload contains characters outside the standard alphabet.`,
|
||||
);
|
||||
}
|
||||
const mimeMatch = header.match(/data:([^;]+)/);
|
||||
const ext = mimeMatch?.[1]?.split("/")[1] ?? "png";
|
||||
// Estimate decoded byte count from base64 length BEFORE allocating the
|
||||
// full buffer to avoid spiking memory on oversized payloads.
|
||||
const estimatedBytes = Math.ceil((data.length * 3) / 4);
|
||||
const estimatedBytes = Math.ceil((trimmedData.length * 3) / 4);
|
||||
if (estimatedBytes > maxBytes) {
|
||||
throw new Error(
|
||||
`Image data URI exceeds limit: estimated ${estimatedBytes} bytes > ${maxBytes} bytes`,
|
||||
);
|
||||
}
|
||||
const buffer = Buffer.from(data, "base64");
|
||||
const buffer = Buffer.from(trimmedData, "base64");
|
||||
return { buffer, fileName: explicitFileName ?? `image.${ext}` };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user