Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package emptyepsilon for openSUSE:Factory checked in at 2024-09-16 17:43:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/emptyepsilon (Old) and /work/SRC/openSUSE:Factory/.emptyepsilon.new.29891 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "emptyepsilon" Mon Sep 16 17:43:01 2024 rev:3 rq:1201280 version:2024.08.09 Changes: -------- --- /work/SRC/openSUSE:Factory/emptyepsilon/emptyepsilon.changes 2024-02-23 16:45:09.262956415 +0100 +++ /work/SRC/openSUSE:Factory/.emptyepsilon.new.29891/emptyepsilon.changes 2024-09-16 17:44:17.848087501 +0200 @@ -1,0 +2,10 @@ +Sun Sep 15 16:52:32 UTC 2024 - Dominik Heidler <dheid...@suse.com> + +- Version 2024.08.09 + * Add a quick&dirty way to get callback errors + * Clamp the warp and jump commands + * fix voice path scenario 51 + * fix voice path scenario 48 + * Fix the wiggle console with just 1 text line + +------------------------------------------------------------------- Old: ---- EmptyEpsilon-2023.06.17.tar.gz SeriousProton-2023.06.17.tar.gz New: ---- EmptyEpsilon-2024.08.09.tar.gz SeriousProton-2024.08.09.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ emptyepsilon.spec ++++++ --- /var/tmp/diff_new_pack.1khzNy/_old 2024-09-16 17:44:19.716164758 +0200 +++ /var/tmp/diff_new_pack.1khzNy/_new 2024-09-16 17:44:19.716164758 +0200 @@ -17,7 +17,7 @@ Name: emptyepsilon -Version: 2023.06.17 +Version: 2024.08.09 Release: 0 Summary: Open source spaceship bridge simulator License: GPL-2.0-only ++++++ EmptyEpsilon-2023.06.17.tar.gz -> EmptyEpsilon-2024.08.09.tar.gz ++++++ /work/SRC/openSUSE:Factory/emptyepsilon/EmptyEpsilon-2023.06.17.tar.gz /work/SRC/openSUSE:Factory/.emptyepsilon.new.29891/EmptyEpsilon-2024.08.09.tar.gz differ: char 13, line 1 ++++++ SeriousProton-2023.06.17.tar.gz -> SeriousProton-2024.08.09.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/.tinyci new/SeriousProton-EE-2024.08.09/.tinyci --- old/SeriousProton-EE-2023.06.17/.tinyci 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/.tinyci 2024-08-08 09:44:40.000000000 +0200 @@ -5,4 +5,4 @@ directory = _build_native commands = cmake .. -DWARNING_IS_ERROR=1 - make -j 2 + make -j 10 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/CMakeLists.txt new/SeriousProton-EE-2024.08.09/CMakeLists.txt --- old/SeriousProton-EE-2023.06.17/CMakeLists.txt 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/CMakeLists.txt 2024-08-08 09:44:40.000000000 +0200 @@ -22,6 +22,9 @@ set(DOWNLOADS_DIR "${PROJECT_BINARY_DIR}/downloads") file(MAKE_DIRECTORY "${EXTERNAL_DIR}" "${DOWNLOADS_DIR}") +# We just want C++17 for everything we build +set(CMAKE_CXX_STANDARD 17) + include("cmake/DrMingw.cmake") #--------------------------------Dependencies---------------------------------- @@ -170,6 +173,7 @@ src/resources.cpp src/scriptInterface.cpp src/scriptInterfaceMagic.cpp + src/scriptInterfaceSandbox.cpp src/shaderManager.cpp src/soundManager.cpp src/stringImproved.cpp @@ -249,6 +253,7 @@ src/resources.h src/scriptInterface.h src/scriptInterfaceMagic.h + src/scriptInterfaceSandbox.h src/shaderManager.h src/soundManager.h src/stringImproved.h diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/graphics/shader.cpp new/SeriousProton-EE-2024.08.09/src/graphics/shader.cpp --- old/SeriousProton-EE-2023.06.17/src/graphics/shader.cpp 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/src/graphics/shader.cpp 2024-08-08 09:44:40.000000000 +0200 @@ -8,7 +8,7 @@ static Shader* current_shader = nullptr; static const char* vertex_shader_header_es = "#version 100\nprecision highp float;\n"; -static const char* fragment_shader_header_es = "#version 100\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float\n#endif\n"; +static const char* fragment_shader_header_es = "#version 100\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n"; static const char* vertex_shader_header = "#version 120\n"; static const char* fragment_shader_header = "#version 120\n"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/io/dataBuffer.h new/SeriousProton-EE-2024.08.09/src/io/dataBuffer.h --- old/SeriousProton-EE-2023.06.17/src/io/dataBuffer.h 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/src/io/dataBuffer.h 2024-08-08 09:44:40.000000000 +0200 @@ -186,6 +186,7 @@ { uint32_t len = 0; read(len); + if (len == 0) { s.clear(); return; } if (read_index + len > buffer.size()) return; s.assign(reinterpret_cast<char*>(&buffer[read_index]), len); read_index += len; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/io/http/server.cpp new/SeriousProton-EE-2024.08.09/src/io/http/server.cpp --- old/SeriousProton-EE-2023.06.17/src/io/http/server.cpp 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/src/io/http/server.cpp 2024-08-08 09:44:40.000000000 +0200 @@ -57,7 +57,7 @@ { if (*pSrc == '%') { - char dec1, dec2; + signed char dec1, dec2; if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)]) && -1 != (dec2 = HEX2DEC[*(pSrc + 2)])) { @@ -292,6 +292,7 @@ auto path_query = parts[1].partition("?"); request.method = parts[0]; request.path = path_query.first; + request.query.clear(); for(auto& param : path_query.second.split("&")) { auto key_value = param.partition("="); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/io/keyValueTreeLoader.cpp new/SeriousProton-EE-2024.08.09/src/io/keyValueTreeLoader.cpp --- old/SeriousProton-EE-2023.06.17/src/io/keyValueTreeLoader.cpp 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/src/io/keyValueTreeLoader.cpp 2024-08-08 09:44:40.000000000 +0200 @@ -20,7 +20,7 @@ } result = std::make_shared<KeyValueTree>(); - LOG(Info, "Loading tree", resource_name); + LOG(Info, "Loading tree ", resource_name); while(stream->tell() < stream->getSize()) { @@ -44,7 +44,7 @@ } else if (line == "}") { - LOG(Error, "Failed to parse key value tree: Node close while no node open.", resource_name); + LOG(Error, "Failed to parse key value tree: Node close while no node open. ", resource_name); result = nullptr; return; } @@ -54,8 +54,8 @@ } else if (line.length() > 0) { - LOG(Error, "Failed to parse line:", line); - result->root_nodes.clear(); + LOG(Error, "Failed to parse line: ", line); + result = nullptr; return; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/io/keybinding.cpp new/SeriousProton-EE-2024.08.09/src/io/keybinding.cpp --- old/SeriousProton-EE-2023.06.17/src/io/keybinding.cpp 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/src/io/keybinding.cpp 2024-08-08 09:44:40.000000000 +0200 @@ -70,7 +70,7 @@ void Keybinding::addKey(const string& key, bool inverted) { - if (key.startswith("-")) + if (key.startswith("-") && key.length() > 1) { return addKey(key.substr(1), !inverted); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/networkAudioStream.cpp new/SeriousProton-EE-2024.08.09/src/networkAudioStream.cpp --- old/SeriousProton-EE-2023.06.17/src/networkAudioStream.cpp 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/src/networkAudioStream.cpp 2024-08-08 09:44:40.000000000 +0200 @@ -13,7 +13,7 @@ samples.reserve(sample_rate * 10); int error = 0; - decoder = opus_decoder_create(sample_rate, 1, &error); + decoder = opus_decoder_create(48000, 1, &error); } void NetworkAudioStream::onMixSamples(int16_t* stream, int sample_count) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/networkRecorder.cpp new/SeriousProton-EE-2024.08.09/src/networkRecorder.cpp --- old/SeriousProton-EE-2023.06.17/src/networkRecorder.cpp 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/src/networkRecorder.cpp 2024-08-08 09:44:40.000000000 +0200 @@ -101,7 +101,7 @@ void NetworkAudioRecorder::startSending() { int error = 0; - encoder = opus_encoder_create(44100, 1, OPUS_APPLICATION_VOIP, &error); + encoder = opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, &error); if (!encoder) { LOG(ERROR) << "Failed to create opus encoder:" << error; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/scriptInterface.cpp new/SeriousProton-EE-2024.08.09/src/scriptInterface.cpp --- old/SeriousProton-EE-2023.06.17/src/scriptInterface.cpp 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/src/scriptInterface.cpp 2024-08-08 09:44:40.000000000 +0200 @@ -1,8 +1,10 @@ #include <sys/stat.h> +#include <cstring> #include "random.h" #include "resources.h" #include "scriptInterface.h" +#include "scriptInterfaceSandbox.h" static int random(lua_State* L) { @@ -107,6 +109,13 @@ {NULL, NULL} }; +static const char* safe_functions[] = { + "assert", "error", "getmetatable", "ipairs", "next", "pairs", "pcall", + "print", "rawequal", "rawget", "rawlen", "rawset", "require", "select", + "setmetatable", "tonumber", "tostring", "type", "xpcall", + NULL, +}; + void ScriptObject::createLuaState() { if (L == NULL) @@ -119,20 +128,80 @@ luaL_requiref(L, lib->name, lib->func, 1); lua_pop(L, 1); /* remove lib */ } + + // Protect the metatable the string library sets on strings. + // This metatable points to the global `string` library, rather than the environment's copy. + // This global string library table can't be accessed directly, but it means a function defining + // `function string.foo(...)` can't call that function as `"some_string":foo()` since the metatable + // points to the global version rather than its own copy. + // TODO see if this can be fixed without breaking the sandbox. probably not. + lua_pushstring(L, ""); + protectLuaMetatable(L); + lua_pop(L, 1); } //Setup a new table as the first upvalue. This will be used as "global" environment for the script. And thus will prevent global namespace polution. lua_newtable(L); /* environment for loaded function */ + // set a _G in the script's environment pointing to its own global environment + lua_pushstring(L, "_G"); + lua_pushvalue(L, -2); + lua_rawset(L, -3); + + // Copy in the safe global functions. + for (const char **fn = safe_functions; *fn; fn++) + { + lua_pushstring(L, *fn); + lua_getglobal(L, *fn); + lua_rawset(L, -3); + } + + // Copy in the global libraries. + for (const luaL_Reg *lib = loadedlibs; lib->func; lib++) + { + if (!strcmp(lib->name, "_G")) { + continue; + } + + // Make a table for the library. + lua_newtable(L); // [env] [local] + + // Set it into the script environment. + lua_pushstring(L, lib->name); // [env] [local] [libname] + lua_pushvalue(L, -2); // [env] [local] [libname] [local] + lua_rawset(L, -4); // [env] [local] + + // Iterate the global library. + lua_getglobal(L, lib->name); // [env] [local] [global] + lua_pushnil(L); // [env] [local] [global] nil + while (lua_next(L, -2)) + { // [env] [local] [global] [key] [value] + if (!lua_isfunction(L, -1) && !lua_isnumber(L, -1)) + { + // This doesn't trigger on anything right now; it's here in case anything gets added to any of the libraries that would potentially break the sandbox. + LOG(WARNING) << "ignoring non-{function,number} in " << lib->name; + lua_pop(L, 1); + continue; + } + + // Functions and numbers are safe to share - copy the value into the script's library table + lua_pushvalue(L, -2); // [env] [local] [global] [key] [value] [key] + lua_rotate(L, -2, 1); // [env] [local] [global] [key] [key] [value] + lua_rawset(L, -5); // [env] [local] [global] [key] + } + // [env] [local] [global] + lua_pop(L, 2); // [env] + } + //Register all global functions for our game. for(ScriptClassInfo* item = scriptClassInfoList; item != NULL; item = item->next) + { item->register_function(L); - lua_newtable(L); /* meta table for the environment, with an __index pointing to the general global table so we can access every global function */ - lua_pushstring(L, "__index"); - lua_pushglobaltable(L); - lua_rawset(L, -3); - lua_setmetatable(L, -2); + lua_pushstring(L, item->class_name.c_str()); + lua_getglobal(L, item->class_name.c_str()); + lua_rawset(L, -3); + } //Register the destroyScript function. This needs a reference back to the script object, we pass this as an upvalue. lua_pushstring(L, "destroyScript"); @@ -225,7 +294,7 @@ //Set our variable in this environment table lua_pushstring(L, variable_name.c_str()); lua_pushstring(L, value.c_str()); - lua_settable(L, -3); + lua_rawset(L, -3); //Pop the table lua_pop(L, 1); @@ -242,7 +311,7 @@ if (convert< P<PObject> >::returnType(L, object)) { - lua_settable(L, -3); + lua_rawset(L, -3); //Pop the environment table lua_pop(L, 1); }else{ @@ -366,7 +435,7 @@ lua_gettable(L, LUA_REGISTRYINDEX); //Get the function from the environment lua_pushstring(L, name.c_str()); - lua_gettable(L, -2); + lua_rawget(L, -2); //Call the function if (lua_pcall(L, 0, 0, 0)) { @@ -420,7 +489,7 @@ lua_gettable(L, LUA_REGISTRYINDEX); // Get the update function from the script environment lua_pushstring(L, "update"); - lua_gettable(L, -2); + lua_rawget(L, -2); // If it's a function, call it, if not, pop the environment and the function from the stack. if (!lua_isfunction(L, -1)) @@ -511,7 +580,7 @@ lua_pop(L, 1); return; } - + lua_pushnil(L); while (lua_next(L, -2) != 0) { @@ -526,7 +595,7 @@ //Stack is [callback_table] [callback_key] [callback_entry_table] [script_pointer] lua_pushvalue(L, -3); lua_pushnil(L); - lua_settable(L, -6); + lua_rawset(L, -6); lua_pop(L, 1); }else{ lua_pop(L, 1); @@ -697,7 +766,7 @@ //Stack is now: [function_environment] [callback object pointer] [table] "script_pointer" lua_pushstring(L, "__script_pointer"); - lua_gettable(L, -5); + lua_rawget(L, -5); if (lua_isnil(L, -1)) { //Simple functions that do not access globals do not inherit their environment from their creator, so they have nil here. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/scriptInterface.h new/SeriousProton-EE-2024.08.09/src/scriptInterface.h --- old/SeriousProton-EE-2023.06.17/src/scriptInterface.h 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/src/scriptInterface.h 2024-08-08 09:44:40.000000000 +0200 @@ -160,6 +160,7 @@ if (lua_pcall(L, i, 1, 0)) { LOG(ERROR) << "Callback function error: " << lua_tostring(L, -1); + last_error = lua_tostring(L, -1); lua_pop(L, 2); if constexpr (std::is_void_v<Return>) return; @@ -232,6 +233,8 @@ //Return the script object linked to this callback, if any. P<ScriptObject> getScriptObject(); + + static inline string last_error; }; template<> void convert<ScriptSimpleCallback>::param(lua_State* L, int& idx, ScriptSimpleCallback& callback); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/scriptInterfaceMagic.h new/SeriousProton-EE-2024.08.09/src/scriptInterfaceMagic.h --- old/SeriousProton-EE-2023.06.17/src/scriptInterfaceMagic.h 2023-06-09 10:35:14.000000000 +0200 +++ new/SeriousProton-EE-2024.08.09/src/scriptInterfaceMagic.h 2024-08-08 09:44:40.000000000 +0200 @@ -10,6 +10,7 @@ #include "P.h" #include "stringImproved.h" #include "lua/lua.hpp" +#include "scriptInterfaceSandbox.h" #include "glm/gtc/type_precision.hpp" #include <typeinfo> #include <optional> @@ -124,7 +125,7 @@ return; } lua_pushstring(L, "__ptr"); - lua_gettable(L, idx++); + lua_rawget(L, idx++); P<PObject>** p = static_cast< P<PObject>** >(lua_touserdata(L, -1)); lua_pop(L, 1); @@ -153,7 +154,7 @@ return; } lua_pushstring(L, "__ptr"); - lua_gettable(L, idx++); + lua_rawget(L, idx++); P<PObject>** p = static_cast< P<PObject>** >(lua_touserdata(L, -1)); lua_pop(L, 1); @@ -196,7 +197,8 @@ P<PObject>** p = static_cast< P<PObject>** >(lua_newuserdata(L, sizeof(P<PObject>*))); *p = new P<PObject>(); (**p) = ptr; - lua_settable(L, -3); + + lua_rawset(L, -3); lua_pushlightuserdata(L, ptr); lua_pushvalue(L, -2); @@ -367,7 +369,7 @@ if (!lua_istable(L, -1)) luaL_error(L, "??[setcallbackFunction] Upvalue 1 of function is not a table..."); lua_pushstring(L, "__script_pointer"); - lua_gettable(L, -2); + lua_rawget(L, -2); if (!lua_islightuserdata(L, -1)) luaL_error(L, "??[setcallbackFunction] Cannot find reference back to script..."); //Stack is now: [function_environment] [pointer] @@ -523,7 +525,7 @@ if (!lua_istable(L, -1)) return 0; lua_pushstring(L, "__ptr"); - lua_gettable(L, -2); + lua_rawget(L, -2); if (lua_isuserdata(L, -1)) //When a subclass is destroyed, it's metatable might call the __gc function on it's sub-metatable. So we can get nil values here, ignore that. { PT* p = static_cast< PT* >(lua_touserdata(L, -1)); @@ -598,6 +600,10 @@ lua_pop(L, 1); luaL_newmetatable(L, objectTypeName); } + + lua_pushstring(L, "__metatable"); // protect the metatable + lua_pushstring(L, "sandbox"); + lua_settable(L, metatable); lua_pushstring(L, "__gc"); lua_pushcfunction(L, gc_collect); @@ -701,4 +707,12 @@ } \ ScriptClassInfo scriptClassInfo ## F ( # F , "" , registerFunctionFunction ## F , NULL ); +#define REGISTER_SCRIPT_FUNCTION_NAMED(F, NAME) \ + static void registerFunctionFunction ## F (lua_State* L) { \ + lua_pushvalue(L, -1); \ + lua_pushcclosure(L, &F, 1); \ + lua_setglobal(L, NAME ); \ + } \ + ScriptClassInfo scriptClassInfo ## F ( NAME , "" , registerFunctionFunction ## F , NULL ); + #endif//SCRIPT_INTERFACE_MAGIC_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/scriptInterfaceSandbox.cpp new/SeriousProton-EE-2024.08.09/src/scriptInterfaceSandbox.cpp --- old/SeriousProton-EE-2023.06.17/src/scriptInterfaceSandbox.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/SeriousProton-EE-2024.08.09/src/scriptInterfaceSandbox.cpp 2024-08-08 09:44:40.000000000 +0200 @@ -0,0 +1,19 @@ +#include "lua/lua.hpp" +#include "scriptInterfaceSandbox.h" + +// Add or protect a metatable for the provided object +// Input Lua stack: [object] +// Output Lua stack: [object] +void protectLuaMetatable(lua_State* L) +{ + if (!lua_getmetatable(L, -1)) { + lua_newtable(L); // [object] [mt] + lua_pushvalue(L, -1); // [object] [mt] [mt] + lua_setmetatable(L, -3); // [object] [mt] + } + + lua_pushstring(L, "__metatable"); // [object] [mt] "__metatable" + lua_pushstring(L, "sandbox"); // [object] [mt] "__metatable" "sandbox" + lua_rawset(L, -3); // [object] [mt] + lua_pop(L, 1); // [object] +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SeriousProton-EE-2023.06.17/src/scriptInterfaceSandbox.h new/SeriousProton-EE-2024.08.09/src/scriptInterfaceSandbox.h --- old/SeriousProton-EE-2023.06.17/src/scriptInterfaceSandbox.h 1970-01-01 01:00:00.000000000 +0100 +++ new/SeriousProton-EE-2024.08.09/src/scriptInterfaceSandbox.h 2024-08-08 09:44:40.000000000 +0200 @@ -0,0 +1,11 @@ +#ifndef SCRIPT_INTERFACE_SANDBOX_H +#define SCRIPT_INTERFACE_SANDBOX_H + +#include "lua/lua.hpp" + +// Add or protect a metatable for the provided object such that the metatable can't be read or changed from inside the sandbox. +// Input Lua stack: [object] +// Output Lua stack: [object] +void protectLuaMetatable(lua_State* L); + +#endif // SCRIPT_INTERFACE_SANDBOX_H