Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/wasm/module-decoder.cc

Issue 2657463003: [wasm] Errors in names section do not fail the whole module. (Closed)
Patch Set: Fix string offsets Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/wasm/decoder.h ('k') | test/mjsunit/wasm/names.js » ('j') | test/mjsunit/wasm/names.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698