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

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

Issue 1967023004: [wasm] Add UTF-8 validation (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase on parallel compilation Created 4 years, 7 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
« no previous file with comments | « src/unicode-inl.h ('k') | src/wasm/wasm-function-name-table.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/macro-assembler.h" 9 #include "src/macro-assembler.h"
10 #include "src/objects.h" 10 #include "src/objects.h"
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 if (functions_count != module->functions.size()) { 260 if (functions_count != module->functions.size()) {
261 error(pos, pos, "function name count %u mismatch (%u expected)", 261 error(pos, pos, "function name count %u mismatch (%u expected)",
262 functions_count, 262 functions_count,
263 static_cast<uint32_t>(module->functions.size())); 263 static_cast<uint32_t>(module->functions.size()));
264 break; 264 break;
265 } 265 }
266 266
267 for (uint32_t i = 0; i < functions_count; i++) { 267 for (uint32_t i = 0; i < functions_count; i++) {
268 WasmFunction* function = &module->functions[i]; 268 WasmFunction* function = &module->functions[i];
269 function->name_offset = 269 function->name_offset =
270 consume_string(&function->name_length, "function name"); 270 consume_string(&function->name_length, false);
271 271
272 uint32_t local_names_count = 272 uint32_t local_names_count =
273 consume_u32v(&length, "local names count"); 273 consume_u32v(&length, "local names count");
274 for (uint32_t j = 0; j < local_names_count; j++) { 274 for (uint32_t j = 0; j < local_names_count; j++) {
275 uint32_t unused = 0; 275 uint32_t unused = 0;
276 uint32_t offset = consume_string(&unused, "local name"); 276 uint32_t offset = consume_string(&unused, false);
277 USE(unused); 277 USE(unused);
278 USE(offset); 278 USE(offset);
279 } 279 }
280 } 280 }
281 break; 281 break;
282 } 282 }
283 case WasmSection::Code::Globals: { 283 case WasmSection::Code::Globals: {
284 int length; 284 int length;
285 uint32_t globals_count = consume_u32v(&length, "globals count"); 285 uint32_t globals_count = consume_u32v(&length, "globals count");
286 module->globals.reserve(SafeReserve(globals_count)); 286 module->globals.reserve(SafeReserve(globals_count));
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 module->import_table.push_back({nullptr, // sig 365 module->import_table.push_back({nullptr, // sig
366 0, // sig_index 366 0, // sig_index
367 0, // module_name_offset 367 0, // module_name_offset
368 0, // module_name_length 368 0, // module_name_length
369 0, // function_name_offset 369 0, // function_name_offset
370 0}); // function_name_length 370 0}); // function_name_length
371 WasmImport* import = &module->import_table.back(); 371 WasmImport* import = &module->import_table.back();
372 372
373 import->sig_index = consume_sig_index(module, &import->sig); 373 import->sig_index = consume_sig_index(module, &import->sig);
374 const byte* pos = pc_; 374 const byte* pos = pc_;
375 import->module_name_offset = consume_string( 375 import->module_name_offset =
376 &import->module_name_length, "import module name"); 376 consume_string(&import->module_name_length, true);
377 if (import->module_name_length == 0) { 377 if (import->module_name_length == 0) {
378 error(pos, "import module name cannot be NULL"); 378 error(pos, "import module name cannot be NULL");
379 } 379 }
380 import->function_name_offset = consume_string( 380 import->function_name_offset =
381 &import->function_name_length, "import function name"); 381 consume_string(&import->function_name_length, true);
382 } 382 }
383 break; 383 break;
384 } 384 }
385 case WasmSection::Code::ExportTable: { 385 case WasmSection::Code::ExportTable: {
386 // Declares an export table. 386 // Declares an export table.
387 CheckForFunctions(module, section); 387 CheckForFunctions(module, section);
388 int length; 388 int length;
389 uint32_t export_table_count = 389 uint32_t export_table_count =
390 consume_u32v(&length, "export table count"); 390 consume_u32v(&length, "export table count");
391 module->export_table.reserve(SafeReserve(export_table_count)); 391 module->export_table.reserve(SafeReserve(export_table_count));
392 // Decode export table. 392 // Decode export table.
393 for (uint32_t i = 0; i < export_table_count; i++) { 393 for (uint32_t i = 0; i < export_table_count; i++) {
394 if (failed()) break; 394 if (failed()) break;
395 TRACE("DecodeExportTable[%d] module+%d\n", i, 395 TRACE("DecodeExportTable[%d] module+%d\n", i,
396 static_cast<int>(pc_ - start_)); 396 static_cast<int>(pc_ - start_));
397 397
398 module->export_table.push_back({0, // func_index 398 module->export_table.push_back({0, // func_index
399 0, // name_offset 399 0, // name_offset
400 0}); // name_length 400 0}); // name_length
401 WasmExport* exp = &module->export_table.back(); 401 WasmExport* exp = &module->export_table.back();
402 402
403 WasmFunction* func; 403 WasmFunction* func;
404 exp->func_index = consume_func_index(module, &func); 404 exp->func_index = consume_func_index(module, &func);
405 exp->name_offset = consume_string(&exp->name_length, "export name"); 405 exp->name_offset = consume_string(&exp->name_length, true);
406 } 406 }
407 break; 407 break;
408 } 408 }
409 case WasmSection::Code::Max: 409 case WasmSection::Code::Max:
410 // Skip unknown sections. 410 // Skip unknown sections.
411 TRACE("Unknown section: '"); 411 TRACE("Unknown section: '");
412 for (uint32_t i = 0; i != string_length; ++i) { 412 for (uint32_t i = 0; i != string_length; ++i) {
413 TRACE("%c", *(section_name_start + i)); 413 TRACE("%c", *(section_name_start + i));
414 } 414 }
415 TRACE("'\n"); 415 TRACE("'\n");
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 493
494 private: 494 private:
495 Zone* module_zone; 495 Zone* module_zone;
496 ModuleResult result_; 496 ModuleResult result_;
497 ModuleOrigin origin_; 497 ModuleOrigin origin_;
498 498
499 uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); } 499 uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); }
500 500
501 // Decodes a single global entry inside a module starting at {pc_}. 501 // Decodes a single global entry inside a module starting at {pc_}.
502 void DecodeGlobalInModule(WasmGlobal* global) { 502 void DecodeGlobalInModule(WasmGlobal* global) {
503 global->name_offset = consume_string(&global->name_length, "global name"); 503 global->name_offset = consume_string(&global->name_length, false);
504 DCHECK(unibrow::Utf8::Validate(start_ + global->name_offset,
505 global->name_length));
504 global->type = mem_type(); 506 global->type = mem_type();
505 global->offset = 0; 507 global->offset = 0;
506 global->exported = consume_u8("exported") != 0; 508 global->exported = consume_u8("exported") != 0;
507 } 509 }
508 510
509 // Decodes a single function entry inside a module starting at {pc_}. 511 // Decodes a single function entry inside a module starting at {pc_}.
510 // TODO(titzer): legacy function body; remove 512 // TODO(titzer): legacy function body; remove
511 void DecodeFunctionInModule(WasmModule* module, WasmFunction* function, 513 void DecodeFunctionInModule(WasmModule* module, WasmFunction* function,
512 bool verify_body = true) { 514 bool verify_body = true) {
513 byte decl_bits = consume_u8("function decl"); 515 byte decl_bits = consume_u8("function decl");
514 516
515 const byte* sigpos = pc_; 517 const byte* sigpos = pc_;
516 function->sig_index = consume_u16("signature index"); 518 function->sig_index = consume_u16("signature index");
517 519
518 if (function->sig_index >= module->signatures.size()) { 520 if (function->sig_index >= module->signatures.size()) {
519 return error(sigpos, "invalid signature index"); 521 return error(sigpos, "invalid signature index");
520 } else { 522 } else {
521 function->sig = module->signatures[function->sig_index]; 523 function->sig = module->signatures[function->sig_index];
522 } 524 }
523 525
524 TRACE(" +%d <function attributes:%s%s%s%s%s>\n", 526 TRACE(" +%d <function attributes:%s%s%s%s%s>\n",
525 static_cast<int>(pc_ - start_), 527 static_cast<int>(pc_ - start_),
526 decl_bits & kDeclFunctionName ? " name" : "", 528 decl_bits & kDeclFunctionName ? " name" : "",
527 decl_bits & kDeclFunctionImport ? " imported" : "", 529 decl_bits & kDeclFunctionImport ? " imported" : "",
528 decl_bits & kDeclFunctionLocals ? " locals" : "", 530 decl_bits & kDeclFunctionLocals ? " locals" : "",
529 decl_bits & kDeclFunctionExport ? " exported" : "", 531 decl_bits & kDeclFunctionExport ? " exported" : "",
530 (decl_bits & kDeclFunctionImport) == 0 ? " body" : ""); 532 (decl_bits & kDeclFunctionImport) == 0 ? " body" : "");
531 533
534 function->exported = decl_bits & kDeclFunctionExport;
535
532 if (decl_bits & kDeclFunctionName) { 536 if (decl_bits & kDeclFunctionName) {
533 function->name_offset = 537 function->name_offset =
534 consume_string(&function->name_length, "function name"); 538 consume_string(&function->name_length, function->exported);
535 } 539 }
536 540
537 function->exported = decl_bits & kDeclFunctionExport;
538
539 // Imported functions have no locals or body. 541 // Imported functions have no locals or body.
540 if (decl_bits & kDeclFunctionImport) { 542 if (decl_bits & kDeclFunctionImport) {
541 function->external = true; 543 function->external = true;
542 return; 544 return;
543 } 545 }
544 546
545 if (decl_bits & kDeclFunctionLocals) { 547 if (decl_bits & kDeclFunctionLocals) {
546 function->local_i32_count = consume_u16("i32 count"); 548 function->local_i32_count = consume_u16("i32 count");
547 function->local_i64_count = consume_u16("i64 count"); 549 function->local_i64_count = consume_u16("i64 count");
548 function->local_f32_count = consume_u16("f32 count"); 550 function->local_f32_count = consume_u16("f32 count");
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 uint32_t consume_offset(const char* name = nullptr) { 634 uint32_t consume_offset(const char* name = nullptr) {
633 uint32_t offset = consume_u32(name ? name : "offset"); 635 uint32_t offset = consume_u32(name ? name : "offset");
634 if (offset > static_cast<uint32_t>(limit_ - start_)) { 636 if (offset > static_cast<uint32_t>(limit_ - start_)) {
635 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); 637 error(pc_ - sizeof(uint32_t), "offset out of bounds of module");
636 } 638 }
637 return offset; 639 return offset;
638 } 640 }
639 641
640 // Reads a length-prefixed string, checking that it is within bounds. Returns 642 // Reads a length-prefixed string, checking that it is within bounds. Returns
641 // the offset of the string, and the length as an out parameter. 643 // the offset of the string, and the length as an out parameter.
642 uint32_t consume_string(uint32_t* length, const char* name = nullptr) { 644 uint32_t consume_string(uint32_t* length, bool validate_utf8) {
643 int varint_length; 645 int varint_length;
644 *length = consume_u32v(&varint_length, "string length"); 646 *length = consume_u32v(&varint_length, "string length");
645 uint32_t offset = pc_offset(); 647 uint32_t offset = pc_offset();
646 TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length); 648 TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length);
649 if (validate_utf8 && !unibrow::Utf8::Validate(pc_, *length)) {
650 error(pc_, "no valid UTF-8 string");
651 }
647 consume_bytes(*length); 652 consume_bytes(*length);
648 return offset; 653 return offset;
649 } 654 }
650 655
651 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { 656 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) {
652 const byte* pos = pc_; 657 const byte* pos = pc_;
653 int length; 658 int length;
654 uint32_t sig_index = consume_u32v(&length, "signature index"); 659 uint32_t sig_index = consume_u32v(&length, "signature index");
655 if (sig_index >= module->signatures.size()) { 660 if (sig_index >= module->signatures.size()) {
656 error(pos, pos, "signature index %u out of bounds (%d signatures)", 661 error(pos, pos, "signature index %u out of bounds (%d signatures)",
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 return FunctionError("size > maximum function size"); 843 return FunctionError("size > maximum function size");
839 isolate->counters()->wasm_function_size_bytes()->AddSample( 844 isolate->counters()->wasm_function_size_bytes()->AddSample(
840 static_cast<int>(size)); 845 static_cast<int>(size));
841 WasmFunction* function = new WasmFunction(); 846 WasmFunction* function = new WasmFunction();
842 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); 847 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin);
843 return decoder.DecodeSingleFunction(module_env, function); 848 return decoder.DecodeSingleFunction(module_env, function);
844 } 849 }
845 } // namespace wasm 850 } // namespace wasm
846 } // namespace internal 851 } // namespace internal
847 } // namespace v8 852 } // namespace v8
OLDNEW
« no previous file with comments | « src/unicode-inl.h ('k') | src/wasm/wasm-function-name-table.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698