summaryrefslogtreecommitdiff
path: root/src/wasm/literal.cpp
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2020-09-01 15:55:58 -0700
committerGitHub <noreply@github.com>2020-09-01 15:55:58 -0700
commit85234cb540c2b2863dfea6c20496dcb451df8889 (patch)
treea2475df8d4f79a4d04f43cb991b4a4a07b59b9c4 /src/wasm/literal.cpp
parentfecfa92d71633f8bb28bb97a60adc9b54998456f (diff)
downloadbinaryen-85234cb540c2b2863dfea6c20496dcb451df8889.tar.gz
binaryen-85234cb540c2b2863dfea6c20496dcb451df8889.tar.bz2
binaryen-85234cb540c2b2863dfea6c20496dcb451df8889.zip
Fix ExceptionPackage memory errors (#3088)
First, adds an explicit destructor call to fix a memory leak in `Literal::operator=` in which existing `ExceptionPackage`s would be silently dropped. Next, changes `Literal::getExceptionPackage` to return the `ExceptionPackage` by value to avoid a use-after-free bug in the interpreter that was surfaced by the new destructor call. A future improvement would be to switch to using `std::variant`. Fixes #3087.
Diffstat (limited to 'src/wasm/literal.cpp')
-rw-r--r--src/wasm/literal.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index ffb007cf3..ce1c73d56 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -33,10 +33,7 @@ Literal::Literal(const uint8_t init[16]) : type(Type::v128) {
memcpy(&v128, init, 16);
}
-Literal::Literal(const Literal& other) { *this = other; }
-
-Literal& Literal::operator=(const Literal& other) {
- type = other.type;
+Literal::Literal(const Literal& other) : type(other.type) {
TODO_SINGLE_COMPOUND(type);
switch (type.getBasic()) {
case Type::i32:
@@ -54,6 +51,7 @@ Literal& Literal::operator=(const Literal& other) {
func = other.func;
break;
case Type::exnref:
+ // Avoid calling the destructor on an uninitialized value
new (&exn) auto(std::make_unique<ExceptionPackage>(*other.exn));
break;
case Type::none:
@@ -63,6 +61,13 @@ Literal& Literal::operator=(const Literal& other) {
case Type::unreachable:
WASM_UNREACHABLE("unexpected type");
}
+}
+
+Literal& Literal::operator=(const Literal& other) {
+ if (this != &other) {
+ this->~Literal();
+ new (this) auto(other);
+ }
return *this;
}
@@ -124,6 +129,11 @@ std::array<uint8_t, 16> Literal::getv128() const {
return ret;
}
+ExceptionPackage Literal::getExceptionPackage() const {
+ assert(type == Type::exnref);
+ return *exn.get();
+}
+
Literal Literal::castToF32() {
assert(type == Type::i32);
Literal ret(i32);