Fix setupExe metadata + improve PKSFX detection
Build & Deploy / build-and-deploy (push) Successful in 50s
Build & Deploy / build-and-deploy (push) Successful in 50s
- Added 'sfx' and 'makesfx' to SKIP_EXE_NAMES - Increased self-extractor detection buffer to 32KB - Fixed false-positive risk: PK signatures only checked after offset 0x40 using proper signature comparison (not sequential byte matching) - Fixed setupExe metadata: only set when setup bundle was actually created, preventing phantom Setup button when setup exe is Windows
This commit is contained in:
@@ -106,11 +106,13 @@ public class UploadResource {
|
||||
// Create setup bundle only if the setup executable is itself DOS-compatible.
|
||||
// Some games (e.g. Fallout) ship a Windows SETUP.EXE even though the main
|
||||
// game is DOS — that setup would fail with "This program cannot run in DOS mode".
|
||||
boolean hasSetupBundle = false;
|
||||
if (setupExe != null) {
|
||||
String setupPlatform = detectPlatform(Path.of(setupExe));
|
||||
if (!"windows".equals(setupPlatform)) {
|
||||
Path setupBundlePath = svc.getGamesDir().resolve(gameId + ".setup.jsdos");
|
||||
createBundle(extractDir, setupExe, setupBundlePath);
|
||||
hasSetupBundle = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +120,9 @@ public class UploadResource {
|
||||
Game game = new Game(gameId, title);
|
||||
game.setBundleFile(bundleFile);
|
||||
game.setPlatform(platform);
|
||||
game.setSetupExe(setupExe != null ? extractDir.relativize(Path.of(setupExe)).toString() : null);
|
||||
if (hasSetupBundle) {
|
||||
game.setSetupExe(extractDir.relativize(Path.of(setupExe)).toString());
|
||||
}
|
||||
game.setReady(true);
|
||||
svc.save(game);
|
||||
|
||||
@@ -291,25 +295,27 @@ public class UploadResource {
|
||||
*/
|
||||
static boolean isLikelySelfExtractor(Path exePath) {
|
||||
try (var fis = Files.newInputStream(exePath)) {
|
||||
byte[] buf = new byte[4096];
|
||||
byte[] buf = new byte[32768]; // 32KB to cover most PKSFX stubs
|
||||
int read = fis.readNBytes(buf, 0, buf.length);
|
||||
if (read < 0x40) return false;
|
||||
// Must start with MZ
|
||||
if (buf[0] != 0x4D || buf[1] != 0x5A) return false;
|
||||
// Scan the MS-DOS stub area (after the header) for PKWARE signatures
|
||||
// PKSFX/PKZIP stubs contain strings like "PKZIP", "PK", "PKSFX"
|
||||
// in the first few KB of the executable
|
||||
// Scan for PKWARE text signatures in the MS-DOS stub area
|
||||
String content = new String(buf, 0, read, java.nio.charset.StandardCharsets.ISO_8859_1);
|
||||
if (content.contains("PKZIP") || content.contains("PKSFX"))
|
||||
return true;
|
||||
// Check for the typical PKWARE "PK\x03\x04" local file header signature
|
||||
// which appears in append-to-exe style self-extractors
|
||||
for (int i = 0; i < read - 4; i++) {
|
||||
if (buf[i] == 0x50 && buf[i+1] == 0x4B && buf[i+2] == 0x03 && buf[i+3] == 0x04)
|
||||
return true;
|
||||
if (buf[i] == 0x50 && buf[i+1] == 0x4B && buf[i+2] == 0x05 && buf[i+3] == 0x06)
|
||||
// Check for PKWARE zip signatures in appended zip data.
|
||||
// Only check at reasonable offsets (past the MZ header + stub)
|
||||
// to avoid false positives on code bytes that happen to be 0x50,0x4B.
|
||||
for (int i = 0x40; i < read - 4; i++) {
|
||||
int p = buf[i] & 0xFF;
|
||||
// PK\x03\x04 = local file header, PK\x01\x02 = central dir
|
||||
if (p == 0x50 && (buf[i+1] & 0xFF) == 0x4B) {
|
||||
int sig = (buf[i+2] & 0xFF) | ((buf[i+3] & 0xFF) << 8);
|
||||
if (sig == 0x0403 || sig == 0x0201 || sig == 0x0605)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
@@ -379,7 +385,7 @@ public class UploadResource {
|
||||
"debug", // Debugger
|
||||
"uninst", "uninstall", "uninstaller", // Uninstallers
|
||||
// Compression / archive tools (self-extractors)
|
||||
"pksfx", "pkzip", "pkunzip", // PKWARE
|
||||
"pksfx", "pkzip", "pkunzip", "sfx", "makesfx", // PKWARE
|
||||
"unzip", "zip", "zip2exe", // Info-ZIP
|
||||
"arj", "arj32", // ARJ
|
||||
"lha", "lha32", "lzh", // LHA/LHarc
|
||||
|
||||
Reference in New Issue
Block a user