Files

39 lines
1.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ---------- PHP serialize 反序列化(字节精确,覆盖 s/i/d/b/a/N) ---------- */
export function phpUnserialize(input: string): unknown {
const buf = Buffer.from(input, "utf8");
let i = 0;
function parse(): unknown {
const type = String.fromCharCode(buf[i]);
const colon = buf.indexOf(0x3a, i + 2); // 跳过 "类型:" 后定位计数值结束的冒号
if (type === "N") { i += 2; return null; } // N;
if (type === "b") { const v = buf[i + 2] === 0x31; i += 4; return v; } // b:0; / b:1;
if (type === "i") { const j = buf.indexOf(0x3b, i); const v = parseInt(buf.toString("utf8", i + 2, j)); i = j + 1; return v; } // i:123;
if (type === "d") { const j = buf.indexOf(0x3b, i); const v = parseFloat(buf.toString("utf8", i + 2, j)); i = j + 1; return v; } // d:1.5;
if (type === "s") { // s:LEN:"...";(LEN 为 UTF-8 字节数)
const len = parseInt(buf.toString("utf8", i + 2, colon));
const start = colon + 2;
const v = buf.toString("utf8", start, start + len);
i = start + len + 2;
return v;
}
if (type === "a") { // a:COUNT:{ key;value; ... }
const n = parseInt(buf.toString("utf8", i + 2, colon));
i = colon + 2; // 跳过 '{'
const arr: unknown[] = [];
const obj: Record<string, unknown> = {};
let isArr = true;
for (let k = 0; k < n; k++) {
const key = parse();
const val = parse();
if (typeof key === "number") { isArr = isArr && true; arr[key] = val; }
else { isArr = false; obj[String(key)] = val; }
}
i += 1; // 消费 '}'
return isArr ? arr : obj;
}
throw new Error(`phpUnserialize: unknown type '${type}' at byte ${i}`);
}
return parse();
}