1 /* Copyright 2017 Mozilla Foundation 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 // See https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md 16 17 use std::boxed::Box; 18 use std::vec::Vec; 19 20 use crate::limits::{ 21 MAX_WASM_FUNCTIONS, MAX_WASM_FUNCTION_LOCALS, MAX_WASM_STRING_SIZE, MAX_WASM_TABLE_ENTRIES, 22 }; 23 24 use crate::primitives::{ 25 BinaryReaderError, CustomSectionKind, ExternalKind, FuncType, GlobalType, 26 ImportSectionEntryType, LinkingType, MemoryType, Naming, Operator, RelocType, Result, 27 SectionCode, TableType, Type, 28 }; 29 30 use crate::readers::{ 31 CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems, 32 ElementKind, ElementSectionReader, Export, ExportSectionReader, FunctionBody, 33 FunctionSectionReader, Global, GlobalSectionReader, Import, ImportSectionReader, 34 LinkingSectionReader, MemorySectionReader, ModuleReader, Name, NameSectionReader, NamingReader, 35 OperatorsReader, Reloc, RelocSectionReader, Section, SectionReader, TableSectionReader, 36 TypeSectionReader, 37 }; 38 39 use crate::binary_reader::{BinaryReader, Range}; 40 41 const MAX_DATA_CHUNK_SIZE: usize = MAX_WASM_STRING_SIZE; 42 43 #[derive(Debug)] 44 pub struct LocalName<'a> { 45 pub index: u32, 46 pub locals: Box<[Naming<'a>]>, 47 } 48 49 #[derive(Debug)] 50 pub enum NameEntry<'a> { 51 Module(&'a str), 52 Function(Box<[Naming<'a>]>), 53 Local(Box<[LocalName<'a>]>), 54 } 55 56 #[derive(Debug)] 57 pub struct RelocEntry { 58 pub ty: RelocType, 59 pub offset: u32, 60 pub index: u32, 61 pub addend: Option<u32>, 62 } 63 64 enum InitExpressionContinuationSection { 65 Global, 66 Element, 67 Data, 68 } 69 70 #[derive(Debug)] 71 pub enum ParserState<'a> { 72 Error(BinaryReaderError), 73 Initial, 74 BeginWasm { 75 version: u32, 76 }, 77 EndWasm, 78 BeginSection { 79 code: SectionCode<'a>, 80 range: Range, 81 }, 82 EndSection, 83 SkippingSection, 84 ReadingCustomSection(CustomSectionKind), 85 ReadingSectionRawData, 86 SectionRawData(&'a [u8]), 87 88 TypeSectionEntry(FuncType), 89 ImportSectionEntry { 90 module: &'a str, 91 field: &'a str, 92 ty: ImportSectionEntryType, 93 }, 94 FunctionSectionEntry(u32), 95 TableSectionEntry(TableType), 96 MemorySectionEntry(MemoryType), 97 ExportSectionEntry { 98 field: &'a str, 99 kind: ExternalKind, 100 index: u32, 101 }, 102 NameSectionEntry(NameEntry<'a>), 103 StartSectionEntry(u32), 104 DataCountSectionEntry(u32), 105 106 BeginInitExpressionBody, 107 InitExpressionOperator(Operator<'a>), 108 EndInitExpressionBody, 109 110 BeginFunctionBody { 111 range: Range, 112 }, 113 FunctionBodyLocals { 114 locals: Box<[(u32, Type)]>, 115 }, 116 CodeOperator(Operator<'a>), 117 EndFunctionBody, 118 SkippingFunctionBody, 119 120 BeginElementSectionEntry { 121 /// `None` means this is a passive or defined entry 122 table: ElemSectionEntryTable, 123 ty: Type, 124 }, 125 ElementSectionEntryBody(Box<[ElementItem]>), 126 EndElementSectionEntry, 127 128 BeginPassiveDataSectionEntry, 129 BeginActiveDataSectionEntry(u32), 130 EndDataSectionEntry, 131 BeginDataSectionEntryBody(u32), 132 DataSectionEntryBodyChunk(&'a [u8]), 133 EndDataSectionEntryBody, 134 135 BeginGlobalSectionEntry(GlobalType), 136 EndGlobalSectionEntry, 137 138 RelocSectionHeader(SectionCode<'a>), 139 RelocSectionEntry(RelocEntry), 140 LinkingSectionEntry(LinkingType), 141 142 SourceMappingURL(&'a str), 143 } 144 145 #[derive(Debug, Copy, Clone)] 146 pub enum ElemSectionEntryTable { 147 Passive, 148 Declared, 149 Active(u32), 150 } 151 152 #[derive(Debug, Copy, Clone)] 153 pub enum ParserInput { 154 Default, 155 SkipSection, 156 SkipFunctionBody, 157 ReadCustomSection, 158 ReadSectionRawData, 159 } 160 161 pub trait WasmDecoder<'a> { read(&mut self) -> &ParserState<'a>162 fn read(&mut self) -> &ParserState<'a>; push_input(&mut self, input: ParserInput)163 fn push_input(&mut self, input: ParserInput); read_with_input(&mut self, input: ParserInput) -> &ParserState<'a>164 fn read_with_input(&mut self, input: ParserInput) -> &ParserState<'a>; create_binary_reader<'b>(&mut self) -> BinaryReader<'b> where 'a: 'b165 fn create_binary_reader<'b>(&mut self) -> BinaryReader<'b> 166 where 167 'a: 'b; last_state(&self) -> &ParserState<'a>168 fn last_state(&self) -> &ParserState<'a>; 169 } 170 171 enum ParserSectionReader<'a> { 172 None, 173 CodeSectionReader(CodeSectionReader<'a>), 174 DataSectionReader(DataSectionReader<'a>), 175 ElementSectionReader(ElementSectionReader<'a>), 176 ExportSectionReader(ExportSectionReader<'a>), 177 FunctionSectionReader(FunctionSectionReader<'a>), 178 GlobalSectionReader(GlobalSectionReader<'a>), 179 ImportSectionReader(ImportSectionReader<'a>), 180 MemorySectionReader(MemorySectionReader<'a>), 181 TableSectionReader(TableSectionReader<'a>), 182 TypeSectionReader(TypeSectionReader<'a>), 183 NameSectionReader(NameSectionReader<'a>), 184 LinkingSectionReader(LinkingSectionReader<'a>), 185 RelocSectionReader(RelocSectionReader<'a>), 186 } 187 188 macro_rules! section_reader { 189 ($self:ident, $ty_and_name:ident) => { 190 if let ParserSectionReader::$ty_and_name(ref mut reader) = $self.section_reader { 191 reader 192 } else { 193 panic!("expected {} reader", stringify!($ty_and_name)); 194 } 195 }; 196 } 197 198 macro_rules! start_section_reader { 199 ($self:ident, $ty_and_name:ident, $factory:ident) => {{ 200 let reader = $self 201 .current_section 202 .as_ref() 203 .expect("section") 204 .$factory()?; 205 $self.section_entries_left = reader.get_count(); 206 $self.section_reader = ParserSectionReader::$ty_and_name(reader); 207 }}; 208 } 209 210 /// The `Parser` type. A simple event-driven parser of WebAssembly binary 211 /// format. The `read(&mut self)` is used to iterate through WebAssembly records. 212 pub struct Parser<'a> { 213 data: &'a [u8], 214 state: ParserState<'a>, 215 module_reader: Option<ModuleReader<'a>>, 216 current_section: Option<Section<'a>>, 217 section_reader: ParserSectionReader<'a>, 218 element_items: Option<ElementItems<'a>>, 219 current_function_body: Option<FunctionBody<'a>>, 220 init_expr_continuation: Option<InitExpressionContinuationSection>, 221 current_data_segment: Option<&'a [u8]>, 222 binary_reader: Option<BinaryReader<'a>>, 223 operators_reader: Option<OperatorsReader<'a>>, 224 section_entries_left: u32, 225 } 226 227 impl<'a> Parser<'a> { 228 /// Constructs `Parser` type. 229 /// 230 /// # Examples 231 /// ``` 232 /// let data: &[u8] = &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 233 /// 0x01, 0x4, 0x01, 0x60, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 234 /// 0x0a, 0x05, 0x01, 0x03, 0x00, 0x01, 0x0b]; 235 /// let mut parser = wasmparser::Parser::new(data); 236 /// ``` new(data: &[u8]) -> Parser237 pub fn new(data: &[u8]) -> Parser { 238 Parser { 239 data, 240 state: ParserState::Initial, 241 module_reader: None, 242 current_section: None, 243 section_reader: ParserSectionReader::None, 244 element_items: None, 245 current_function_body: None, 246 init_expr_continuation: None, 247 current_data_segment: None, 248 binary_reader: None, 249 operators_reader: None, 250 section_entries_left: 0, 251 } 252 } 253 eof(&self) -> bool254 pub fn eof(&self) -> bool { 255 match self.state { 256 ParserState::EndWasm => true, 257 ParserState::BeginWasm { .. } | ParserState::EndSection => { 258 self.module_reader.as_ref().expect("module reader").eof() 259 } 260 _ => false, // in-process of reading 261 } 262 } 263 current_position(&self) -> usize264 pub fn current_position(&self) -> usize { 265 if let ParserState::Initial = self.state { 266 return 0; 267 } 268 if self.binary_reader.is_some() { 269 return self 270 .binary_reader 271 .as_ref() 272 .expect("binary reader") 273 .original_position(); 274 } 275 if self.operators_reader.is_some() { 276 return self 277 .operators_reader 278 .as_ref() 279 .expect("operators reader") 280 .original_position(); 281 } 282 match self.section_reader { 283 ParserSectionReader::CodeSectionReader(ref reader) => { 284 return reader.original_position() 285 } 286 ParserSectionReader::DataSectionReader(ref reader) => { 287 return reader.original_position() 288 } 289 ParserSectionReader::ElementSectionReader(ref reader) => { 290 return reader.original_position(); 291 } 292 ParserSectionReader::ExportSectionReader(ref reader) => { 293 return reader.original_position(); 294 } 295 ParserSectionReader::FunctionSectionReader(ref reader) => { 296 return reader.original_position(); 297 } 298 ParserSectionReader::GlobalSectionReader(ref reader) => { 299 return reader.original_position(); 300 } 301 ParserSectionReader::ImportSectionReader(ref reader) => { 302 return reader.original_position(); 303 } 304 ParserSectionReader::MemorySectionReader(ref reader) => { 305 return reader.original_position(); 306 } 307 ParserSectionReader::TableSectionReader(ref reader) => { 308 return reader.original_position(); 309 } 310 ParserSectionReader::TypeSectionReader(ref reader) => { 311 return reader.original_position() 312 } 313 ParserSectionReader::NameSectionReader(ref reader) => { 314 return reader.original_position() 315 } 316 ParserSectionReader::LinkingSectionReader(ref reader) => { 317 return reader.original_position(); 318 } 319 ParserSectionReader::RelocSectionReader(ref reader) => { 320 return reader.original_position(); 321 } 322 _ => (), 323 }; 324 // TODO might not cover all cases 325 self.module_reader 326 .as_ref() 327 .expect("module reader") 328 .current_position() 329 } 330 read_module(&mut self) -> Result<()>331 fn read_module(&mut self) -> Result<()> { 332 let module_reader = ModuleReader::new(self.data)?; 333 let version = module_reader.get_version(); 334 self.module_reader = Some(module_reader); 335 self.state = ParserState::BeginWasm { version }; 336 Ok(()) 337 } 338 read_section_header(&mut self) -> Result<()>339 fn read_section_header(&mut self) -> Result<()> { 340 let section = self.module_reader.as_mut().expect("module reader").read()?; 341 let code = section.code; 342 let range = section.range(); 343 self.current_section = Some(section); 344 self.state = ParserState::BeginSection { code, range }; 345 Ok(()) 346 } 347 read_type_entry(&mut self) -> Result<()>348 fn read_type_entry(&mut self) -> Result<()> { 349 if self.section_entries_left == 0 { 350 return self.check_section_end(); 351 } 352 let type_entry = section_reader!(self, TypeSectionReader).read()?; 353 self.state = ParserState::TypeSectionEntry(type_entry); 354 self.section_entries_left -= 1; 355 Ok(()) 356 } 357 read_import_entry(&mut self) -> Result<()>358 fn read_import_entry(&mut self) -> Result<()> { 359 if self.section_entries_left == 0 { 360 return self.check_section_end(); 361 } 362 let Import { module, field, ty } = section_reader!(self, ImportSectionReader).read()?; 363 self.state = ParserState::ImportSectionEntry { module, field, ty }; 364 self.section_entries_left -= 1; 365 Ok(()) 366 } 367 read_function_entry(&mut self) -> Result<()>368 fn read_function_entry(&mut self) -> Result<()> { 369 if self.section_entries_left == 0 { 370 return self.check_section_end(); 371 } 372 let func_type = section_reader!(self, FunctionSectionReader).read()?; 373 self.state = ParserState::FunctionSectionEntry(func_type); 374 self.section_entries_left -= 1; 375 Ok(()) 376 } 377 read_memory_entry(&mut self) -> Result<()>378 fn read_memory_entry(&mut self) -> Result<()> { 379 if self.section_entries_left == 0 { 380 return self.check_section_end(); 381 } 382 let memory_type = section_reader!(self, MemorySectionReader).read()?; 383 self.state = ParserState::MemorySectionEntry(memory_type); 384 self.section_entries_left -= 1; 385 Ok(()) 386 } 387 read_global_entry(&mut self) -> Result<()>388 fn read_global_entry(&mut self) -> Result<()> { 389 if self.section_entries_left == 0 { 390 return self.check_section_end(); 391 } 392 let Global { ty, init_expr } = section_reader!(self, GlobalSectionReader).read()?; 393 self.state = ParserState::BeginGlobalSectionEntry(ty); 394 self.operators_reader = Some(init_expr.get_operators_reader()); 395 self.section_entries_left -= 1; 396 Ok(()) 397 } 398 read_init_expression_body(&mut self, cont: InitExpressionContinuationSection)399 fn read_init_expression_body(&mut self, cont: InitExpressionContinuationSection) { 400 self.state = ParserState::BeginInitExpressionBody; 401 self.init_expr_continuation = Some(cont); 402 } 403 read_init_expression_operator(&mut self) -> Result<()>404 fn read_init_expression_operator(&mut self) -> Result<()> { 405 let op = self 406 .operators_reader 407 .as_mut() 408 .expect("operator reader") 409 .read()?; 410 if let Operator::End = op { 411 self.operators_reader = None; 412 self.state = ParserState::EndInitExpressionBody; 413 return Ok(()); 414 } 415 self.state = ParserState::InitExpressionOperator(op); 416 Ok(()) 417 } 418 read_export_entry(&mut self) -> Result<()>419 fn read_export_entry(&mut self) -> Result<()> { 420 if self.section_entries_left == 0 { 421 return self.check_section_end(); 422 } 423 let Export { field, kind, index } = section_reader!(self, ExportSectionReader).read()?; 424 self.state = ParserState::ExportSectionEntry { field, kind, index }; 425 self.section_entries_left -= 1; 426 Ok(()) 427 } 428 read_element_entry(&mut self) -> Result<()>429 fn read_element_entry(&mut self) -> Result<()> { 430 if self.section_entries_left == 0 { 431 return self.check_section_end(); 432 } 433 let Element { kind, items, ty } = section_reader!(self, ElementSectionReader).read()?; 434 let table = match kind { 435 ElementKind::Passive => ElemSectionEntryTable::Passive, 436 ElementKind::Declared => ElemSectionEntryTable::Declared, 437 ElementKind::Active { 438 table_index, 439 init_expr, 440 } => { 441 self.operators_reader = Some(init_expr.get_operators_reader()); 442 ElemSectionEntryTable::Active(table_index) 443 } 444 }; 445 self.state = ParserState::BeginElementSectionEntry { table, ty }; 446 self.element_items = Some(items); 447 self.section_entries_left -= 1; 448 Ok(()) 449 } 450 read_element_entry_body(&mut self) -> Result<()>451 fn read_element_entry_body(&mut self) -> Result<()> { 452 let mut reader = self 453 .element_items 454 .take() 455 .expect("element items") 456 .get_items_reader()?; 457 let num_elements = reader.get_count() as usize; 458 if num_elements > MAX_WASM_TABLE_ENTRIES { 459 return Err(BinaryReaderError::new( 460 "num_elements is out of bounds", 461 0, // reader.position - 1, // TODO offset 462 )); 463 } 464 let mut elements = Vec::with_capacity(num_elements); 465 for _ in 0..num_elements { 466 elements.push(reader.read()?); 467 } 468 self.state = ParserState::ElementSectionEntryBody(elements.into_boxed_slice()); 469 Ok(()) 470 } 471 read_function_body(&mut self) -> Result<()>472 fn read_function_body(&mut self) -> Result<()> { 473 if self.section_entries_left == 0 { 474 self.current_function_body = None; 475 return self.check_section_end(); 476 } 477 let function_body = section_reader!(self, CodeSectionReader).read()?; 478 let range = function_body.range(); 479 self.state = ParserState::BeginFunctionBody { range }; 480 self.current_function_body = Some(function_body); 481 self.section_entries_left -= 1; 482 Ok(()) 483 } 484 read_function_body_locals(&mut self) -> Result<()>485 fn read_function_body_locals(&mut self) -> Result<()> { 486 let function_body = self.current_function_body.as_mut().expect("function body"); 487 let mut reader = function_body.get_locals_reader()?; 488 let local_count = reader.get_count() as usize; 489 if local_count > MAX_WASM_FUNCTION_LOCALS { 490 return Err(BinaryReaderError::new( 491 "local_count is out of bounds", 492 reader.original_position() - 1, 493 )); 494 } 495 let mut locals: Vec<(u32, Type)> = Vec::with_capacity(local_count); 496 let mut locals_total: usize = 0; 497 for _ in 0..local_count { 498 let (count, ty) = reader.read()?; 499 locals_total = locals_total.checked_add(count as usize).ok_or_else(|| { 500 BinaryReaderError::new( 501 "locals_total is out of bounds", 502 reader.original_position() - 1, 503 ) 504 })?; 505 if locals_total > MAX_WASM_FUNCTION_LOCALS { 506 return Err(BinaryReaderError::new( 507 "locals_total is out of bounds", 508 reader.original_position() - 1, 509 )); 510 } 511 locals.push((count, ty)); 512 } 513 self.operators_reader = Some(function_body.get_operators_reader()?); 514 self.state = ParserState::FunctionBodyLocals { 515 locals: locals.into_boxed_slice(), 516 }; 517 Ok(()) 518 } 519 read_code_operator(&mut self) -> Result<()>520 fn read_code_operator(&mut self) -> Result<()> { 521 if self 522 .operators_reader 523 .as_ref() 524 .expect("operator reader") 525 .eof() 526 { 527 if let ParserState::CodeOperator(Operator::End) = self.state { 528 self.state = ParserState::EndFunctionBody; 529 self.operators_reader = None; 530 self.current_function_body = None; 531 return Ok(()); 532 } 533 let reader = self.operators_reader.as_ref().expect("operator reader"); 534 return Err(BinaryReaderError::new( 535 "Expected end of function marker", 536 reader.original_position(), 537 )); 538 } 539 let reader = self.operators_reader.as_mut().expect("operator reader"); 540 let op = reader.read()?; 541 self.state = ParserState::CodeOperator(op); 542 Ok(()) 543 } 544 read_table_entry(&mut self) -> Result<()>545 fn read_table_entry(&mut self) -> Result<()> { 546 if self.section_entries_left == 0 { 547 return self.check_section_end(); 548 } 549 let table_entry = section_reader!(self, TableSectionReader).read()?; 550 self.state = ParserState::TableSectionEntry(table_entry); 551 self.section_entries_left -= 1; 552 Ok(()) 553 } 554 read_data_entry(&mut self) -> Result<()>555 fn read_data_entry(&mut self) -> Result<()> { 556 if self.section_entries_left == 0 { 557 return self.check_section_end(); 558 } 559 let Data { kind, data } = section_reader!(self, DataSectionReader).read()?; 560 match kind { 561 DataKind::Passive => { 562 self.state = ParserState::BeginPassiveDataSectionEntry; 563 } 564 DataKind::Active { 565 memory_index, 566 init_expr, 567 } => { 568 self.state = ParserState::BeginActiveDataSectionEntry(memory_index); 569 self.operators_reader = Some(init_expr.get_operators_reader()); 570 } 571 } 572 self.current_data_segment = Some(data); 573 self.section_entries_left -= 1; 574 Ok(()) 575 } 576 read_data_entry_body(&mut self) -> Result<()>577 fn read_data_entry_body(&mut self) -> Result<()> { 578 let size = self.current_data_segment.expect("data entry").len(); 579 self.state = ParserState::BeginDataSectionEntryBody(size as u32); 580 Ok(()) 581 } 582 read_naming<'b>( mut naming_reader: NamingReader<'a>, limit: usize, ) -> Result<Box<[Naming<'b>]>> where 'a: 'b,583 fn read_naming<'b>( 584 mut naming_reader: NamingReader<'a>, 585 limit: usize, 586 ) -> Result<Box<[Naming<'b>]>> 587 where 588 'a: 'b, 589 { 590 let count = naming_reader.get_count() as usize; 591 if count > limit { 592 return Err(BinaryReaderError::new( 593 "name map size is out of bound", 594 naming_reader.original_position() - 1, 595 )); 596 } 597 let mut result = Vec::with_capacity(count); 598 for _ in 0..count { 599 result.push(naming_reader.read()?); 600 } 601 Ok(result.into_boxed_slice()) 602 } 603 read_name_entry(&mut self) -> Result<()>604 fn read_name_entry(&mut self) -> Result<()> { 605 if section_reader!(self, NameSectionReader).eof() { 606 return self.position_to_section_end(); 607 } 608 let entry = match section_reader!(self, NameSectionReader).read()? { 609 Name::Module(name) => NameEntry::Module(name.get_name()?), 610 Name::Function(func) => { 611 NameEntry::Function(Self::read_naming(func.get_map()?, MAX_WASM_FUNCTIONS)?) 612 } 613 Name::Local(locals) => { 614 let mut reader = locals.get_function_local_reader()?; 615 let funcs_len = reader.get_count() as usize; 616 if funcs_len > MAX_WASM_FUNCTIONS { 617 return Err(BinaryReaderError::new( 618 "function count is out of bounds", 619 reader.original_position() - 1, 620 )); 621 } 622 let mut funcs: Vec<LocalName<'a>> = Vec::with_capacity(funcs_len); 623 for _ in 0..funcs_len { 624 let func = reader.read()?; 625 funcs.push(LocalName { 626 index: func.func_index, 627 locals: Self::read_naming(func.get_map()?, MAX_WASM_FUNCTION_LOCALS)?, 628 }); 629 } 630 NameEntry::Local(funcs.into_boxed_slice()) 631 } 632 }; 633 self.state = ParserState::NameSectionEntry(entry); 634 Ok(()) 635 } 636 read_source_mapping(&mut self) -> Result<()>637 fn read_source_mapping(&mut self) -> Result<()> { 638 let url = self 639 .current_section 640 .as_ref() 641 .expect("section") 642 .get_sourcemappingurl_section_content()?; 643 self.state = ParserState::SourceMappingURL(url); 644 Ok(()) 645 } 646 647 // See https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md read_reloc_header(&mut self) -> Result<()>648 fn read_reloc_header(&mut self) -> Result<()> { 649 let section_code = section_reader!(self, RelocSectionReader).get_section_code(); 650 self.state = ParserState::RelocSectionHeader(section_code); 651 Ok(()) 652 } 653 read_reloc_entry(&mut self) -> Result<()>654 fn read_reloc_entry(&mut self) -> Result<()> { 655 if self.section_entries_left == 0 { 656 return self.check_section_end(); 657 } 658 let Reloc { 659 ty, 660 offset, 661 index, 662 addend, 663 } = section_reader!(self, RelocSectionReader).read()?; 664 self.state = ParserState::RelocSectionEntry(RelocEntry { 665 ty, 666 offset, 667 index, 668 addend, 669 }); 670 self.section_entries_left -= 1; 671 Ok(()) 672 } 673 read_linking_entry(&mut self) -> Result<()>674 fn read_linking_entry(&mut self) -> Result<()> { 675 if self.section_entries_left == 0 { 676 return self.check_section_end(); 677 } 678 let entry = section_reader!(self, LinkingSectionReader).read()?; 679 self.state = ParserState::LinkingSectionEntry(entry); 680 self.section_entries_left -= 1; 681 Ok(()) 682 } 683 read_section_body(&mut self) -> Result<()>684 fn read_section_body(&mut self) -> Result<()> { 685 match self.state { 686 ParserState::BeginSection { 687 code: SectionCode::Type, 688 .. 689 } => { 690 start_section_reader!(self, TypeSectionReader, get_type_section_reader); 691 self.read_type_entry()?; 692 } 693 ParserState::BeginSection { 694 code: SectionCode::Import, 695 .. 696 } => { 697 start_section_reader!(self, ImportSectionReader, get_import_section_reader); 698 self.read_import_entry()?; 699 } 700 ParserState::BeginSection { 701 code: SectionCode::Function, 702 .. 703 } => { 704 start_section_reader!(self, FunctionSectionReader, get_function_section_reader); 705 self.read_function_entry()?; 706 } 707 ParserState::BeginSection { 708 code: SectionCode::Memory, 709 .. 710 } => { 711 start_section_reader!(self, MemorySectionReader, get_memory_section_reader); 712 self.read_memory_entry()?; 713 } 714 ParserState::BeginSection { 715 code: SectionCode::Global, 716 .. 717 } => { 718 start_section_reader!(self, GlobalSectionReader, get_global_section_reader); 719 self.read_global_entry()?; 720 } 721 ParserState::BeginSection { 722 code: SectionCode::Export, 723 .. 724 } => { 725 start_section_reader!(self, ExportSectionReader, get_export_section_reader); 726 self.read_export_entry()?; 727 } 728 ParserState::BeginSection { 729 code: SectionCode::Element, 730 .. 731 } => { 732 start_section_reader!(self, ElementSectionReader, get_element_section_reader); 733 self.read_element_entry()?; 734 } 735 ParserState::BeginSection { 736 code: SectionCode::Code, 737 .. 738 } => { 739 start_section_reader!(self, CodeSectionReader, get_code_section_reader); 740 self.read_function_body()?; 741 } 742 ParserState::BeginSection { 743 code: SectionCode::Table, 744 .. 745 } => { 746 start_section_reader!(self, TableSectionReader, get_table_section_reader); 747 self.read_table_entry()?; 748 } 749 ParserState::BeginSection { 750 code: SectionCode::Data, 751 .. 752 } => { 753 start_section_reader!(self, DataSectionReader, get_data_section_reader); 754 self.read_data_entry()?; 755 } 756 ParserState::BeginSection { 757 code: SectionCode::Start, 758 .. 759 } => { 760 let func_index = self 761 .current_section 762 .as_ref() 763 .expect("section") 764 .get_start_section_content()?; 765 self.state = ParserState::StartSectionEntry(func_index); 766 } 767 ParserState::BeginSection { 768 code: SectionCode::DataCount, 769 .. 770 } => { 771 let func_index = self 772 .current_section 773 .as_ref() 774 .expect("section") 775 .get_data_count_section_content()?; 776 self.state = ParserState::DataCountSectionEntry(func_index); 777 } 778 ParserState::BeginSection { 779 code: SectionCode::Custom { .. }, 780 .. 781 } => { 782 self.create_custom_section_binary_reader(); 783 self.read_section_body_bytes()?; 784 } 785 _ => unreachable!(), 786 } 787 Ok(()) 788 } 789 create_custom_section_binary_reader(&mut self)790 fn create_custom_section_binary_reader(&mut self) { 791 let reader = self 792 .current_section 793 .as_ref() 794 .expect("section") 795 .get_binary_reader(); 796 self.binary_reader = Some(reader); 797 } 798 read_custom_section_body(&mut self) -> Result<()>799 fn read_custom_section_body(&mut self) -> Result<()> { 800 match self.state { 801 ParserState::ReadingCustomSection(CustomSectionKind::Name) => { 802 let reader = self 803 .current_section 804 .as_ref() 805 .expect("section") 806 .get_name_section_reader()?; 807 self.section_reader = ParserSectionReader::NameSectionReader(reader); 808 self.read_name_entry()?; 809 } 810 ParserState::ReadingCustomSection(CustomSectionKind::SourceMappingURL) => { 811 self.read_source_mapping()?; 812 } 813 ParserState::ReadingCustomSection(CustomSectionKind::Reloc) => { 814 start_section_reader!(self, RelocSectionReader, get_reloc_section_reader); 815 self.read_reloc_header()?; 816 } 817 ParserState::ReadingCustomSection(CustomSectionKind::Linking) => { 818 start_section_reader!(self, LinkingSectionReader, get_linking_section_reader); 819 self.read_linking_entry()?; 820 } 821 ParserState::ReadingCustomSection(CustomSectionKind::Producers) 822 | ParserState::ReadingCustomSection(CustomSectionKind::Unknown) => { 823 self.create_custom_section_binary_reader(); 824 self.read_section_body_bytes()?; 825 } 826 _ => unreachable!(), 827 } 828 Ok(()) 829 } 830 position_to_section_end(&mut self) -> Result<()>831 fn position_to_section_end(&mut self) -> Result<()> { 832 self.current_section = None; 833 self.binary_reader = None; 834 self.state = ParserState::EndSection; 835 Ok(()) 836 } 837 check_section_end(&mut self) -> Result<()>838 fn check_section_end(&mut self) -> Result<()> { 839 match self.section_reader { 840 ParserSectionReader::CodeSectionReader(ref reader) => reader.ensure_end()?, 841 ParserSectionReader::DataSectionReader(ref reader) => reader.ensure_end()?, 842 ParserSectionReader::ElementSectionReader(ref reader) => reader.ensure_end()?, 843 ParserSectionReader::ExportSectionReader(ref reader) => reader.ensure_end()?, 844 ParserSectionReader::FunctionSectionReader(ref reader) => reader.ensure_end()?, 845 ParserSectionReader::GlobalSectionReader(ref reader) => reader.ensure_end()?, 846 ParserSectionReader::ImportSectionReader(ref reader) => reader.ensure_end()?, 847 ParserSectionReader::MemorySectionReader(ref reader) => reader.ensure_end()?, 848 ParserSectionReader::TableSectionReader(ref reader) => reader.ensure_end()?, 849 ParserSectionReader::TypeSectionReader(ref reader) => reader.ensure_end()?, 850 ParserSectionReader::LinkingSectionReader(ref reader) => reader.ensure_end()?, 851 ParserSectionReader::RelocSectionReader(ref reader) => reader.ensure_end()?, 852 _ => unreachable!(), 853 } 854 self.position_to_section_end() 855 } 856 read_section_body_bytes(&mut self) -> Result<()>857 fn read_section_body_bytes(&mut self) -> Result<()> { 858 if self.binary_reader.as_ref().expect("binary reader").eof() { 859 self.state = ParserState::EndSection; 860 self.binary_reader = None; 861 return Ok(()); 862 } 863 let binary_reader = self.binary_reader.as_mut().expect("binary reader"); 864 let to_read = if binary_reader.buffer.len() - binary_reader.position < MAX_DATA_CHUNK_SIZE { 865 binary_reader.buffer.len() - binary_reader.position 866 } else { 867 MAX_DATA_CHUNK_SIZE 868 }; 869 let bytes = binary_reader.read_bytes(to_read)?; 870 self.state = ParserState::SectionRawData(bytes); 871 Ok(()) 872 } 873 read_data_chunk(&mut self) -> Result<()>874 fn read_data_chunk(&mut self) -> Result<()> { 875 let data = self.current_data_segment.expect("data"); 876 if data.is_empty() { 877 self.state = ParserState::EndDataSectionEntryBody; 878 self.current_data_segment = None; 879 return Ok(()); 880 } 881 let to_read = if data.len() > MAX_DATA_CHUNK_SIZE { 882 MAX_DATA_CHUNK_SIZE 883 } else { 884 data.len() 885 }; 886 let (head, tail) = data.split_at(to_read); 887 self.current_data_segment = Some(tail); 888 self.state = ParserState::DataSectionEntryBodyChunk(head); 889 Ok(()) 890 } 891 read_next_section(&mut self) -> Result<()>892 fn read_next_section(&mut self) -> Result<()> { 893 if self.module_reader.as_ref().expect("module_reader").eof() { 894 self.current_section = None; 895 self.state = ParserState::EndWasm; 896 } else { 897 self.read_section_header()?; 898 } 899 Ok(()) 900 } 901 read_wrapped(&mut self) -> Result<()>902 fn read_wrapped(&mut self) -> Result<()> { 903 match self.state { 904 ParserState::EndWasm => panic!("Parser in end state"), 905 ParserState::Error(_) => panic!("Parser in error state"), 906 ParserState::Initial => self.read_module()?, 907 ParserState::BeginWasm { .. } | ParserState::EndSection => self.read_next_section()?, 908 ParserState::BeginSection { .. } => self.read_section_body()?, 909 ParserState::SkippingSection => { 910 self.position_to_section_end()?; 911 self.read_next_section()?; 912 } 913 ParserState::TypeSectionEntry(_) => self.read_type_entry()?, 914 ParserState::ImportSectionEntry { .. } => self.read_import_entry()?, 915 ParserState::FunctionSectionEntry(_) => self.read_function_entry()?, 916 ParserState::MemorySectionEntry(_) => self.read_memory_entry()?, 917 ParserState::TableSectionEntry(_) => self.read_table_entry()?, 918 ParserState::ExportSectionEntry { .. } => self.read_export_entry()?, 919 ParserState::BeginGlobalSectionEntry(_) => { 920 self.read_init_expression_body(InitExpressionContinuationSection::Global) 921 } 922 ParserState::EndGlobalSectionEntry => self.read_global_entry()?, 923 ParserState::BeginElementSectionEntry { 924 table: ElemSectionEntryTable::Active(_), 925 .. 926 } => self.read_init_expression_body(InitExpressionContinuationSection::Element), 927 ParserState::BeginElementSectionEntry { .. } => self.read_element_entry_body()?, 928 ParserState::BeginInitExpressionBody | ParserState::InitExpressionOperator(_) => { 929 self.read_init_expression_operator()? 930 } 931 ParserState::BeginPassiveDataSectionEntry => self.read_data_entry_body()?, 932 ParserState::BeginActiveDataSectionEntry(_) => { 933 self.read_init_expression_body(InitExpressionContinuationSection::Data) 934 } 935 ParserState::EndInitExpressionBody => { 936 match self.init_expr_continuation { 937 Some(InitExpressionContinuationSection::Global) => { 938 self.state = ParserState::EndGlobalSectionEntry 939 } 940 Some(InitExpressionContinuationSection::Element) => { 941 self.read_element_entry_body()? 942 } 943 Some(InitExpressionContinuationSection::Data) => self.read_data_entry_body()?, 944 None => unreachable!(), 945 } 946 self.init_expr_continuation = None; 947 } 948 ParserState::BeginFunctionBody { .. } => self.read_function_body_locals()?, 949 ParserState::FunctionBodyLocals { .. } | ParserState::CodeOperator(_) => { 950 self.read_code_operator()? 951 } 952 ParserState::EndFunctionBody => self.read_function_body()?, 953 ParserState::SkippingFunctionBody => { 954 self.current_function_body = None; 955 self.read_function_body()?; 956 } 957 ParserState::EndDataSectionEntry => self.read_data_entry()?, 958 ParserState::BeginDataSectionEntryBody(_) 959 | ParserState::DataSectionEntryBodyChunk(_) => self.read_data_chunk()?, 960 ParserState::EndDataSectionEntryBody => { 961 self.state = ParserState::EndDataSectionEntry; 962 } 963 ParserState::ElementSectionEntryBody(_) => { 964 self.state = ParserState::EndElementSectionEntry; 965 } 966 ParserState::EndElementSectionEntry => self.read_element_entry()?, 967 ParserState::StartSectionEntry(_) => self.position_to_section_end()?, 968 ParserState::DataCountSectionEntry(_) => self.position_to_section_end()?, 969 ParserState::NameSectionEntry(_) => self.read_name_entry()?, 970 ParserState::SourceMappingURL(_) => self.position_to_section_end()?, 971 ParserState::RelocSectionHeader(_) => { 972 let mut reader = self 973 .current_section 974 .as_ref() 975 .expect("section") 976 .get_binary_reader(); 977 self.section_entries_left = reader.read_var_u32()?; 978 self.binary_reader = Some(reader); 979 self.read_reloc_entry()?; 980 } 981 ParserState::RelocSectionEntry(_) => self.read_reloc_entry()?, 982 ParserState::LinkingSectionEntry(_) => self.read_linking_entry()?, 983 ParserState::ReadingCustomSection(_) => self.read_custom_section_body()?, 984 ParserState::ReadingSectionRawData | ParserState::SectionRawData(_) => { 985 self.read_section_body_bytes()? 986 } 987 } 988 Ok(()) 989 } 990 skip_section(&mut self)991 fn skip_section(&mut self) { 992 match self.state { 993 ParserState::Initial 994 | ParserState::EndWasm 995 | ParserState::Error(_) 996 | ParserState::BeginWasm { .. } 997 | ParserState::EndSection => panic!("Invalid reader state during skip section"), 998 _ => self.state = ParserState::SkippingSection, 999 } 1000 } 1001 skip_function_body(&mut self)1002 fn skip_function_body(&mut self) { 1003 match self.state { 1004 ParserState::BeginFunctionBody { .. } 1005 | ParserState::FunctionBodyLocals { .. } 1006 | ParserState::CodeOperator(_) => self.state = ParserState::SkippingFunctionBody, 1007 _ => panic!("Invalid reader state during skip function body"), 1008 } 1009 } 1010 read_custom_section(&mut self)1011 fn read_custom_section(&mut self) { 1012 match self.state { 1013 ParserState::BeginSection { 1014 code: SectionCode::Custom { kind, .. }, 1015 .. 1016 } => { 1017 self.state = ParserState::ReadingCustomSection(kind); 1018 } 1019 _ => panic!("Invalid reader state during reading custom section"), 1020 } 1021 } 1022 read_raw_section_data(&mut self)1023 fn read_raw_section_data(&mut self) { 1024 match self.state { 1025 ParserState::BeginSection { .. } => { 1026 self.binary_reader = Some( 1027 self.current_section 1028 .as_ref() 1029 .expect("section") 1030 .get_binary_reader(), 1031 ); 1032 self.state = ParserState::ReadingSectionRawData; 1033 } 1034 _ => panic!("Invalid reader state during reading raw section data"), 1035 } 1036 } 1037 } 1038 1039 impl<'a> WasmDecoder<'a> for Parser<'a> { 1040 /// Reads next record from the WebAssembly binary data. The methods returns 1041 /// reference to current state of the parser. See `ParserState` num. 1042 /// 1043 /// # Examples 1044 /// ``` 1045 /// # let data: &[u8] = &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 1046 /// # 0x01, 0x4, 0x01, 0x60, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 1047 /// # 0x0a, 0x05, 0x01, 0x03, 0x00, 0x01, 0x0b]; 1048 /// use wasmparser::WasmDecoder; 1049 /// let mut parser = wasmparser::Parser::new(data); 1050 /// { 1051 /// let state = parser.read(); 1052 /// println!("First state {:?}", state); 1053 /// } 1054 /// { 1055 /// let state = parser.read(); 1056 /// println!("Second state {:?}", state); 1057 /// } 1058 /// ``` read(&mut self) -> &ParserState<'a>1059 fn read(&mut self) -> &ParserState<'a> { 1060 let result = self.read_wrapped(); 1061 if result.is_err() { 1062 self.state = ParserState::Error(result.err().unwrap()); 1063 } 1064 &self.state 1065 } 1066 push_input(&mut self, input: ParserInput)1067 fn push_input(&mut self, input: ParserInput) { 1068 match input { 1069 ParserInput::Default => (), 1070 ParserInput::SkipSection => self.skip_section(), 1071 ParserInput::SkipFunctionBody => self.skip_function_body(), 1072 ParserInput::ReadCustomSection => self.read_custom_section(), 1073 ParserInput::ReadSectionRawData => self.read_raw_section_data(), 1074 } 1075 } 1076 1077 /// Creates a BinaryReader when current state is ParserState::BeginSection 1078 /// or ParserState::BeginFunctionBody. 1079 /// 1080 /// # Examples 1081 /// ``` 1082 /// # let data = &[0x0, 0x61, 0x73, 0x6d, 0x1, 0x0, 0x0, 0x0, 0x1, 0x84, 1083 /// # 0x80, 0x80, 0x80, 0x0, 0x1, 0x60, 0x0, 0x0, 0x3, 0x83, 1084 /// # 0x80, 0x80, 0x80, 0x0, 0x2, 0x0, 0x0, 0x6, 0x81, 0x80, 1085 /// # 0x80, 0x80, 0x0, 0x0, 0xa, 0x91, 0x80, 0x80, 0x80, 0x0, 1086 /// # 0x2, 0x83, 0x80, 0x80, 0x80, 0x0, 0x0, 0x1, 0xb, 0x83, 1087 /// # 0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0xb]; 1088 /// use wasmparser::{WasmDecoder, Parser, ParserState}; 1089 /// let mut parser = Parser::new(data); 1090 /// let mut types = Vec::new(); 1091 /// let mut function_types = Vec::new(); 1092 /// let mut function_readers = Vec::new(); 1093 /// loop { 1094 /// match parser.read() { 1095 /// ParserState::Error(_) | 1096 /// ParserState::EndWasm => break, 1097 /// ParserState::TypeSectionEntry(ty) => { 1098 /// types.push(ty.clone()); 1099 /// } 1100 /// ParserState::FunctionSectionEntry(id) => { 1101 /// function_types.push(id.clone()); 1102 /// } 1103 /// ParserState::BeginFunctionBody {..} => { 1104 /// let reader = parser.create_binary_reader(); 1105 /// function_readers.push(reader); 1106 /// } 1107 /// _ => continue 1108 /// } 1109 /// } 1110 /// for (i, reader) in function_readers.iter_mut().enumerate() { 1111 /// // Access the function type through the types table. 1112 /// let ty = &types[function_types[i] as usize]; 1113 /// println!("\nFunction {} of type {:?}", i, ty); 1114 /// // Read the local declarations required by the function body. 1115 /// let local_decls_len = reader.read_local_count().unwrap(); 1116 /// let mut local_decls = Vec::with_capacity(local_decls_len); 1117 /// let mut local_count = ty.params.len(); 1118 /// for _ in 0..local_decls_len { 1119 /// let local_decl = reader.read_local_decl(&mut local_count).unwrap(); 1120 /// local_decls.push(local_decl); 1121 /// } 1122 /// println!("Function locals: vars {:?}; total {} ", local_decls, local_count); 1123 /// // Read the operations of the function body. 1124 /// while let Ok(ref op) = reader.read_operator() { 1125 /// println!(" {:?}", op); 1126 /// } 1127 /// } 1128 /// ``` create_binary_reader<'b>(&mut self) -> BinaryReader<'b> where 'a: 'b,1129 fn create_binary_reader<'b>(&mut self) -> BinaryReader<'b> 1130 where 1131 'a: 'b, 1132 { 1133 match self.state { 1134 ParserState::BeginSection { .. } => self 1135 .current_section 1136 .as_ref() 1137 .expect("section") 1138 .get_binary_reader(), 1139 ParserState::BeginFunctionBody { .. } | ParserState::FunctionBodyLocals { .. } => self 1140 .current_function_body 1141 .as_ref() 1142 .expect("function body") 1143 .get_binary_reader(), 1144 _ => panic!("Invalid reader state during get binary reader operation"), 1145 } 1146 } 1147 1148 /// Reads next record from the WebAssembly binary data. It also allows to 1149 /// control how parser will treat the next record(s). The method accepts the 1150 /// `ParserInput` parameter that allows e.g. to skip section or function 1151 /// operators. The methods returns reference to current state of the parser. 1152 /// 1153 /// # Examples 1154 /// ``` 1155 /// # let data: &[u8] = &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 1156 /// # 0x01, 0x4, 0x01, 0x60, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 1157 /// # 0x0a, 0x05, 0x01, 0x03, 0x00, 0x01, 0x0b]; 1158 /// use wasmparser::WasmDecoder; 1159 /// let mut parser = wasmparser::Parser::new(data); 1160 /// let mut next_input = wasmparser::ParserInput::Default; 1161 /// loop { 1162 /// let state = parser.read_with_input(next_input); 1163 /// match *state { 1164 /// wasmparser::ParserState::EndWasm => break, 1165 /// wasmparser::ParserState::BeginWasm { .. } | 1166 /// wasmparser::ParserState::EndSection => 1167 /// next_input = wasmparser::ParserInput::Default, 1168 /// wasmparser::ParserState::BeginSection { ref code, .. } => { 1169 /// println!("Found section: {:?}", code); 1170 /// next_input = wasmparser::ParserInput::SkipSection; 1171 /// }, 1172 /// _ => unreachable!() 1173 /// } 1174 /// } 1175 /// ``` read_with_input(&mut self, input: ParserInput) -> &ParserState<'a>1176 fn read_with_input(&mut self, input: ParserInput) -> &ParserState<'a> { 1177 self.push_input(input); 1178 self.read() 1179 } 1180 last_state(&self) -> &ParserState<'a>1181 fn last_state(&self) -> &ParserState<'a> { 1182 &self.state 1183 } 1184 } 1185