Added cycle detection to Variant

We accidentally enabled nested tables previously, and now it errors properly when the tables contain cycles. Before you'd get (or at least I got) a nice lua stack overflow error.

--HG--
branch : minor
This commit is contained in:
Bart van Strien
2017-08-30 13:07:57 +02:00
parent d35f69bcff
commit 5ddc89a033
7 changed files with 44 additions and 18 deletions
+17 -3
View File
@@ -18,6 +18,8 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#include <memory>
#include "Variant.h"
#include "common/StringMap.h"
@@ -162,7 +164,7 @@ Variant &Variant::operator = (const Variant &v)
return *this;
}
Variant Variant::fromLua(lua_State *L, int n, bool allowTables)
Variant Variant::fromLua(lua_State *L, int n, std::set<const void*> *tableSet)
{
size_t len;
const char *str;
@@ -186,11 +188,23 @@ Variant Variant::fromLua(lua_State *L, int n, bool allowTables)
case LUA_TNIL:
return Variant();
case LUA_TTABLE:
if (allowTables)
{
bool success = true;
std::unique_ptr<std::set<const void*>> tableSetPtr;
std::vector<std::pair<Variant, Variant>> *table = new std::vector<std::pair<Variant, Variant>>();
// If we had no tables argument, allocate one now, and store it in our unique_ptr
if (tableSet == nullptr)
tableSetPtr.reset(tableSet = new std::set<const void*>);
// Now make sure this table wasn't already serialised
{
const void *table = lua_topointer(L, n);
auto result = tableSet->insert(table);
if (!result.second) // insertion failed
throw love::Exception("Cycle detected in table");
}
size_t len = luax_objlen(L, -1);
if (len > 0)
table->reserve(len);
@@ -199,7 +213,7 @@ Variant Variant::fromLua(lua_State *L, int n, bool allowTables)
while (lua_next(L, n))
{
table->emplace_back(fromLua(L, -2), fromLua(L, -1));
table->emplace_back(fromLua(L, -2, tableSet), fromLua(L, -1, tableSet));
lua_pop(L, 1);
const auto &p = table->back();