Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/wasm/module-decoder.h" | 5 #include "src/wasm/module-decoder.h" |
| 6 | 6 |
| 7 #include "src/base/functional.h" | 7 #include "src/base/functional.h" |
| 8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
| 9 #include "src/flags.h" | 9 #include "src/flags.h" |
| 10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 602 0 // source_size | 602 0 // source_size |
| 603 }); | 603 }); |
| 604 WasmDataSegment* segment = &module->data_segments.back(); | 604 WasmDataSegment* segment = &module->data_segments.back(); |
| 605 DecodeDataSegmentInModule(module, segment); | 605 DecodeDataSegmentInModule(module, segment); |
| 606 } | 606 } |
| 607 section_iter.advance(); | 607 section_iter.advance(); |
| 608 } | 608 } |
| 609 | 609 |
| 610 // ===== Name section ==================================================== | 610 // ===== Name section ==================================================== |
| 611 if (section_iter.section_code() == kNameSectionCode) { | 611 if (section_iter.section_code() == kNameSectionCode) { |
| 612 uint32_t functions_count = consume_u32v("functions count"); | 612 // Use an inner decoder so that errors don't fail the outer decoder. |
| 613 Decoder inner(start_, pc_, end_); | |
|
ahaas
2017/01/24 12:40:14
Can we tell a developer in some way that the names
titzer
2017/01/24 12:42:56
Added a TODO.
| |
| 614 uint32_t functions_count = inner.consume_u32v("functions count"); | |
| 613 | 615 |
| 614 for (uint32_t i = 0; ok() && i < functions_count; ++i) { | 616 for (uint32_t i = 0; inner.ok() && i < functions_count; ++i) { |
| 615 uint32_t function_name_length = 0; | 617 uint32_t function_name_length = 0; |
| 616 uint32_t name_offset = consume_string(&function_name_length, false); | 618 uint32_t name_offset = |
| 619 consume_string(inner, &function_name_length, false); | |
| 617 uint32_t func_index = i; | 620 uint32_t func_index = i; |
| 618 if (func_index < module->functions.size()) { | 621 if (func_index < module->functions.size()) { |
| 619 module->functions[func_index].name_offset = name_offset; | 622 module->functions[func_index].name_offset = name_offset; |
| 620 module->functions[func_index].name_length = function_name_length; | 623 module->functions[func_index].name_length = function_name_length; |
| 621 } | 624 } |
| 622 | 625 |
| 623 uint32_t local_names_count = consume_u32v("local names count"); | 626 uint32_t local_names_count = inner.consume_u32v("local names count"); |
| 624 for (uint32_t j = 0; ok() && j < local_names_count; j++) { | 627 for (uint32_t j = 0; ok() && j < local_names_count; j++) { |
| 625 skip_string(); | 628 uint32_t length = inner.consume_u32v("string length"); |
| 629 inner.consume_bytes(length, "string"); | |
| 626 } | 630 } |
| 627 } | 631 } |
| 632 // Skip the whole names section in the outer decoder. | |
| 633 consume_bytes(section_iter.payload_length(), nullptr); | |
| 628 section_iter.advance(); | 634 section_iter.advance(); |
| 629 } | 635 } |
| 630 | 636 |
| 631 // ===== Remaining sections ============================================== | 637 // ===== Remaining sections ============================================== |
| 632 if (section_iter.more() && ok()) { | 638 if (section_iter.more() && ok()) { |
| 633 error(pc(), pc(), "unexpected section: %s", | 639 error(pc(), pc(), "unexpected section: %s", |
| 634 SectionName(section_iter.section_code())); | 640 SectionName(section_iter.section_code())); |
| 635 } | 641 } |
| 636 | 642 |
| 637 if (ok()) { | 643 if (ok()) { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 char* buffer = new char[len]; | 809 char* buffer = new char[len]; |
| 804 strncpy(buffer, raw, len); | 810 strncpy(buffer, raw, len); |
| 805 buffer[len - 1] = 0; | 811 buffer[len - 1] = 0; |
| 806 | 812 |
| 807 // Copy error code and location. | 813 // Copy error code and location. |
| 808 result_.MoveFrom(result); | 814 result_.MoveFrom(result); |
| 809 result_.error_msg.reset(buffer); | 815 result_.error_msg.reset(buffer); |
| 810 } | 816 } |
| 811 } | 817 } |
| 812 | 818 |
| 819 uint32_t consume_string(uint32_t* length, bool validate_utf8) { | |
| 820 return consume_string(*this, length, validate_utf8); | |
| 821 } | |
| 822 | |
| 813 // Reads a length-prefixed string, checking that it is within bounds. Returns | 823 // Reads a length-prefixed string, checking that it is within bounds. Returns |
| 814 // the offset of the string, and the length as an out parameter. | 824 // the offset of the string, and the length as an out parameter. |
| 815 uint32_t consume_string(uint32_t* length, bool validate_utf8) { | 825 uint32_t consume_string(Decoder& decoder, uint32_t* length, |
| 816 *length = consume_u32v("string length"); | 826 bool validate_utf8) { |
| 817 uint32_t offset = pc_offset(); | 827 *length = decoder.consume_u32v("string length"); |
| 818 const byte* string_start = pc_; | 828 uint32_t offset = decoder.pc_offset(); |
| 829 const byte* string_start = decoder.pc(); | |
| 819 // Consume bytes before validation to guarantee that the string is not oob. | 830 // Consume bytes before validation to guarantee that the string is not oob. |
| 820 if (*length > 0) consume_bytes(*length, "string"); | 831 if (*length > 0) decoder.consume_bytes(*length, "string"); |
| 821 if (ok() && validate_utf8 && | 832 if (decoder.ok() && validate_utf8 && |
| 822 !unibrow::Utf8::Validate(string_start, *length)) { | 833 !unibrow::Utf8::Validate(string_start, *length)) { |
| 823 error(string_start, "no valid UTF-8 string"); | 834 decoder.error(string_start, "no valid UTF-8 string"); |
| 824 } | 835 } |
| 825 return offset; | 836 return offset; |
| 826 } | 837 } |
| 827 | 838 |
| 828 // Skips over a length-prefixed string, but checks that it is within bounds. | |
| 829 void skip_string() { | |
| 830 uint32_t length = consume_u32v("string length"); | |
| 831 consume_bytes(length, "string"); | |
| 832 } | |
| 833 | |
| 834 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { | 839 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { |
| 835 const byte* pos = pc_; | 840 const byte* pos = pc_; |
| 836 uint32_t sig_index = consume_u32v("signature index"); | 841 uint32_t sig_index = consume_u32v("signature index"); |
| 837 if (sig_index >= module->signatures.size()) { | 842 if (sig_index >= module->signatures.size()) { |
| 838 error(pos, pos, "signature index %u out of bounds (%d signatures)", | 843 error(pos, pos, "signature index %u out of bounds (%d signatures)", |
| 839 sig_index, static_cast<int>(module->signatures.size())); | 844 sig_index, static_cast<int>(module->signatures.size())); |
| 840 *sig = nullptr; | 845 *sig = nullptr; |
| 841 return 0; | 846 return 0; |
| 842 } | 847 } |
| 843 *sig = module->signatures[sig_index]; | 848 *sig = module->signatures[sig_index]; |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1257 table.push_back(std::move(func_asm_offsets)); | 1262 table.push_back(std::move(func_asm_offsets)); |
| 1258 } | 1263 } |
| 1259 if (decoder.more()) decoder.error("unexpected additional bytes"); | 1264 if (decoder.more()) decoder.error("unexpected additional bytes"); |
| 1260 | 1265 |
| 1261 return decoder.toResult(std::move(table)); | 1266 return decoder.toResult(std::move(table)); |
| 1262 } | 1267 } |
| 1263 | 1268 |
| 1264 } // namespace wasm | 1269 } // namespace wasm |
| 1265 } // namespace internal | 1270 } // namespace internal |
| 1266 } // namespace v8 | 1271 } // namespace v8 |
| OLD | NEW |