From 33432725d61d6b89f8542d88f4bbfd190f9f9858 Mon Sep 17 00:00:00 2001 From: boykopovar Date: Tue, 13 Oct 2026 14:30:57 +0300 Subject: [PATCH] fix(web): limit executable detection to app root --- demo/web/archive.mjs | 3 ++- demo/web/tests/archive.test.mjs | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/demo/web/archive.mjs b/demo/web/archive.mjs index 9df648585..c9da69f1b 100644 --- a/demo/web/archive.mjs +++ b/demo/web/archive.mjs @@ -130,13 +130,14 @@ export class Archive { const item = this.files[index]; report({ phase: "Inspecting files", input: item.name, completed: index, total: this.files.length }); if (item.entry.directory || item.name.startsWith("sce_sys/")) continue; + if (!item.name.startsWith("sce_module/") && item.name.includes("/")) continue; if (item.name.startsWith("sce_module/") && item.name.endsWith(".guest.prx")) continue; const elf = await signature(item.entry); if (item.name.startsWith("sce_module/")) { if (elf) this.modules.push(item); } else if (elf) executables.push(item); } - if (executables.length !== 1) throw new Error(`Expected exactly one executable ELF outside sce_module; found ${executables.length}`); + if (executables.length !== 1) throw new Error(`Expected exactly one executable ELF in the app root; found ${executables.length}`); this.executable = executables[0]; if (this.executable.name.includes("/")) throw new Error("Place the executable next to sce_sys and sce_module, not inside another folder"); this.icon = this.files.find(item => item.name === "sce_sys/icon0.png" && !item.entry.directory); diff --git a/demo/web/tests/archive.test.mjs b/demo/web/tests/archive.test.mjs index 3f26fa187..20e67411a 100644 --- a/demo/web/tests/archive.test.mjs +++ b/demo/web/tests/archive.test.mjs @@ -22,13 +22,14 @@ async function zip(entries) { return writer.close(); } -const source = await zip([["title/", null, { directory: true }], ["title/program.dat", executable], ["title/sce_module/library.prx.esbak", module], ["title/sce_module/library.prx", new Uint8Array([79, 21, 61, 29])], ["title/sce_module/library.prx.esbak.guest.prx", new Uint8Array([77, 90, 0, 0])], ["title/sce_sys/param.json", new TextEncoder().encode("{}")], ["title/content/resource.bin", resource]]); +const source = await zip([["title/", null, { directory: true }], ["title/program.dat", executable], ["title/sce_module/library.prx.esbak", module], ["title/sce_module/library.prx", new Uint8Array([79, 21, 61, 29])], ["title/sce_module/library.prx.esbak.guest.prx", new Uint8Array([77, 90, 0, 0])], ["title/sce_sys/param.json", new TextEncoder().encode("{}")], ["title/shaders/example.frag", executable], ["title/content/resource.bin", resource]]); const folder = [ { path: "title/program.dat", file: new Blob([executable]) }, { path: "title/sce_module/library.prx.esbak", file: new Blob([module]) }, { path: "title/sce_module/library.prx", file: new Blob([new Uint8Array([79, 21, 61, 29])]) }, { path: "title/sce_module/library.prx.esbak.guest.prx", file: new Blob([new Uint8Array([77, 90, 0, 0])]) }, { path: "title/sce_sys/param.json", file: new Blob(["{}"]) }, + { path: "title/shaders/example.frag", file: new Blob([executable]) }, { path: "title/content/resource.bin", file: new Blob([resource]) } ]; for (const [kind, selected] of [["ZIP", source], ["folder", folder]]) { @@ -63,6 +64,7 @@ for (const target of ["windows", "linux"]) { const byName = new Map(entries.map(entry => [entry.filename, entry])); assert(byName.has(input.outputName)); assert(byName.has("libs/system.prx")); + assert.deepEqual(await byName.get("app0/shaders/example.frag").getData(new Uint8ArrayWriter(), { checkSignature: true }), executable); assert.deepEqual(await byName.get("app0/sce_module/library.prx.esbak.guest.prx").getData(new Uint8ArrayWriter(), { checkSignature: true }), converted.modules[0].bytes); assert.deepEqual(await byName.get("app0/sce_module/library.prx").getData(new Uint8ArrayWriter(), { checkSignature: true }), new Uint8Array([79, 21, 61, 29])); assert.deepEqual(await byName.get("app0/program.dat").getData(new Uint8ArrayWriter(), { checkSignature: true }), executable);