| Index: src/wasm/module-decoder.cc
|
| diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc
|
| index 0a36640308e9e4d488c7fee11e546339ccbb6fb3..b3e0928d1c8082327cb042d37a0993c5fe1f4a6c 100644
|
| --- a/src/wasm/module-decoder.cc
|
| +++ b/src/wasm/module-decoder.cc
|
| @@ -248,8 +248,8 @@ class ModuleDecoder : public Decoder {
|
|
|
| // ===== Type section ====================================================
|
| if (section_iter.section_code() == kTypeSectionCode) {
|
| - uint32_t signatures_count = consume_u32v("signatures count");
|
| - module->signatures.reserve(SafeReserve(signatures_count));
|
| + uint32_t signatures_count = consume_count("types count", kV8MaxWasmTypes);
|
| + module->signatures.reserve(signatures_count);
|
| for (uint32_t i = 0; ok() && i < signatures_count; ++i) {
|
| TRACE("DecodeSignature[%d] module+%d\n", i,
|
| static_cast<int>(pc_ - start_));
|
| @@ -261,8 +261,9 @@ class ModuleDecoder : public Decoder {
|
|
|
| // ===== Import section ==================================================
|
| if (section_iter.section_code() == kImportSectionCode) {
|
| - uint32_t import_table_count = consume_u32v("import table count");
|
| - module->import_table.reserve(SafeReserve(import_table_count));
|
| + uint32_t import_table_count =
|
| + consume_count("imports count", kV8MaxWasmImports);
|
| + module->import_table.reserve(import_table_count);
|
| for (uint32_t i = 0; ok() && i < import_table_count; ++i) {
|
| TRACE("DecodeImportTable[%d] module+%d\n", i,
|
| static_cast<int>(pc_ - start_));
|
| @@ -352,8 +353,9 @@ class ModuleDecoder : public Decoder {
|
|
|
| // ===== Function section ================================================
|
| if (section_iter.section_code() == kFunctionSectionCode) {
|
| - uint32_t functions_count = consume_u32v("functions count");
|
| - module->functions.reserve(SafeReserve(functions_count));
|
| + uint32_t functions_count =
|
| + consume_count("functions count", kV8MaxWasmFunctions);
|
| + module->functions.reserve(functions_count);
|
| module->num_declared_functions = functions_count;
|
| for (uint32_t i = 0; ok() && i < functions_count; ++i) {
|
| uint32_t func_index = static_cast<uint32_t>(module->functions.size());
|
| @@ -374,12 +376,7 @@ class ModuleDecoder : public Decoder {
|
|
|
| // ===== Table section ===================================================
|
| if (section_iter.section_code() == kTableSectionCode) {
|
| - const byte* pos = pc_;
|
| - uint32_t table_count = consume_u32v("table count");
|
| - // Require at most one table for now.
|
| - if (table_count > 1) {
|
| - error(pos, pos, "invalid table count %d, maximum 1", table_count);
|
| - }
|
| + uint32_t table_count = consume_count("table count", kV8MaxWasmTables);
|
| if (module->function_tables.size() < 1) {
|
| module->function_tables.push_back({0, 0, false, std::vector<int32_t>(),
|
| false, false, SignatureMap()});
|
| @@ -397,12 +394,7 @@ class ModuleDecoder : public Decoder {
|
|
|
| // ===== Memory section ==================================================
|
| if (section_iter.section_code() == kMemorySectionCode) {
|
| - const byte* pos = pc_;
|
| - uint32_t memory_count = consume_u32v("memory count");
|
| - // Require at most one memory for now.
|
| - if (memory_count > 1) {
|
| - error(pos, pos, "invalid memory count %d, maximum 1", memory_count);
|
| - }
|
| + uint32_t memory_count = consume_count("memory count", kV8MaxWasmMemories);
|
|
|
| for (uint32_t i = 0; ok() && i < memory_count; i++) {
|
| bool has_max = false;
|
| @@ -416,14 +408,10 @@ class ModuleDecoder : public Decoder {
|
|
|
| // ===== Global section ==================================================
|
| if (section_iter.section_code() == kGlobalSectionCode) {
|
| - uint32_t globals_count = consume_u32v("globals count");
|
| + uint32_t globals_count =
|
| + consume_count("globals count", kV8MaxWasmGlobals);
|
| uint32_t imported_globals = static_cast<uint32_t>(module->globals.size());
|
| - if (!IsWithinLimit(std::numeric_limits<int32_t>::max(), globals_count,
|
| - imported_globals)) {
|
| - error(pos, pos, "too many imported+defined globals: %u + %u",
|
| - imported_globals, globals_count);
|
| - }
|
| - module->globals.reserve(SafeReserve(imported_globals + globals_count));
|
| + module->globals.reserve(imported_globals + globals_count);
|
| for (uint32_t i = 0; ok() && i < globals_count; ++i) {
|
| TRACE("DecodeGlobal[%d] module+%d\n", i,
|
| static_cast<int>(pc_ - start_));
|
| @@ -438,8 +426,9 @@ class ModuleDecoder : public Decoder {
|
|
|
| // ===== Export section ==================================================
|
| if (section_iter.section_code() == kExportSectionCode) {
|
| - uint32_t export_table_count = consume_u32v("export table count");
|
| - module->export_table.reserve(SafeReserve(export_table_count));
|
| + uint32_t export_table_count =
|
| + consume_count("exports count", kV8MaxWasmImports);
|
| + module->export_table.reserve(export_table_count);
|
| for (uint32_t i = 0; ok() && i < export_table_count; ++i) {
|
| TRACE("DecodeExportTable[%d] module+%d\n", i,
|
| static_cast<int>(pc_ - start_));
|
| @@ -536,7 +525,8 @@ class ModuleDecoder : public Decoder {
|
|
|
| // ===== Elements section ================================================
|
| if (section_iter.section_code() == kElementSectionCode) {
|
| - uint32_t element_count = consume_u32v("element count");
|
| + uint32_t element_count =
|
| + consume_count("element count", kV8MaxWasmTableSize);
|
| for (uint32_t i = 0; ok() && i < element_count; ++i) {
|
| const byte* pos = pc();
|
| uint32_t table_index = consume_u32v("table index");
|
| @@ -554,7 +544,6 @@ class ModuleDecoder : public Decoder {
|
| std::vector<uint32_t> vector;
|
| module->table_inits.push_back({table_index, offset, vector});
|
| WasmTableInit* init = &module->table_inits.back();
|
| - init->entries.reserve(SafeReserve(num_elem));
|
| for (uint32_t j = 0; ok() && j < num_elem; j++) {
|
| WasmFunction* func = nullptr;
|
| uint32_t index = consume_func_index(module, &func);
|
| @@ -597,8 +586,9 @@ class ModuleDecoder : public Decoder {
|
|
|
| // ===== Data section ====================================================
|
| if (section_iter.section_code() == kDataSectionCode) {
|
| - uint32_t data_segments_count = consume_u32v("data segments count");
|
| - module->data_segments.reserve(SafeReserve(data_segments_count));
|
| + uint32_t data_segments_count =
|
| + consume_count("data segments count", kV8MaxWasmDataSegments);
|
| + module->data_segments.reserve(data_segments_count);
|
| for (uint32_t i = 0; ok() && i < data_segments_count; ++i) {
|
| if (!module->has_memory) {
|
| error("cannot load data without memory");
|
| @@ -656,12 +646,6 @@ class ModuleDecoder : public Decoder {
|
| return result;
|
| }
|
|
|
| - uint32_t SafeReserve(uint32_t count) {
|
| - // Avoid OOM by only reserving up to a certain size.
|
| - const uint32_t kMaxReserve = 20000;
|
| - return count < kMaxReserve ? count : kMaxReserve;
|
| - }
|
| -
|
| // Decodes a single anonymous function starting at {start_}.
|
| FunctionResult DecodeSingleFunction(ModuleBytesEnv* module_env,
|
| WasmFunction* function) {
|
| @@ -838,6 +822,17 @@ class ModuleDecoder : public Decoder {
|
| return sig_index;
|
| }
|
|
|
| + uint32_t consume_count(const char* name, size_t maximum) {
|
| + const byte* p = pc_;
|
| + uint32_t count = consume_u32v(name);
|
| + if (count > maximum) {
|
| + error(p, p, "%s of %u exceeds internal limit of %zu", name, count,
|
| + maximum);
|
| + return static_cast<uint32_t>(maximum);
|
| + }
|
| + return count;
|
| + }
|
| +
|
| uint32_t consume_func_index(WasmModule* module, WasmFunction** func) {
|
| return consume_index("function index", module->functions, func);
|
| }
|
| @@ -1012,7 +1007,9 @@ class ModuleDecoder : public Decoder {
|
| FunctionSig* consume_sig() {
|
| if (!expect_u8("type form", kWasmFunctionTypeForm)) return nullptr;
|
| // parse parameter types
|
| - uint32_t param_count = consume_u32v("param count");
|
| + uint32_t param_count =
|
| + consume_count("param count", kV8MaxWasmFunctionParams);
|
| + if (failed()) return nullptr;
|
| std::vector<LocalType> params;
|
| for (uint32_t i = 0; ok() && i < param_count; ++i) {
|
| LocalType param = consume_value_type();
|
| @@ -1020,23 +1017,18 @@ class ModuleDecoder : public Decoder {
|
| }
|
|
|
| // parse return types
|
| - const byte* pt = pc_;
|
| - uint32_t return_count = consume_u32v("return count");
|
| - if (return_count > kMaxReturnCount) {
|
| - error(pt, pt, "return count of %u exceeds maximum of %u", return_count,
|
| - kMaxReturnCount);
|
| - return nullptr;
|
| - }
|
| + const size_t max_return_count = FLAG_wasm_mv_prototype
|
| + ? kV8MaxWasmFunctionMultiReturns
|
| + : kV8MaxWasmFunctionReturns;
|
| + uint32_t return_count = consume_count("return count", max_return_count);
|
| + if (failed()) return nullptr;
|
| std::vector<LocalType> returns;
|
| for (uint32_t i = 0; ok() && i < return_count; ++i) {
|
| LocalType ret = consume_value_type();
|
| returns.push_back(ret);
|
| }
|
|
|
| - if (failed()) {
|
| - // Decoding failed, return void -> void
|
| - return new (module_zone) FunctionSig(0, 0, nullptr);
|
| - }
|
| + if (failed()) return nullptr;
|
|
|
| // FunctionSig stores the return types first.
|
| LocalType* buffer =
|
|
|