Show failure
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index ae4983d..b73df07 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp
@@ -2765,13 +2765,11 @@ namespace HeapTypes { HeapType getMutI8Array() { - static HeapType i8Array = Array(Field(Field::i8, Mutable)); - return i8Array; + return Array(Field(Field::i8, Mutable)); } HeapType getMutI16Array() { - static HeapType i16Array = Array(Field(Field::i16, Mutable)); - return i16Array; + return Array(Field(Field::i16, Mutable)); } } // namespace HeapTypes @@ -2779,8 +2777,7 @@ namespace Types { Type getI64Pair() { - static Type i64Pair({Type::i64, Type::i64}); - return i64Pair; + return Type({Type::i64, Type::i64}); } } // namespace Types
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 6aa8373..cce6b2f 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp
@@ -812,8 +812,7 @@ rightHigh->type == Type::unreachable) { type = Type::unreachable; } else { - static Type i64Pair = Types::getI64Pair(); - type = i64Pair; + type = Types::getI64Pair(); } } @@ -821,8 +820,7 @@ if (left->type == Type::unreachable || right->type == Type::unreachable) { type = Type::unreachable; } else { - static Type i64Pair = Types::getI64Pair(); - type = i64Pair; + type = Types::getI64Pair(); } }
diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index 0953df4..e4fcb60 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt
@@ -35,6 +35,7 @@ suffix_tree.cpp topological-sort.cpp type-builder.cpp + type-caching.cpp wat-lexer.cpp validator.cpp source-map.cpp
diff --git a/test/gtest/type-caching.cpp b/test/gtest/type-caching.cpp new file mode 100644 index 0000000..0a4e22d --- /dev/null +++ b/test/gtest/type-caching.cpp
@@ -0,0 +1,30 @@ +#include "wasm-type.h" +#include "type-test.h" +#include "gtest/gtest.h" + +using namespace wasm; + +TEST_F(TypeTest, UseAfterFreeOfCachedTypes) { + // 1. Initialize the static types. + HeapType i8Array1 = HeapTypes::getMutI8Array(); + HeapType i16Array1 = HeapTypes::getMutI16Array(); + Type i64Pair1 = Types::getI64Pair(); + + EXPECT_TRUE(i8Array1.isArray()); + EXPECT_TRUE(i16Array1.isArray()); + EXPECT_TRUE(i64Pair1.isTuple()); + + // 2. Destroy all types, simulating the end of a test case. + wasm::destroyAllTypesForTestingPurposesOnly(); + + // 3. Attempt to get the types again. Since they are cached as static local + // variables, these calls will return the old, now-dangling references. + HeapType i8Array2 = HeapTypes::getMutI8Array(); + HeapType i16Array2 = HeapTypes::getMutI16Array(); + Type i64Pair2 = Types::getI64Pair(); + + // 4. Accessing the dangling references will cause a use-after-free. + EXPECT_TRUE(i8Array2.isArray()); + EXPECT_TRUE(i16Array2.isArray()); + EXPECT_TRUE(i64Pair2.isTuple()); +}