mirror of
https://github.com/morluto/rea.git
synced 2026-11-10 17:30:32 -10:00
103 lines
2.9 KiB
TypeScript
103 lines
2.9 KiB
TypeScript
import { expect, it } from "vitest";
|
|
import {
|
|
inspectPythonPycInputSchema,
|
|
pythonPycMarshalProfile,
|
|
PYTHON_PYC_MARSHAL_PROFILES,
|
|
pythonPycHeaderSchema,
|
|
} from "./pythonPyc.js";
|
|
import { pythonBytecodeIdentity } from "./pythonBytecodeIdentity.js";
|
|
|
|
const hashHeader = {
|
|
magic: 3531,
|
|
python_version: "3.12",
|
|
code_layout: "py311",
|
|
flags: 3,
|
|
hash_based: true,
|
|
check_source: true,
|
|
source_hash_hex: "0123456789abcdef",
|
|
source_mtime: null,
|
|
source_size: null,
|
|
};
|
|
|
|
it.each(["", "ab", "g".repeat(16)])(
|
|
"rejects an invalid source hash %j",
|
|
(source_hash_hex) => {
|
|
expect(
|
|
pythonPycHeaderSchema.safeParse({ ...hashHeader, source_hash_hex })
|
|
.success,
|
|
).toBe(false);
|
|
},
|
|
);
|
|
|
|
it.each([
|
|
{ hash_based: false },
|
|
{ check_source: false },
|
|
{ source_hash_hex: null },
|
|
{ source_mtime: 0 },
|
|
{ source_size: 0 },
|
|
])("keeps header facts consistent with the recorded flags: %j", (changed) => {
|
|
expect(
|
|
pythonPycHeaderSchema.safeParse({ ...hashHeader, ...changed }).success,
|
|
).toBe(false);
|
|
});
|
|
|
|
it("preserves unknown raw header flags and valid hash bytes", () => {
|
|
const header = { ...hashHeader, flags: 0x80000003 };
|
|
expect(pythonPycHeaderSchema.parse(header)).toEqual(header);
|
|
});
|
|
|
|
it("keeps pinned CPython identity separate from standalone marshal coverage", () => {
|
|
expect(pythonPycMarshalProfile(3394)).toEqual({
|
|
code_layout: "py37",
|
|
negative_code_fields: "accepted",
|
|
});
|
|
expect(pythonBytecodeIdentity(3390)).toEqual({
|
|
pythonVersion: "3.7",
|
|
headerBytes: 12,
|
|
});
|
|
expect(pythonBytecodeIdentity(3391)).toEqual({
|
|
pythonVersion: "3.7",
|
|
headerBytes: 12,
|
|
});
|
|
expect(pythonPycMarshalProfile(3413)).toEqual({
|
|
code_layout: "py38",
|
|
negative_code_fields: "rejected",
|
|
});
|
|
expect(pythonPycMarshalProfile(3401)?.negative_code_fields).toBe("accepted");
|
|
expect(pythonPycMarshalProfile(3410)?.negative_code_fields).toBe(
|
|
"revision-dependent",
|
|
);
|
|
expect(pythonPycMarshalProfile(3411)?.negative_code_fields).toBe("rejected");
|
|
expect(pythonPycMarshalProfile(3531)).toEqual({
|
|
code_layout: "py311",
|
|
negative_code_fields: "rejected",
|
|
});
|
|
expect(pythonPycMarshalProfile(3571)).toEqual({
|
|
code_layout: "py311",
|
|
negative_code_fields: "rejected",
|
|
});
|
|
// Recognizing a newer CPython identity does not authorize its code layout.
|
|
expect(pythonBytecodeIdentity(3627)).toEqual({
|
|
pythonVersion: "3.14",
|
|
headerBytes: 16,
|
|
});
|
|
expect(pythonBytecodeIdentity(3666)).toEqual({
|
|
pythonVersion: "3.15",
|
|
headerBytes: 16,
|
|
});
|
|
expect(pythonPycMarshalProfile(3627)).toBeNull();
|
|
expect(pythonPycMarshalProfile(3666)).toBeNull();
|
|
expect(pythonPycMarshalProfile(3450)).toBeNull();
|
|
expect(pythonPycMarshalProfile(62171)).toBeNull();
|
|
expect(PYTHON_PYC_MARSHAL_PROFILES.size).toBeGreaterThan(80);
|
|
});
|
|
|
|
it("rejects extra inspect arguments", () => {
|
|
expect(
|
|
inspectPythonPycInputSchema.safeParse({
|
|
path: "/artifacts/module.pyc",
|
|
detail: "complete",
|
|
}).success,
|
|
).toBe(false);
|
|
});
|