Various checks for binary lua files (#397)

* various checks for binary lua files

* endianness
This commit is contained in:
PeachyPeach 2023-06-11 23:36:15 +02:00 committed by GitHub
parent 2fc3d7fee9
commit 175dbada5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 104 additions and 0 deletions

View File

@ -64,7 +64,111 @@ void smlua_exec_str(char* str) {
lua_pop(L, lua_gettop(L));
}
#define LUA_BOM_11 0x0000000000005678llu
#define LUA_BOM_19 0x4077280000000000llu
static bool smlua_check_binary_header(struct ModFile *file) {
FILE *f = fopen(file->cachedPath, "rb");
if (f) {
// Read signature
char signature[sizeof(LUA_SIGNATURE)] = {0};
if (fread(signature, 1, sizeof(LUA_SIGNATURE) - 1, f) != sizeof(LUA_SIGNATURE) - 1) {
LOG_LUA("Failed to load lua script '%s': File too short.", file->cachedPath);
fclose(f);
return false;
}
// Check signature
if (strcmp(signature, LUA_SIGNATURE) != 0) {
fclose(f);
return true; // Not a binary lua
}
// Read version number
u8 version;
if (fread(&version, 1, 1, f) != 1) {
LOG_LUA("Failed to load lua script '%s': File too short.", file->cachedPath);
fclose(f);
return false;
}
// Check version number
u8 expectedVersion = strtoul(LUA_VERSION_MAJOR LUA_VERSION_MINOR, NULL, 16);
if (version != expectedVersion) {
LOG_LUA("Failed to load lua script '%s': Lua versions don't match (%X, expected %X).", file->cachedPath, version, expectedVersion);
fclose(f);
return false;
}
// Read the rest of the header
u8 header[28];
if (fread(header, 1, 28, f) != 28) {
LOG_LUA("Failed to load lua script '%s': File too short.", file->cachedPath);
fclose(f);
return false;
}
// The following errors are silent (they're due to non-matching endianness/bitness and shouldn't prevent the rest of the mod from loading)
// Check endianness
u64 bom11 = *((u64 *) (header + 12));
u64 bom19 = *((u64 *) (header + 20));
if (bom11 != LUA_BOM_11) {
LOG_ERROR("Failed to load lua script '%s': BOM at offset 0x11 don't match (%016llX, expected %016llX).", file->cachedPath, bom11, LUA_BOM_11);
fclose(f);
return false;
}
if (bom19 != LUA_BOM_19) {
LOG_ERROR("Failed to load lua script '%s': BOM at offset 0x19 don't match (%016llX, expected %016llX).", file->cachedPath, bom19, LUA_BOM_19);
fclose(f);
return false;
}
// Check sizes
u8 sizeOfCInteger = header[7];
u8 sizeOfCPointer = header[8];
u8 sizeOfCFloat = header[9];
u8 sizeOfLuaInteger = header[10];
u8 sizeOfLuaNumber = header[11];
if (sizeOfCInteger != sizeof(int)) {
LOG_ERROR("Failed to load lua script '%s': sizes of C Integer don't match (%d, expected %llu).", file->cachedPath, sizeOfCInteger, sizeof(int));
fclose(f);
return false;
}
if (sizeOfCPointer != sizeof(void *)) { // 4 for 32-bit architectures, 8 for 64-bit
LOG_ERROR("Failed to load lua script '%s': sizes of C Pointer don't match (%d, expected %llu).", file->cachedPath, sizeOfCPointer, sizeof(void *));
fclose(f);
return false;
}
if (sizeOfCFloat != sizeof(float)) {
LOG_ERROR("Failed to load lua script '%s': sizes of C Float don't match (%d, expected %llu).", file->cachedPath, sizeOfCFloat, sizeof(float));
fclose(f);
return false;
}
if (sizeOfLuaInteger != sizeof(LUA_INTEGER)) {
LOG_ERROR("Failed to load lua script '%s': sizes of Lua Integer don't match (%d, expected %llu).", file->cachedPath, sizeOfLuaInteger, sizeof(LUA_INTEGER));
fclose(f);
return false;
}
if (sizeOfLuaNumber != sizeof(LUA_NUMBER)) {
LOG_ERROR("Failed to load lua script '%s': sizes of Lua Number don't match (%d, expected %llu).", file->cachedPath, sizeOfLuaNumber, sizeof(LUA_NUMBER));
fclose(f);
return false;
}
// All's good
LOG_INFO("Loading lua script '%s'", file->cachedPath);
fclose(f);
return true;
}
LOG_LUA("Failed to load lua script '%s': File not found.", file->cachedPath);
return false;
}
static void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteIndex) {
if (!smlua_check_binary_header(file)) return;
lua_State* L = gLuaState;
lua_settop(L, 0);