mirror of
https://github.com/morluto/rea
synced 2026-10-26 22:28:27 -04:00
48e7470041
The hex carrier trimmed outer ASCII whitespace with a global start|end-anchored regex. For an invalid carrier with a long interior whitespace run, the end branch was retried at every position of the run, so rejection took quadratic time (about 18 s for a 200 KB run) and a few hundred KB could exhaust the worker deadline instead of returning the documented invalid-format error. Trim with index scans over the same ASCII whitespace set. Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
35 lines
1.4 KiB
TypeScript
35 lines
1.4 KiB
TypeScript
/** Expected carrier encoding failure, independent of the analysis engine. */
|
|
export class EvmCarrierFailure extends Error {}
|
|
|
|
/** Outer ASCII whitespace only; BOM and other Unicode spaces stay invalid. */
|
|
const asciiWhitespace = (code: number): boolean =>
|
|
code === 0x20 || (code >= 0x09 && code <= 0x0d);
|
|
|
|
/** Decode only the explicitly selected representation; source carrier bytes are retained separately. */
|
|
export const decodeEvmBytecodeCarrier = (
|
|
bytes: Uint8Array,
|
|
encoding: "raw" | "hex",
|
|
): Uint8Array => {
|
|
if (encoding === "raw") return Uint8Array.from(bytes);
|
|
let text: string;
|
|
try {
|
|
text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
|
bytes,
|
|
);
|
|
} catch (cause: unknown) {
|
|
throw new EvmCarrierFailure("Hex carrier must be valid UTF-8.", { cause });
|
|
}
|
|
// Index scans keep trimming linear; a global start|end regex backtracks
|
|
// through every interior whitespace run.
|
|
let start = 0;
|
|
let end = text.length;
|
|
while (start < end && asciiWhitespace(text.charCodeAt(start))) start += 1;
|
|
while (end > start && asciiWhitespace(text.charCodeAt(end - 1))) end -= 1;
|
|
const code = text.slice(start, end).replace(/^0x/i, "");
|
|
if (!/^(?:[a-fA-F0-9]{2})*$/.test(code))
|
|
throw new EvmCarrierFailure(
|
|
"Hex carrier requires complete hexadecimal byte pairs, an optional 0x prefix and outer ASCII whitespace; interior separators are invalid.",
|
|
);
|
|
return Uint8Array.from(Buffer.from(code, "hex"));
|
|
};
|