Initial curated chimera source from a8ae5b1db07fb49926c94585e2718e5130330974
This commit is contained in:
commit
c737a37f71
531 files changed
+119270
No files matched your search
@@ -0,0 +1,109 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const crypto = require('node:crypto');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const test = require('node:test');
|
||||
const { validatePs5FpkgCandidate } = require('../../src/services/ps5-fih-validator');
|
||||
const { createPs5NativePackageService } = require('../../src/services/ps5-native-package-service');
|
||||
const { PINNED_PS5_BUILDER } = require('../../src/services/ps5-native-pkg-builder-provider');
|
||||
const { validatePs5NativePackageManifest } = require('../../src/services/ps5-native-package-registration-service');
|
||||
|
||||
const TITLE_ID = 'PPSA12345';
|
||||
const CONTENT_ID = 'UP0001-PPSA12345_00-CHIMERATEST00001';
|
||||
|
||||
function writeFih(filename, contentId = CONTENT_ID) {
|
||||
const fih = Buffer.alloc(0x10000); const pfs = Buffer.alloc(0x10000); const cnt = Buffer.alloc(0x2900);
|
||||
Buffer.from([0x7f, 0x46, 0x49, 0x48]).copy(fih); fih[4] = 1; fih.writeUInt16LE(3, 6); fih.writeUInt32LE(1, 8);
|
||||
fih.writeBigUInt64LE(0x10000n, 0x10); fih.writeBigUInt64LE(0x10000n, 0x18); fih.writeBigUInt64LE(0x20000n, 0x58); fih.writeUInt32LE(1, 0xfc);
|
||||
const gameDigest = crypto.createHash('sha3-256').update(pfs).digest(); for (const offset of [0x30, 0x70, 0xd0]) gameDigest.copy(fih, offset);
|
||||
Buffer.from([0x7f, 0x43, 0x4e, 0x54]).copy(cnt); cnt.writeUInt32BE(1, 0x10); cnt.writeUInt16BE(1, 0x14); cnt.writeUInt16BE(1, 0x16); cnt.writeUInt32BE(0x2000, 0x18); cnt.writeBigUInt64BE(0x2000n, 0x20); cnt.writeBigUInt64BE(0x900n, 0x28);
|
||||
Buffer.from(contentId, 'ascii').copy(cnt, 0x40, 0, 0x30); cnt.writeUInt32BE(0x20, 0x2000); cnt.writeUInt32BE(0x2100, 0x2010); cnt.writeUInt32BE(0x800, 0x2014);
|
||||
for (const [record, offset] of [0x000, 0x180, 0x300, 0x480, 0x600].entries()) crypto.createHash('sha256').update(`${contentId}:${record}`).digest().copy(cnt, 0x2100 + offset);
|
||||
crypto.createHash('sha3-256').update(cnt.subarray(0, 0xfe0)).digest().copy(cnt, 0xfe0);
|
||||
fs.mkdirSync(path.dirname(filename), { recursive: true }); fs.writeFileSync(filename, Buffer.concat([fih, pfs, cnt]));
|
||||
}
|
||||
|
||||
function writeBackup(root) {
|
||||
const source = path.join(root, 'source'); fs.mkdirSync(path.join(source, 'sce_sys'), { recursive: true });
|
||||
fs.writeFileSync(path.join(source, 'eboot.bin'), Buffer.concat([Buffer.from([0x7f, 0x45, 0x4c, 0x46]), Buffer.alloc(64)]));
|
||||
fs.writeFileSync(path.join(source, 'sce_sys', 'param.json'), JSON.stringify({ titleId: TITLE_ID, contentId: CONTENT_ID, contentVersion: '01.00', titleName: 'Artifact test' }));
|
||||
return source;
|
||||
}
|
||||
|
||||
function upstream(accepted = true) { return { accepted, validator: 'ProsperoPkgValidator', launchReady: true, unresolvedModules: [] }; }
|
||||
|
||||
test('admits only literal finalized FIH .pkg candidates with matching upstream identity', t => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-fpkg-format-')); t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
||||
const fih = path.join(root, 'game.pkg'); writeFih(fih);
|
||||
assert.equal(validatePs5FpkgCandidate(fih, { expectedContentId: CONTENT_ID, upstreamValidation: upstream() }).accepted, true);
|
||||
for (const [name, bytes] of [
|
||||
['cnt.pkg', Buffer.concat([Buffer.from([0x7f, 0x43, 0x4e, 0x54]), Buffer.alloc(32)])],
|
||||
['mount.ffpkg', Buffer.concat([Buffer.from([0x7f, 0x46, 0x49, 0x48]), Buffer.alloc(32)])],
|
||||
['renamed.pkg', Buffer.from('ffpkg/UFS image renamed as pkg')],
|
||||
['unknown.pkg', Buffer.from('unknown package')],
|
||||
]) {
|
||||
const candidate = path.join(root, name); fs.writeFileSync(candidate, bytes);
|
||||
assert.throws(() => validatePs5FpkgCandidate(candidate, { expectedContentId: CONTENT_ID, upstreamValidation: upstream() }), error => error.code === 'PS5_FPKG_OUTPUT_NOT_FIH');
|
||||
}
|
||||
assert.throws(() => validatePs5FpkgCandidate(fih, { expectedContentId: 'UP0001-PPSA99999_00-CHIMERATEST00001', upstreamValidation: upstream() }), error => error.code === 'PS5_FPKG_TITLE_MISMATCH');
|
||||
assert.throws(() => validatePs5FpkgCandidate(fih, { expectedContentId: CONTENT_ID, upstreamValidation: upstream(false) }), error => error.code === 'PS5_FPKG_VALIDATION_FAILED');
|
||||
});
|
||||
|
||||
test('direct builder registers truthful manifest v2 provenance without install or launch claims', async t => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-fpkg-manifest-')); t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
||||
const libraryRoot = path.join(root, 'library'); const outputRoot = path.join(root, 'vault'); fs.mkdirSync(libraryRoot);
|
||||
const registrations = [];
|
||||
const provider = {
|
||||
probe: async () => ({ available: true, ...PINNED_PS5_BUILDER, capabilities: { backupBuildApi: 'ProsperoPackageBuilder', backupToDebugFpkg: true, dataDlcToDebugFpkg: true, updateToDebugFpkg: false, packageValidation: true, licenseFreeBuild: true, finalizedFihOutput: true } }),
|
||||
build: async input => { writeFih(input.outputPath, input.contentId); return { provider: PINNED_PS5_BUILDER }; },
|
||||
validatePackage: async () => upstream(),
|
||||
};
|
||||
const service = createPs5NativePackageService({ allowedRoots: () => [libraryRoot, outputRoot], outputRoot, stateFile: path.join(root, 'jobs.json'), provider, registrar: async manifest => { registrations.push(manifest); return { packageSetId: 1303 }; }, idFactory: () => 'artifact-job', now: () => 1_800_000_000_000 });
|
||||
const created = await service.create({ sourcePath: writeBackup(libraryRoot) });
|
||||
assert.equal(created.status, 'package_ready');
|
||||
const result = await service.run(created.id);
|
||||
assert.equal(result.status, 'artifact_registered');
|
||||
assert.equal(result.launchVerified, false); assert.equal(result.productionRestorable, false);
|
||||
const manifest = registrations[0];
|
||||
assert.equal(validatePs5NativePackageManifest(manifest).schemaVersion, 2);
|
||||
assert.equal(manifest.builder.api, 'ProsperoPackageBuilder');
|
||||
const historical = structuredClone(manifest); historical.builder.api = 'ProsperoBackupConverter';
|
||||
assert.equal(validatePs5NativePackageManifest(historical).schemaVersion, 2);
|
||||
const invalid = structuredClone(manifest); invalid.builder.api = 'arbitrary-builder';
|
||||
assert.throws(() => validatePs5NativePackageManifest(invalid));
|
||||
assert.deepEqual(manifest.packageFormat, { family: 'ps5-fpkg', extension: '.pkg', container: 'FIH', magic: '7f464948', debug: true, licenseFree: true, retail: false });
|
||||
assert.equal(manifest.builder.bridgeAbi, 'chimera-prospero-bridge-v4'); assert.equal(manifest.builder.patched, true);
|
||||
assert.equal(manifest.builder.patch, 'chimera-stream-large-package-assembly-u2c24-v2');
|
||||
assert.equal(manifest.evidence.consoleInstall.status, 'unproven'); assert.equal(manifest.evidence.consoleLaunch.status, 'unproven');
|
||||
assert.equal(manifest.launchVerified, false); assert.equal(manifest.productionRestorable, false);
|
||||
});
|
||||
|
||||
test('registration interruption preserves the artifact and hash drift blocks retry', async t => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-fpkg-drift-')); t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
||||
const libraryRoot = path.join(root, 'library'); const outputRoot = path.join(root, 'vault'); fs.mkdirSync(libraryRoot);
|
||||
let builds = 0;
|
||||
const provider = {
|
||||
probe: async () => ({ available: true, ...PINNED_PS5_BUILDER, capabilities: { backupToDebugFpkg: true, dataDlcToDebugFpkg: true, updateToDebugFpkg: false, packageValidation: true, licenseFreeBuild: true, finalizedFihOutput: true } }),
|
||||
build: async input => { builds++; writeFih(input.outputPath, input.contentId); }, validatePackage: async () => upstream(),
|
||||
};
|
||||
const service = createPs5NativePackageService({ allowedRoots: () => [libraryRoot, outputRoot], outputRoot, stateFile: path.join(root, 'jobs.json'), provider, registrar: async () => ({}), idFactory: () => 'drift-job' });
|
||||
const created = await service.create({ sourcePath: writeBackup(libraryRoot) });
|
||||
await assert.rejects(() => service.run(created.id), error => error.code === 'PS5_PACKAGE_REGISTRATION_INCOMPLETE');
|
||||
const pending = service.get(created.id); assert.equal(pending.status, 'registration_pending');
|
||||
const fd = fs.openSync(pending.manifest.components[0].absolutePath, 'r+'); fs.writeSync(fd, Buffer.from([0x01]), 0, 1, 0x10010); fs.closeSync(fd);
|
||||
await assert.rejects(() => service.run(created.id), error => error.code === 'PS5_FPKG_ARTIFACT_HASH_DRIFT');
|
||||
assert.equal(builds, 1); assert.equal(service.get(created.id).status, 'registration_pending');
|
||||
});
|
||||
|
||||
test('blocked fPKG analysis remains a safe preservation result', async t => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-fpkg-blocked-')); t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
||||
const libraryRoot = path.join(root, 'library'); const outputRoot = path.join(root, 'vault'); fs.mkdirSync(libraryRoot);
|
||||
const source = writeBackup(libraryRoot); fs.writeFileSync(path.join(source, 'eboot.bin'), Buffer.concat([Buffer.from([0x54, 0x14, 0xf5, 0xee]), Buffer.alloc(64)]));
|
||||
const service = createPs5NativePackageService({ allowedRoots: () => [libraryRoot, outputRoot], outputRoot, stateFile: path.join(root, 'jobs.json'), provider: { probe: async () => ({}), build: async () => ({}) }, registrar: async () => ({ packageSetId: 1 }) });
|
||||
const result = await service.create({ sourcePath: source });
|
||||
assert.equal(result.status, 'package_blocked'); assert.notEqual(result.status, 'failed');
|
||||
assert.equal(result.components[0].preservation.complete, true); assert.equal(result.components[0].fpkgReadiness.state, 'blocked');
|
||||
});
|
||||
Reference in new issue
Block a user