summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2018-03-16 09:40:11 -0700
committerGitHub <noreply@github.com>2018-03-16 09:40:11 -0700
commitd37e6942a011ac72cf59934ca26c1993e37a23fd (patch)
treec264ab85314cdfb85179d4bb676c9edd07af29e0 /src
parent8fd854d6f60c6c711c3c04e1d30c74a6b2f1821b (diff)
downloadbinaryen-d37e6942a011ac72cf59934ca26c1993e37a23fd.tar.gz
binaryen-d37e6942a011ac72cf59934ca26c1993e37a23fd.tar.bz2
binaryen-d37e6942a011ac72cf59934ca26c1993e37a23fd.zip
validate we are in a function context when adding a label in binary parsing. found by valgrind (#1478)
Diffstat (limited to 'src')
-rw-r--r--src/wasm-binary.h7
-rw-r--r--src/wasm/wasm-binary.cpp31
2 files changed, 20 insertions, 18 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index cc98ebf8b..e03fd29ea 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -862,9 +862,7 @@ public:
void readFunctionSignatures();
size_t nextLabel;
- Name getNextLabel() {
- return cashew::IString(("label$" + std::to_string(nextLabel++)).c_str(), false);
- }
+ Name getNextLabel();
// We read functions before we know their names, so we need to backpatch the names later
std::vector<Function*> functions; // we store functions here before wasm.addFunction after we know their names
@@ -874,6 +872,9 @@ public:
Function* currFunction = nullptr;
Index endOfFunction = -1; // before we see a function (like global init expressions), there is no end of function to check
+ // Throws a parsing error if we are not in a function context
+ void requireFunctionContext(const char* error);
+
void readFunctions();
std::map<Export*, Index> exportIndexes;
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 69e939c44..7a459eb7f 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1682,6 +1682,17 @@ void WasmBinaryBuilder::readImports() {
}
}
+Name WasmBinaryBuilder::getNextLabel() {
+ requireFunctionContext("getting a label");
+ return Name("label$" + std::to_string(nextLabel++));
+}
+
+void WasmBinaryBuilder::requireFunctionContext(const char* error) {
+ if (!currFunction) {
+ throw ParseException(std::string("in a non-function context: ") + error);
+ }
+}
+
void WasmBinaryBuilder::readFunctionSignatures() {
if (debug) std::cerr << "== readFunctionSignatures" << std::endl;
size_t num = getU32LEB();
@@ -2041,9 +2052,7 @@ Expression* WasmBinaryBuilder::popNonVoidExpression() {
expressions.pop_back();
}
auto type = block->list[0]->type;
- if (!currFunction) {
- throw ParseException("popping void outside of function, where we need a new local");
- }
+ requireFunctionContext("popping void where we need a new local");
auto local = builder.addVar(currFunction, type);
block->list[0] = builder.makeSetLocal(local, block->list[0]);
block->list.push_back(builder.makeGetLocal(local, type));
@@ -2321,9 +2330,7 @@ void WasmBinaryBuilder::pushBlockElements(Block* curr, size_t start, size_t end)
expressionStack.resize(start);
// if we have a consumable item and need it, use it
if (consumable != NONE && curr->list.back()->type == none) {
- if (!currFunction) {
- throw ParseException("need an extra var in a non-function context, invalid wasm");
- }
+ requireFunctionContext("need an extra var in a non-function context, invalid wasm");
Builder builder(wasm);
auto* item = curr->list[consumable]->cast<Drop>()->value;
auto temp = builder.addVar(currFunction, item->type);
@@ -2534,9 +2541,7 @@ void WasmBinaryBuilder::visitCallIndirect(CallIndirect *curr) {
void WasmBinaryBuilder::visitGetLocal(GetLocal *curr) {
if (debug) std::cerr << "zz node: GetLocal " << pos << std::endl;
- if (!currFunction) {
- throw ParseException("get_local outside of function");
- }
+ requireFunctionContext("get_local");
curr->index = getU32LEB();
if (curr->index >= currFunction->getNumLocals()) {
throw ParseException("bad get_local index");
@@ -2547,9 +2552,7 @@ void WasmBinaryBuilder::visitGetLocal(GetLocal *curr) {
void WasmBinaryBuilder::visitSetLocal(SetLocal *curr, uint8_t code) {
if (debug) std::cerr << "zz node: Set|TeeLocal" << std::endl;
- if (!currFunction) {
- throw ParseException("set_local outside of function");
- }
+ requireFunctionContext("set_local outside of function");
curr->index = getU32LEB();
if (curr->index >= currFunction->getNumLocals()) {
throw ParseException("bad set_local index");
@@ -2946,9 +2949,7 @@ void WasmBinaryBuilder::visitSelect(Select *curr) {
void WasmBinaryBuilder::visitReturn(Return *curr) {
if (debug) std::cerr << "zz node: Return" << std::endl;
- if (!currFunction) {
- throw ParseException("return outside of function");
- }
+ requireFunctionContext("return");
if (currFunction->result != none) {
curr->value = popNonVoidExpression();
}