Chromium Code Reviews| Index: src/wasm/module-decoder.cc |
| diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc |
| index 0a36640308e9e4d488c7fee11e546339ccbb6fb3..d34b5cc23f15022ca20a0bc2a41989fce9f09b59 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", 1); |
| 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", 1); |
| 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)); |
|
Clemens Hammacher
2016/12/14 12:50:26
We could still reserve here if num_elem is "plausi
titzer
2016/12/14 17:19:53
I just really wanted to get rid of safe reserve :-
|
| 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,13 @@ class ModuleDecoder : public Decoder { |
| FunctionSig* consume_sig() { |
| if (!expect_u8("type form", kWasmFunctionTypeForm)) return nullptr; |
| // parse parameter types |
| + const byte* pt = pc_; |
| uint32_t param_count = consume_u32v("param count"); |
| + if (param_count > kV8MaxWasmFunctionParamCount) { |
| + error(pt, pt, "param count of %u exceeds maximum of %lu", param_count, |
| + kV8MaxWasmFunctionParamCount); |
| + return nullptr; |
| + } |
|
Clemens Hammacher
2016/12/14 12:50:26
You can use consume_count() followed by "if (faile
titzer
2016/12/14 17:19:53
Done.
|
| std::vector<LocalType> params; |
| for (uint32_t i = 0; ok() && i < param_count; ++i) { |
| LocalType param = consume_value_type(); |
| @@ -1020,11 +1021,14 @@ class ModuleDecoder : public Decoder { |
| } |
| // parse return types |
| - const byte* pt = pc_; |
| + 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); |
| + const size_t max_return_count = FLAG_wasm_mv_prototype |
|
Clemens Hammacher
2016/12/14 12:50:26
Same here.
|
| + ? kV8MaxWasmFunctionMultiReturnCount |
| + : kV8MaxWasmFunctionReturnCount; |
| + if (return_count > max_return_count) { |
| + error(pt, pt, "return count of %u exceeds maximum of %lu", return_count, |
| + max_return_count); |
| return nullptr; |
| } |
| std::vector<LocalType> returns; |