Skip to content

Commit 6b926f8

Browse files
authored
Added handle.IsClosed checks on all NativeHandle properties. This protects against accessing various things after they have been disposed. (#289)
1 parent e03d3e1 commit 6b926f8

File tree

8 files changed

+65
-5
lines changed

8 files changed

+65
-5
lines changed

src/Config.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ internal Handle NativeHandle
353353
{
354354
get
355355
{
356-
if (handle.IsInvalid)
356+
if (handle.IsInvalid || handle.IsClosed)
357357
{
358358
throw new ObjectDisposedException(typeof(Config).FullName);
359359
}

src/Engine.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ internal Handle NativeHandle
4848
{
4949
get
5050
{
51-
if (handle.IsInvalid)
51+
if (handle.IsInvalid || handle.IsClosed)
5252
{
5353
throw new ObjectDisposedException(typeof(Engine).FullName);
5454
}

src/Module.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ internal Handle NativeHandle
387387
{
388388
get
389389
{
390-
if (handle.IsInvalid)
390+
if (handle.IsInvalid || handle.IsClosed)
391391
{
392392
throw new ObjectDisposedException(typeof(Module).FullName);
393393
}

src/Store.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ internal Handle NativeHandle
279279
{
280280
get
281281
{
282-
if (handle.IsInvalid)
282+
if (handle.IsInvalid || handle.IsClosed)
283283
{
284284
throw new ObjectDisposedException(typeof(Store).FullName);
285285
}

tests/ConfigTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,5 +166,17 @@ public void ItSetsMultiValue()
166166

167167
act.Should().Throw<WasmtimeException>();
168168
}
169+
170+
[Fact]
171+
public void ItCannotBeAccessedOnceDisposed()
172+
{
173+
var config = new Config();
174+
config.Dispose();
175+
176+
Assert.Throws<ObjectDisposedException>(() => config.NativeHandle);
177+
Assert.Throws<ObjectDisposedException>(() => config.WithBulkMemory(true));
178+
Assert.Throws<ObjectDisposedException>(() => config.WithCacheConfig(null));
179+
Assert.Throws<ObjectDisposedException>(() => config.WithEpochInterruption(true));
180+
}
169181
}
170182
}

tests/EngineTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using Xunit;
3+
4+
namespace Wasmtime.Tests;
5+
6+
public class EngineTests
7+
{
8+
[Fact]
9+
public void ItCannotBeAccessedOnceDisposed()
10+
{
11+
var engine = new Engine();
12+
13+
engine.Dispose();
14+
15+
Assert.Throws<ObjectDisposedException>(() => engine.NativeHandle);
16+
Assert.Throws<ObjectDisposedException>(() => engine.IncrementEpoch());
17+
}
18+
}

tests/ModuleLoadTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,20 @@ public void ItLoadsModuleTextFromEmbeddedResource()
5151
// `ObjectDisposedException`
5252
stream.Read(new byte[0], 0, 0);
5353
}
54+
55+
[Fact]
56+
public void ItCannotBeAccessedOnceDisposed()
57+
{
58+
using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("hello.wasm");
59+
stream.Should().NotBeNull();
60+
61+
using var engine = new Engine();
62+
var module = Module.FromStream(engine, "hello.wasm", stream);
63+
64+
module.Dispose();
65+
66+
Assert.Throws<ObjectDisposedException>(() => module.NativeHandle);
67+
Assert.Throws<ObjectDisposedException>(() => module.Serialize());
68+
}
5469
}
5570
}

tests/StoreTests.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using FluentAssertions;
1+
using System;
2+
using FluentAssertions;
23
using System.IO;
34
using Xunit;
45

@@ -91,5 +92,19 @@ public void ItLimitsMemories()
9192
var act = () => { new Instance(Store, module); };
9293
act.Should().Throw<WasmtimeException>();
9394
}
95+
96+
[Fact]
97+
public void ItCannotBeAccessedOnceDisposed()
98+
{
99+
var ctx = Store.Context;
100+
Assert.Equal(Store, ctx.Store);
101+
102+
Store.Dispose();
103+
104+
Assert.Throws<ObjectDisposedException>(() => { var x = Store.Context; });
105+
Assert.Throws<ObjectDisposedException>(() => Store.NativeHandle);
106+
Assert.Throws<ObjectDisposedException>(() => Store.Fuel);
107+
Assert.Throws<ObjectDisposedException>(() => Store.GC());
108+
}
94109
}
95110
}

0 commit comments

Comments
 (0)