refactor(godot): share PCK header facts across inspections

This commit is contained in:
morluto
2026-10-26 14:25:44 +08:00
parent d7d9457661
commit 8982f40d00
4 changed files with 56 additions and 18 deletions
+18 -11
View File
@@ -1,3 +1,7 @@
import {
hasGodotPckHeader,
readGodotPckHeaderFacts,
} from "../domain/godotPckFormat.js";
import type { FileHandle } from "node:fs/promises";
import { createHash } from "node:crypto";
import { setImmediate } from "node:timers/promises";
@@ -108,20 +112,22 @@ export const inspectDesktopFile = async (
raw_version: metadataPrefix.rawVersion,
},
});
if (prefix.length >= 20 && prefix.toString("latin1", 0, 4) === "GDPC")
if (prefix.length >= 20 && hasGodotPckHeader(prefix)) {
const pckHeader = readGodotPckHeaderFacts(prefix);
fact({
kind: "godot-pck-header",
offset: 0,
value: {
pack_version: prefix.readUInt32LE(4),
pack_version: pckHeader.formatVersion,
engine_version: [
prefix.readUInt32LE(8),
prefix.readUInt32LE(12),
prefix.readUInt32LE(16),
pckHeader.engineMajor,
pckHeader.engineMinor,
pckHeader.enginePatch,
],
placement: "standalone",
},
});
}
if (
prefix.length >= 16 &&
prefix.toString("latin1", 0, 4) === "FORM" &&
@@ -320,21 +326,22 @@ const inspectPckTrailer = async (
"Embedded PCK trailer declares an invalid pack extent",
);
const offset = size - 12 - Number(packSize);
const header = await read(offset, 20);
if (header.toString("latin1", 0, 4) !== "GDPC")
const bytes = await read(offset, 20);
if (!hasGodotPckHeader(bytes))
throw new ArtifactReaderFailure(
"format",
"Embedded PCK trailer does not locate a pack header",
);
const header = readGodotPckHeaderFacts(bytes);
fact({
kind: "godot-pck-header",
offset,
value: {
pack_version: header.readUInt32LE(4),
pack_version: header.formatVersion,
engine_version: [
header.readUInt32LE(8),
header.readUInt32LE(12),
header.readUInt32LE(16),
header.engineMajor,
header.engineMinor,
header.enginePatch,
],
placement: "embedded-trailer",
},
+6 -4
View File
@@ -1,3 +1,4 @@
import { readGodotPckHeaderFacts } from "../domain/godotPckFormat.js";
import { artifactExpansionBudgetBytes } from "../domain/artifactExpansionBudget.js";
import type { FileHandle } from "node:fs/promises";
import { setImmediate } from "node:timers/promises";
@@ -301,7 +302,8 @@ const readGodotPckHeader = async (
throw formatFailure("no standalone header or executable trailer");
const { start, end, embedded } = location;
const fixed = await readPckBytes(handle, start, 40, end, signal);
const version = fixed.readUInt32LE(4);
const header = readGodotPckHeaderFacts(fixed);
const version = header.formatVersion;
if (![2, 3, 4].includes(version))
throw new ArtifactReaderFailure(
"unavailable",
@@ -343,9 +345,9 @@ const readGodotPckHeader = async (
return {
kind: "godot-pck",
format_version: version,
engine_major: fixed.readUInt32LE(8),
engine_minor: fixed.readUInt32LE(12),
engine_patch: fixed.readUInt32LE(16),
engine_major: header.engineMajor,
engine_minor: header.engineMinor,
engine_patch: header.enginePatch,
pack_start: start,
pack_end: end,
embedded,
+21
View File
@@ -8,3 +8,24 @@ export const hasGodotPckHeader = (bytes: Uint8Array): boolean =>
bytes[1] === 0x44 &&
bytes[2] === 0x50 &&
bytes[3] === 0x43;
/** Common declared fields; support and pack extent admission belong to callers. */
export interface GodotPckHeaderFacts {
readonly formatVersion: number;
readonly engineMajor: number;
readonly engineMinor: number;
readonly enginePatch: number;
}
/** Decode declared fields after the caller admits a complete 20-byte header. */
export const readGodotPckHeaderFacts = (
bytes: Uint8Array,
): GodotPckHeaderFacts => {
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
return {
formatVersion: view.getUint32(4, true),
engineMajor: view.getUint32(8, true),
engineMinor: view.getUint32(12, true),
enginePatch: view.getUint32(16, true),
};
};
@@ -192,6 +192,8 @@ it("reads sparse embedded PCK ranges without hashing or retaining a large execut
pck.write("GDPC");
pck.writeUInt32LE(3, 4);
pck.writeUInt32LE(4, 8);
pck.writeUInt32LE(0x80000001, 12);
pck.writeUInt32LE(0xffffffff, 16);
const trailer = Buffer.alloc(12);
trailer.writeBigUInt64LE(BigInt(pck.length));
trailer.write("GDPC", 8);
@@ -203,9 +205,15 @@ it("reads sparse embedded PCK ranges without hashing or retaining a large execut
expect(report.candidates.map((row) => row.family)).toContain("godot");
expect(report.coverage.bytes_read).toBeLessThan(4096);
expect(report.files[0]?.bytes).toBe(size);
expect(report.files[0]?.facts).toContainEqual(
expect.objectContaining({ kind: "godot-pck-header", offset: size - 32 }),
);
expect(report.files[0]?.facts).toContainEqual({
kind: "godot-pck-header",
offset: size - 32,
value: {
pack_version: 3,
engine_version: [4, 0x80000001, 0xffffffff],
placement: "embedded-trailer",
},
});
});
it("does not promote filenames, arbitrary pak files or symlink targets into byte facts", async () => {