Various checks for binary lua files (#397)
* various checks for binary lua files * endianness
This commit is contained in:
parent
2fc3d7fee9
commit
175dbada5a
|
@ -64,7 +64,111 @@ void smlua_exec_str(char* str) {
|
||||||
lua_pop(L, lua_gettop(L));
|
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) {
|
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_State* L = gLuaState;
|
||||||
|
|
||||||
lua_settop(L, 0);
|
lua_settop(L, 0);
|
||||||
|
|
Loading…
Reference in New Issue