diff options
author | Alon Zakai <alonzakai@gmail.com> | 2018-03-16 09:40:11 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-16 09:40:11 -0700 |
commit | d37e6942a011ac72cf59934ca26c1993e37a23fd (patch) | |
tree | c264ab85314cdfb85179d4bb676c9edd07af29e0 /src | |
parent | 8fd854d6f60c6c711c3c04e1d30c74a6b2f1821b (diff) | |
download | binaryen-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.h | 7 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 31 |
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(); } |