mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 05:11:25 +00:00
fix(security): reject oversized base64 before decode
This commit is contained in:
37
src/media/base64.ts
Normal file
37
src/media/base64.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
export function estimateBase64DecodedBytes(base64: string): number {
|
||||
// Avoid `trim()`/`replace()` here: they allocate a second (potentially huge) string.
|
||||
// We only need a conservative decoded-size estimate to enforce budgets before Buffer.from(..., "base64").
|
||||
let effectiveLen = 0;
|
||||
for (let i = 0; i < base64.length; i += 1) {
|
||||
const code = base64.charCodeAt(i);
|
||||
// Treat ASCII control + space as whitespace; base64 decoders commonly ignore these.
|
||||
if (code <= 0x20) {
|
||||
continue;
|
||||
}
|
||||
effectiveLen += 1;
|
||||
}
|
||||
|
||||
if (effectiveLen === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let padding = 0;
|
||||
// Find last non-whitespace char(s) to detect '=' padding without allocating/copying.
|
||||
let end = base64.length - 1;
|
||||
while (end >= 0 && base64.charCodeAt(end) <= 0x20) {
|
||||
end -= 1;
|
||||
}
|
||||
if (end >= 0 && base64[end] === "=") {
|
||||
padding = 1;
|
||||
end -= 1;
|
||||
while (end >= 0 && base64.charCodeAt(end) <= 0x20) {
|
||||
end -= 1;
|
||||
}
|
||||
if (end >= 0 && base64[end] === "=") {
|
||||
padding = 2;
|
||||
}
|
||||
}
|
||||
|
||||
const estimated = Math.floor((effectiveLen * 3) / 4) - padding;
|
||||
return Math.max(0, estimated);
|
||||
}
|
||||
Reference in New Issue
Block a user