Skip to content

Commit 5ab546f

Browse files
committedNov 9, 2019
Refactor loading of Lua code with mod security
1 parent 17191a6 commit 5ab546f

File tree

2 files changed

+28
-52
lines changed

2 files changed

+28
-52
lines changed
 

‎src/script/cpp_api/s_security.cpp

+26-52
Original file line numberDiff line numberDiff line change
@@ -372,14 +372,16 @@ bool ScriptApiSecurity::isSecure(lua_State *L)
372372
return secure;
373373
}
374374

375-
376-
#define CHECK_FILE_ERR(ret, fp) \
377-
if (ret) { \
378-
lua_pushfstring(L, "%s: %s", path, strerror(errno)); \
379-
if (fp) std::fclose(fp); \
380-
return false; \
375+
bool ScriptApiSecurity::safeLoadString(lua_State *L, const std::string &code, const char *chunk_name)
376+
{
377+
if (code.size() > 0 && code[0] == LUA_SIGNATURE[0]) {
378+
lua_pushliteral(L, "Bytecode prohibited when mod security is enabled.");
379+
return false;
381380
}
382-
381+
if (luaL_loadbuffer(L, code.data(), code.size(), chunk_name))
382+
return false;
383+
return true;
384+
}
383385

384386
bool ScriptApiSecurity::safeLoadFile(lua_State *L, const char *path, const char *display_name)
385387
{
@@ -406,68 +408,49 @@ bool ScriptApiSecurity::safeLoadFile(lua_State *L, const char *path, const char
406408
int c = std::getc(fp);
407409
if (c == '#') {
408410
// Skip the first line
409-
while ((c = std::getc(fp)) != EOF && c != '\n');
410-
if (c == '\n') c = std::getc(fp);
411+
while ((c = std::getc(fp)) != EOF && c != '\n') {}
412+
if (c == '\n')
413+
std::getc(fp);
411414
start = std::ftell(fp);
412415
}
413416

414-
if (c == LUA_SIGNATURE[0]) {
415-
lua_pushliteral(L, "Bytecode prohibited when mod security is enabled.");
416-
std::fclose(fp);
417-
if (path) {
418-
delete [] chunk_name;
419-
}
420-
return false;
421-
}
422-
423417
// Read the file
424418
int ret = std::fseek(fp, 0, SEEK_END);
425419
if (ret) {
426420
lua_pushfstring(L, "%s: %s", path, strerror(errno));
427-
std::fclose(fp);
428421
if (path) {
422+
std::fclose(fp);
429423
delete [] chunk_name;
430424
}
431425
return false;
432426
}
433427

434428
size_t size = std::ftell(fp) - start;
435-
char *code = new char[size];
429+
std::string code(size, '\0');
436430
ret = std::fseek(fp, start, SEEK_SET);
437431
if (ret) {
438432
lua_pushfstring(L, "%s: %s", path, strerror(errno));
439-
std::fclose(fp);
440-
delete [] code;
441433
if (path) {
434+
std::fclose(fp);
442435
delete [] chunk_name;
443436
}
444437
return false;
445438
}
446439

447-
size_t num_read = std::fread(code, 1, size, fp);
448-
if (path) {
440+
size_t num_read = std::fread(&code[0], 1, size, fp);
441+
if (path)
449442
std::fclose(fp);
450-
}
451443
if (num_read != size) {
452444
lua_pushliteral(L, "Error reading file to load.");
453-
delete [] code;
454-
if (path) {
445+
if (path)
455446
delete [] chunk_name;
456-
}
457-
return false;
458-
}
459-
460-
if (luaL_loadbuffer(L, code, size, chunk_name)) {
461-
delete [] code;
462447
return false;
463448
}
464449

465-
delete [] code;
466-
467-
if (path) {
450+
bool result = safeLoadString(L, code, chunk_name);
451+
if (path)
468452
delete [] chunk_name;
469-
}
470-
return true;
453+
return result;
471454
}
472455

473456

@@ -628,14 +611,9 @@ int ScriptApiSecurity::sl_g_load(lua_State *L)
628611
code += std::string(buf, len);
629612
lua_pop(L, 1); // Pop return value
630613
}
631-
if (code[0] == LUA_SIGNATURE[0]) {
632-
lua_pushnil(L);
633-
lua_pushliteral(L, "Bytecode prohibited when mod security is enabled.");
634-
return 2;
635-
}
636-
if (luaL_loadbuffer(L, code.data(), code.size(), chunk_name)) {
614+
if (!safeLoadString(L, code, chunk_name)) {
637615
lua_pushnil(L);
638-
lua_insert(L, lua_gettop(L) - 1);
616+
lua_insert(L, -2);
639617
return 2;
640618
}
641619
return 1;
@@ -694,15 +672,11 @@ int ScriptApiSecurity::sl_g_loadstring(lua_State *L)
694672

695673
size_t size;
696674
const char *code = lua_tolstring(L, 1, &size);
675+
std::string code_s(code, size);
697676

698-
if (size > 0 && code[0] == LUA_SIGNATURE[0]) {
677+
if (!safeLoadString(L, code_s, chunk_name)) {
699678
lua_pushnil(L);
700-
lua_pushliteral(L, "Bytecode prohibited when mod security is enabled.");
701-
return 2;
702-
}
703-
if (luaL_loadbuffer(L, code, size, chunk_name)) {
704-
lua_pushnil(L);
705-
lua_insert(L, lua_gettop(L) - 1);
679+
lua_insert(L, -2);
706680
return 2;
707681
}
708682
return 1;

‎src/script/cpp_api/s_security.h

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class ScriptApiSecurity : virtual public ScriptApiBase
5050
void initializeSecurityClient();
5151
// Checks if the Lua state has been secured
5252
static bool isSecure(lua_State *L);
53+
// Loads a string as Lua code safely (doesn't allow bytecode).
54+
static bool safeLoadString(lua_State *L, const std::string &code, const char *chunk_name);
5355
// Loads a file as Lua code safely (doesn't allow bytecode).
5456
static bool safeLoadFile(lua_State *L, const char *path, const char *display_name = NULL);
5557
// Checks if mods are allowed to read (and optionally write) to the path

0 commit comments

Comments
 (0)
Please sign in to comment.