| Index: src/wasm/module-decoder.cc
|
| diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc
|
| index d3feb4c3571b62f673ad90ccefc26ea80b907680..c7d61896d6be35a2564c74e5adc303bda42f591e 100644
|
| --- a/src/wasm/module-decoder.cc
|
| +++ b/src/wasm/module-decoder.cc
|
| @@ -609,22 +609,29 @@ class ModuleDecoder : public Decoder {
|
|
|
| // ===== Name section ====================================================
|
| if (section_iter.section_code() == kNameSectionCode) {
|
| - uint32_t functions_count = consume_u32v("functions count");
|
| + // TODO(titzer): find a way to report name errors as warnings.
|
| + // Use an inner decoder so that errors don't fail the outer decoder.
|
| + Decoder inner(start_, pc_, end_);
|
| + uint32_t functions_count = inner.consume_u32v("functions count");
|
|
|
| - for (uint32_t i = 0; ok() && i < functions_count; ++i) {
|
| + for (uint32_t i = 0; inner.ok() && i < functions_count; ++i) {
|
| uint32_t function_name_length = 0;
|
| - uint32_t name_offset = consume_string(&function_name_length, false);
|
| + uint32_t name_offset =
|
| + consume_string(inner, &function_name_length, false);
|
| uint32_t func_index = i;
|
| if (func_index < module->functions.size()) {
|
| module->functions[func_index].name_offset = name_offset;
|
| module->functions[func_index].name_length = function_name_length;
|
| }
|
|
|
| - uint32_t local_names_count = consume_u32v("local names count");
|
| + uint32_t local_names_count = inner.consume_u32v("local names count");
|
| for (uint32_t j = 0; ok() && j < local_names_count; j++) {
|
| - skip_string();
|
| + uint32_t length = inner.consume_u32v("string length");
|
| + inner.consume_bytes(length, "string");
|
| }
|
| }
|
| + // Skip the whole names section in the outer decoder.
|
| + consume_bytes(section_iter.payload_length(), nullptr);
|
| section_iter.advance();
|
| }
|
|
|
| @@ -810,27 +817,26 @@ class ModuleDecoder : public Decoder {
|
| }
|
| }
|
|
|
| + uint32_t consume_string(uint32_t* length, bool validate_utf8) {
|
| + return consume_string(*this, length, validate_utf8);
|
| + }
|
| +
|
| // Reads a length-prefixed string, checking that it is within bounds. Returns
|
| // the offset of the string, and the length as an out parameter.
|
| - uint32_t consume_string(uint32_t* length, bool validate_utf8) {
|
| - *length = consume_u32v("string length");
|
| - uint32_t offset = pc_offset();
|
| - const byte* string_start = pc_;
|
| + uint32_t consume_string(Decoder& decoder, uint32_t* length,
|
| + bool validate_utf8) {
|
| + *length = decoder.consume_u32v("string length");
|
| + uint32_t offset = decoder.pc_offset();
|
| + const byte* string_start = decoder.pc();
|
| // Consume bytes before validation to guarantee that the string is not oob.
|
| - if (*length > 0) consume_bytes(*length, "string");
|
| - if (ok() && validate_utf8 &&
|
| + if (*length > 0) decoder.consume_bytes(*length, "string");
|
| + if (decoder.ok() && validate_utf8 &&
|
| !unibrow::Utf8::Validate(string_start, *length)) {
|
| - error(string_start, "no valid UTF-8 string");
|
| + decoder.error(string_start, "no valid UTF-8 string");
|
| }
|
| return offset;
|
| }
|
|
|
| - // Skips over a length-prefixed string, but checks that it is within bounds.
|
| - void skip_string() {
|
| - uint32_t length = consume_u32v("string length");
|
| - consume_bytes(length, "string");
|
| - }
|
| -
|
| uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) {
|
| const byte* pos = pc_;
|
| uint32_t sig_index = consume_u32v("signature index");
|
|
|