From 0914f116c06d4724f25e23b685279024f809f434 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Wed, 19 Jun 2024 10:00:39 +0100 Subject: win32: code shrink APE detection; avoid UB Detecting Actually Portable Executable binaries used a longer signature than seems necessary. Six characters should be enough for anyone. When right shifting a byte by 24 bits, cast it to unsigned to avoid undefined behaviour. Saves 24-32 bytes. (GitHub issue #424) --- win32/mingw.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/win32/mingw.c b/win32/mingw.c index 26b046f1a..98254fdbe 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -473,16 +473,20 @@ static int has_exec_format(const char *name) * the magic from the file command. */ if (buf[0] == 'M' && buf[1] == 'Z') { +/* Convert four unsigned bytes to an unsigned int (little-endian) */ +#define LE4(b, o) (((unsigned)b[o+3] << 24) + (b[o+2] << 16) + \ + (b[o+1] << 8) + b[o]) + /* Actually Portable Executable */ /* See ape/ape.S at https://github.com/jart/cosmopolitan */ - if (n > 9 && memcmp(buf + 2, "qFpD='\n", 7) == 0) + const unsigned char *qFpD = (unsigned char *)"qFpD"; + if (n > 6 && LE4(buf, 2) == LE4(qFpD, 0)) return 1; if (n > 0x3f) { offset = (buf[0x19] << 8) + buf[0x18]; if (offset > 0x3f) { - offset = (buf[0x3f] << 24) + (buf[0x3e] << 16) + - (buf[0x3d] << 8) + buf[0x3c]; + offset = LE4(buf, 0x3c); if (offset < sizeof(buf)-100) { if (memcmp(buf+offset, "PE\0\0", 4) == 0) { sig = (buf[offset+25] << 8) + buf[offset+24]; -- cgit v1.2.3-55-g6feb