fix(python): preserve marshal names and packaged bytecode

Use one marshal surrogatepass decoder for PYZ directories and Python bytecode.
Validate ordinary UTF-8 spans with the native fatal decoder, preserving BOMs,
lone surrogates, raw bytes and marshal reference slots.

Distinguish legacy full-pyc CArchive modules from modern marshal-only modules
before reconstructing headers. Share typed source/codec failures between stream
output and completion while retaining native-read drain and cleanup ownership.

Validated focused producer, reader, lifecycle, CLI and MCP regressions, plus
public inventory/extraction of CPython 3.14-generated marshal tables and code.
No packaged application was executed. Document original versus derived bytes.

Fixes #6800
Fixes #6789
This commit is contained in:
morluto committed 2026-10-24 01:24:43 +08:00
1 parent 2443b949a4
commit f8f52f205a
18 files changed
+986 -109

No files matched your search

+2 -2
View File
@@ -321,11 +321,11 @@ it("charges long digits to the string budget and keeps large previews bounded",
it("decodes marshal strings with CPython surrogatepass rules", () => {
const report = parse(
withConsts([marshalUnicode(Buffer.from([0x73, 0xed, 0xa0, 0x80]))]),
withConsts([marshalUnicode(Buffer.from("efbbbf73eda080efbbbf", "hex"))]),
);
expect(root(report).consts[0]).toMatchObject({
kind: "str",
value: "s\ud800",
value: "\ufeffs\ud800\ufeff",
});
expect(() =>
parse(withConsts([marshalUnicode(Buffer.from([0xf0, 0x90, 0x80]))])),