Skip to content

Commit

Permalink
Added reference and stack value ownership checks.
Browse files Browse the repository at this point in the history
  • Loading branch information
Quahu committed Mar 27, 2024
1 parent de589ca commit 1ac271e
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/Laylua.Tests/LuaTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ protected virtual LuaAllocator CreateLuaAllocator(nuint maxBytes = 0)
return allocator;
}

protected virtual Lua CreateLua(LuaAllocator allocator)
protected virtual Lua CreateLua(LuaAllocator? allocator = null)
{
return new Lua(allocator)
return new Lua(allocator ?? CreateLuaAllocator())
{
FormatProvider = CultureInfo.InvariantCulture
};
Expand Down
32 changes: 32 additions & 0 deletions src/Laylua.Tests/Tests/Marshaler/LuaMarshalerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,36 @@ public void PushCollection_PopTable_ReturnsSameValues(IEnumerable collection, Ac

assert(table);
}

[Test]
public void PushUnownedReference_Throws()
{
// Arrange
using var lua1 = CreateLua();
Lua.Stack.PushNewTable();
using var table = Lua.Stack[1].GetValue<LuaTable>()!;
Lua.Stack.Pop();

// Act
var ex = Assert.Throws<InvalidOperationException>(() => lua1.Stack.Push(table));

// Assert
Assert.That(ex, Has.Message.Contain("owned"));
}

[Test]
public void PushUnownedStackValue_Throws()
{
// Arrange
using var _ = Lua.Stack.SnapshotCount();
using var lua1 = CreateLua();
Lua.Stack.PushNewTable();
var table = Lua.Stack[1];

// Act
var ex = Assert.Throws<InvalidOperationException>(() => lua1.Stack.Push(table));

// Assert
Assert.That(ex, Has.Message.Contain("owned"));
}
}
8 changes: 8 additions & 0 deletions src/Laylua/Library/Entities/Reference/LuaReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,14 @@ internal static bool TryCreate(lua_State* L, int stackIndex, out int reference)
return true;
}

internal static void ValidateOwnership(Lua lua, LuaReference reference)
{
if (lua != reference._lua)
{
throw new InvalidOperationException($"The given {reference.GetType().Name.SingleQuoted()} is owned by a different Lua state.");
}
}

/// <summary>
/// Checks whether the specified reference is alive,
/// i.e. is initialized and not disposed.
Expand Down
8 changes: 8 additions & 0 deletions src/Laylua/Library/LuaStackValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ private void ThrowIfInvalid()
throw new InvalidOperationException($"The index of this {nameof(LuaStackValue)} is not valid.");
}

internal static void ValidateOwnership(Lua lua, LuaStackValue value)
{
if (lua != value._lua)
{
throw new InvalidOperationException($"The given stack value is owned by a different Lua state.");
}
}

/// <summary>
/// Pushes the value of this stack value
/// onto the stack.
Expand Down
2 changes: 2 additions & 0 deletions src/Laylua/Library/Marshaler/DefaultLuaMarshaler.PushValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,13 @@ public override void PushValue<T>(T obj)
}
case LuaStackValue:
{
LuaStackValue.ValidateOwnership(Lua, (LuaStackValue) (object) obj);
((LuaStackValue) (object) obj).PushValue();
return;
}
case LuaReference:
{
LuaReference.ValidateOwnership(Lua, (LuaReference) (object) obj);
LuaReference.PushValue((LuaReference) (object) obj);
return;
}
Expand Down

0 comments on commit 1ac271e

Please sign in to comment.