fix: read beyond initial 0x80 buffer when PE/NE sig is at higher offset
Build & Deploy / build-and-deploy (push) Successful in 52s

PlatformDetector.detect() and GameService.detectPlatformInBundle()
both read only 0x80 bytes initially, but PE e_lfanew often points to
0x80 (128), putting the signature 2 bytes past the buffer. Added
fallback: re-read up to peOffset+2 bytes when needed.

Fixes PlatformDetectorTest detect_peHeader_returnsWindows and
detect_neHeader_returnsWindows assertions.
This commit is contained in:
David Alvarez
2026-06-10 09:40:54 +02:00
parent 40ca1187db
commit f5815a0ba9
2 changed files with 25 additions and 0 deletions
@@ -229,6 +229,17 @@ public class GameService implements GameStore {
if (entry.getName().equals(relExe.replace('\\', '/'))) { if (entry.getName().equals(relExe.replace('\\', '/'))) {
byte[] buf = new byte[0x80]; byte[] buf = new byte[0x80];
int read = zis.readNBytes(buf, 0, buf.length); int read = zis.readNBytes(buf, 0, buf.length);
// Read more if PE/NE signature is beyond the initial buffer
if (read >= 0x40) {
int peOffset = (buf[0x3C] & 0xFF) | ((buf[0x3D] & 0xFF) << 8)
| ((buf[0x3E] & 0xFF) << 16) | ((buf[0x3F] & 0xFF) << 24);
if (peOffset + 2 > read) {
buf = java.util.Arrays.copyOf(buf, Math.max(buf.length, peOffset + 2));
int remaining = buf.length - read;
zis.readNBytes(buf, read, remaining);
read = buf.length;
}
}
return PlatformDetector.detectFromBytes(buf, read); return PlatformDetector.detectFromBytes(buf, read);
} }
zis.closeEntry(); zis.closeEntry();
@@ -31,6 +31,20 @@ public class PlatformDetector {
try (var fis = Files.newInputStream(exePath)) { try (var fis = Files.newInputStream(exePath)) {
byte[] buf = new byte[0x80]; byte[] buf = new byte[0x80];
int read = fis.readNBytes(buf, 0, buf.length); int read = fis.readNBytes(buf, 0, buf.length);
// If the PE/NE signature is beyond the initial buffer, read more
if (read >= 0x40) {
int peOffset = (buf[0x3C] & 0xFF)
| ((buf[0x3D] & 0xFF) << 8)
| ((buf[0x3E] & 0xFF) << 16)
| ((buf[0x3F] & 0xFF) << 24);
if (peOffset + 2 > read) {
// Need to read beyond the initial buffer
buf = java.util.Arrays.copyOf(buf, Math.max(buf.length, peOffset + 2));
int remaining = buf.length - read;
fis.readNBytes(buf, read, remaining);
read = buf.length;
}
}
return detectFromBytes(buf, read); return detectFromBytes(buf, read);
} catch (IOException e) { } catch (IOException e) {
LOG.warning("Could not read EXE header for " + exePath + ": " + e.getMessage()); LOG.warning("Could not read EXE header for " + exePath + ": " + e.getMessage());