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 { 460 message: "num_elements is out of bounds", 461 offset: 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 { 491 message: "local_count is out of bounds", 492 offset: 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 = 500 locals_total 501 .checked_add(count as usize) 502 .ok_or_else(|| BinaryReaderError { 503 message: "locals_total is out of bounds", 504 offset: reader.original_position() - 1, 505 })?; 506 if locals_total > MAX_WASM_FUNCTION_LOCALS { 507 return Err(BinaryReaderError { 508 message: "locals_total is out of bounds", 509 offset: reader.original_position() - 1, 510 }); 511 } 512 locals.push((count, ty)); 513 } 514 self.operators_reader = Some(function_body.get_operators_reader()?); 515 self.state = ParserState::FunctionBodyLocals { 516 locals: locals.into_boxed_slice(), 517 }; 518 Ok(()) 519 } 520 read_code_operator(&mut self) -> Result<()>521 fn read_code_operator(&mut self) -> Result<()> { 522 if self 523 .operators_reader 524 .as_ref() 525 .expect("operator reader") 526 .eof() 527 { 528 if let ParserState::CodeOperator(Operator::End) = self.state { 529 self.state = ParserState::EndFunctionBody; 530 self.operators_reader = None; 531 self.current_function_body = None; 532 return Ok(()); 533 } 534 let reader = self.operators_reader.as_ref().expect("operator reader"); 535 return Err(BinaryReaderError { 536 message: "Expected end of function marker", 537 offset: reader.original_position(), 538 }); 539 } 540 let reader = self.operators_reader.as_mut().expect("operator reader"); 541 let op = reader.read()?; 542 self.state = ParserState::CodeOperator(op); 543 Ok(()) 544 } 545 read_table_entry(&mut self) -> Result<()>546 fn read_table_entry(&mut self) -> Result<()> { 547 if self.section_entries_left == 0 { 548 return self.check_section_end(); 549 } 550 let table_entry = section_reader!(self, TableSectionReader).read()?; 551 self.state = ParserState::TableSectionEntry(table_entry); 552 self.section_entries_left -= 1; 553 Ok(()) 554 } 555 read_data_entry(&mut self) -> Result<()>556 fn read_data_entry(&mut self) -> Result<()> { 557 if self.section_entries_left == 0 { 558 return self.check_section_end(); 559 } 560 let Data { kind, data } = section_reader!(self, DataSectionReader).read()?; 561 match kind { 562 DataKind::Passive => { 563 self.state = ParserState::BeginPassiveDataSectionEntry; 564 } 565 DataKind::Active { 566 memory_index, 567 init_expr, 568 } => { 569 self.state = ParserState::BeginActiveDataSectionEntry(memory_index); 570 self.operators_reader = Some(init_expr.get_operators_reader()); 571 } 572 } 573 self.current_data_segment = Some(data); 574 self.section_entries_left -= 1; 575 Ok(()) 576 } 577 read_data_entry_body(&mut self) -> Result<()>578 fn read_data_entry_body(&mut self) -> Result<()> { 579 let size = self.current_data_segment.expect("data entry").len(); 580 self.state = ParserState::BeginDataSectionEntryBody(size as u32); 581 Ok(()) 582 } 583 read_naming<'b>( mut naming_reader: NamingReader<'a>, limit: usize, ) -> Result<Box<[Naming<'b>]>> where 'a: 'b,584 fn read_naming<'b>( 585 mut naming_reader: NamingReader<'a>, 586 limit: usize, 587 ) -> Result<Box<[Naming<'b>]>> 588 where 589 'a: 'b, 590 { 591 let count = naming_reader.get_count() as usize; 592 if count > limit { 593 return Err(BinaryReaderError { 594 message: "name map size is out of bound", 595 offset: naming_reader.original_position() - 1, 596 }); 597 } 598 let mut result = Vec::with_capacity(count); 599 for _ in 0..count { 600 result.push(naming_reader.read()?); 601 } 602 Ok(result.into_boxed_slice()) 603 } 604 read_name_entry(&mut self) -> Result<()>605 fn read_name_entry(&mut self) -> Result<()> { 606 if section_reader!(self, NameSectionReader).eof() { 607 return self.position_to_section_end(); 608 } 609 let entry = match section_reader!(self, NameSectionReader).read()? { 610 Name::Module(name) => NameEntry::Module(name.get_name()?), 611 Name::Function(func) => { 612 NameEntry::Function(Self::read_naming(func.get_map()?, MAX_WASM_FUNCTIONS)?) 613 } 614 Name::Local(locals) => { 615 let mut reader = locals.get_function_local_reader()?; 616 let funcs_len = reader.get_count() as usize; 617 if funcs_len > MAX_WASM_FUNCTIONS { 618 return Err(BinaryReaderError { 619 message: "function count is out of bounds", 620 offset: reader.original_position() - 1, 621 }); 622 } 623 let mut funcs: Vec<LocalName<'a>> = Vec::with_capacity(funcs_len); 624 for _ in 0..funcs_len { 625 let func = reader.read()?; 626 funcs.push(LocalName { 627 index: func.func_index, 628 locals: Self::read_naming(func.get_map()?, MAX_WASM_FUNCTION_LOCALS)?, 629 }); 630 } 631 NameEntry::Local(funcs.into_boxed_slice()) 632 } 633 }; 634 self.state = ParserState::NameSectionEntry(entry); 635 Ok(()) 636 } 637 read_source_mapping(&mut self) -> Result<()>638 fn read_source_mapping(&mut self) -> Result<()> { 639 let url = self 640 .current_section 641 .as_ref() 642 .expect("section") 643 .get_sourcemappingurl_section_content()?; 644 self.state = ParserState::SourceMappingURL(url); 645 Ok(()) 646 } 647 648 // See https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md read_reloc_header(&mut self) -> Result<()>649 fn read_reloc_header(&mut self) -> Result<()> { 650 let section_code = section_reader!(self, RelocSectionReader).get_section_code(); 651 self.state = ParserState::RelocSectionHeader(section_code); 652 Ok(()) 653 } 654 read_reloc_entry(&mut self) -> Result<()>655 fn read_reloc_entry(&mut self) -> Result<()> { 656 if self.section_entries_left == 0 { 657 return self.check_section_end(); 658 } 659 let Reloc { 660 ty, 661 offset, 662 index, 663 addend, 664 } = section_reader!(self, RelocSectionReader).read()?; 665 self.state = ParserState::RelocSectionEntry(RelocEntry { 666 ty, 667 offset, 668 index, 669 addend, 670 }); 671 self.section_entries_left -= 1; 672 Ok(()) 673 } 674 read_linking_entry(&mut self) -> Result<()>675 fn read_linking_entry(&mut self) -> Result<()> { 676 if self.section_entries_left == 0 { 677 return self.check_section_end(); 678 } 679 let entry = section_reader!(self, LinkingSectionReader).read()?; 680 self.state = ParserState::LinkingSectionEntry(entry); 681 self.section_entries_left -= 1; 682 Ok(()) 683 } 684 read_section_body(&mut self) -> Result<()>685 fn read_section_body(&mut self) -> Result<()> { 686 match self.state { 687 ParserState::BeginSection { 688 code: SectionCode::Type, 689 .. 690 } => { 691 start_section_reader!(self, TypeSectionReader, get_type_section_reader); 692 self.read_type_entry()?; 693 } 694 ParserState::BeginSection { 695 code: SectionCode::Import, 696 .. 697 } => { 698 start_section_reader!(self, ImportSectionReader, get_import_section_reader); 699 self.read_import_entry()?; 700 } 701 ParserState::BeginSection { 702 code: SectionCode::Function, 703 .. 704 } => { 705 start_section_reader!(self, FunctionSectionReader, get_function_section_reader); 706 self.read_function_entry()?; 707 } 708 ParserState::BeginSection { 709 code: SectionCode::Memory, 710 .. 711 } => { 712 start_section_reader!(self, MemorySectionReader, get_memory_section_reader); 713 self.read_memory_entry()?; 714 } 715 ParserState::BeginSection { 716 code: SectionCode::Global, 717 .. 718 } => { 719 start_section_reader!(self, GlobalSectionReader, get_global_section_reader); 720 self.read_global_entry()?; 721 } 722 ParserState::BeginSection { 723 code: SectionCode::Export, 724 .. 725 } => { 726 start_section_reader!(self, ExportSectionReader, get_export_section_reader); 727 self.read_export_entry()?; 728 } 729 ParserState::BeginSection { 730 code: SectionCode::Element, 731 .. 732 } => { 733 start_section_reader!(self, ElementSectionReader, get_element_section_reader); 734 self.read_element_entry()?; 735 } 736 ParserState::BeginSection { 737 code: SectionCode::Code, 738 .. 739 } => { 740 start_section_reader!(self, CodeSectionReader, get_code_section_reader); 741 self.read_function_body()?; 742 } 743 ParserState::BeginSection { 744 code: SectionCode::Table, 745 .. 746 } => { 747 start_section_reader!(self, TableSectionReader, get_table_section_reader); 748 self.read_table_entry()?; 749 } 750 ParserState::BeginSection { 751 code: SectionCode::Data, 752 .. 753 } => { 754 start_section_reader!(self, DataSectionReader, get_data_section_reader); 755 self.read_data_entry()?; 756 } 757 ParserState::BeginSection { 758 code: SectionCode::Start, 759 .. 760 } => { 761 let func_index = self 762 .current_section 763 .as_ref() 764 .expect("section") 765 .get_start_section_content()?; 766 self.state = ParserState::StartSectionEntry(func_index); 767 } 768 ParserState::BeginSection { 769 code: SectionCode::DataCount, 770 .. 771 } => { 772 let func_index = self 773 .current_section 774 .as_ref() 775 .expect("section") 776 .get_data_count_section_content()?; 777 self.state = ParserState::DataCountSectionEntry(func_index); 778 } 779 ParserState::BeginSection { 780 code: SectionCode::Custom { .. }, 781 .. 782 } => { 783 self.create_custom_section_binary_reader(); 784 self.read_section_body_bytes()?; 785 } 786 _ => unreachable!(), 787 } 788 Ok(()) 789 } 790 create_custom_section_binary_reader(&mut self)791 fn create_custom_section_binary_reader(&mut self) { 792 let reader = self 793 .current_section 794 .as_ref() 795 .expect("section") 796 .get_binary_reader(); 797 self.binary_reader = Some(reader); 798 } 799 read_custom_section_body(&mut self) -> Result<()>800 fn read_custom_section_body(&mut self) -> Result<()> { 801 match self.state { 802 ParserState::ReadingCustomSection(CustomSectionKind::Name) => { 803 let reader = self 804 .current_section 805 .as_ref() 806 .expect("section") 807 .get_name_section_reader()?; 808 self.section_reader = ParserSectionReader::NameSectionReader(reader); 809 self.read_name_entry()?; 810 } 811 ParserState::ReadingCustomSection(CustomSectionKind::SourceMappingURL) => { 812 self.read_source_mapping()?; 813 } 814 ParserState::ReadingCustomSection(CustomSectionKind::Reloc) => { 815 start_section_reader!(self, RelocSectionReader, get_reloc_section_reader); 816 self.read_reloc_header()?; 817 } 818 ParserState::ReadingCustomSection(CustomSectionKind::Linking) => { 819 start_section_reader!(self, LinkingSectionReader, get_linking_section_reader); 820 self.read_linking_entry()?; 821 } 822 ParserState::ReadingCustomSection(CustomSectionKind::Producers) 823 | ParserState::ReadingCustomSection(CustomSectionKind::Unknown) => { 824 self.create_custom_section_binary_reader(); 825 self.read_section_body_bytes()?; 826 } 827 _ => unreachable!(), 828 } 829 Ok(()) 830 } 831 position_to_section_end(&mut self) -> Result<()>832 fn position_to_section_end(&mut self) -> Result<()> { 833 self.current_section = None; 834 self.binary_reader = None; 835 self.state = ParserState::EndSection; 836 Ok(()) 837 } 838 check_section_end(&mut self) -> Result<()>839 fn check_section_end(&mut self) -> Result<()> { 840 match self.section_reader { 841 ParserSectionReader::CodeSectionReader(ref reader) => reader.ensure_end()?, 842 ParserSectionReader::DataSectionReader(ref reader) => reader.ensure_end()?, 843 ParserSectionReader::ElementSectionReader(ref reader) => reader.ensure_end()?, 844 ParserSectionReader::ExportSectionReader(ref reader) => reader.ensure_end()?, 845 ParserSectionReader::FunctionSectionReader(ref reader) => reader.ensure_end()?, 846 ParserSectionReader::GlobalSectionReader(ref reader) => reader.ensure_end()?, 847 ParserSectionReader::ImportSectionReader(ref reader) => reader.ensure_end()?, 848 ParserSectionReader::MemorySectionReader(ref reader) => reader.ensure_end()?, 849 ParserSectionReader::TableSectionReader(ref reader) => reader.ensure_end()?, 850 ParserSectionReader::TypeSectionReader(ref reader) => reader.ensure_end()?, 851 ParserSectionReader::LinkingSectionReader(ref reader) => reader.ensure_end()?, 852 ParserSectionReader::RelocSectionReader(ref reader) => reader.ensure_end()?, 853 _ => unreachable!(), 854 } 855 self.position_to_section_end() 856 } 857 read_section_body_bytes(&mut self) -> Result<()>858 fn read_section_body_bytes(&mut self) -> Result<()> { 859 if self.binary_reader.as_ref().expect("binary reader").eof() { 860 self.state = ParserState::EndSection; 861 self.binary_reader = None; 862 return Ok(()); 863 } 864 let binary_reader = self.binary_reader.as_mut().expect("binary reader"); 865 let to_read = if binary_reader.buffer.len() - binary_reader.position < MAX_DATA_CHUNK_SIZE { 866 binary_reader.buffer.len() - binary_reader.position 867 } else { 868 MAX_DATA_CHUNK_SIZE 869 }; 870 let bytes = binary_reader.read_bytes(to_read)?; 871 self.state = ParserState::SectionRawData(bytes); 872 Ok(()) 873 } 874 read_data_chunk(&mut self) -> Result<()>875 fn read_data_chunk(&mut self) -> Result<()> { 876 let data = self.current_data_segment.expect("data"); 877 if data.is_empty() { 878 self.state = ParserState::EndDataSectionEntryBody; 879 self.current_data_segment = None; 880 return Ok(()); 881 } 882 let to_read = if data.len() > MAX_DATA_CHUNK_SIZE { 883 MAX_DATA_CHUNK_SIZE 884 } else { 885 data.len() 886 }; 887 let (head, tail) = data.split_at(to_read); 888 self.current_data_segment = Some(tail); 889 self.state = ParserState::DataSectionEntryBodyChunk(head); 890 Ok(()) 891 } 892 read_next_section(&mut self) -> Result<()>893 fn read_next_section(&mut self) -> Result<()> { 894 if self.module_reader.as_ref().expect("module_reader").eof() { 895 self.current_section = None; 896 self.state = ParserState::EndWasm; 897 } else { 898 self.read_section_header()?; 899 } 900 Ok(()) 901 } 902 read_wrapped(&mut self) -> Result<()>903 fn read_wrapped(&mut self) -> Result<()> { 904 match self.state { 905 ParserState::EndWasm => panic!("Parser in end state"), 906 ParserState::Error(_) => panic!("Parser in error state"), 907 ParserState::Initial => self.read_module()?, 908 ParserState::BeginWasm { .. } | ParserState::EndSection => self.read_next_section()?, 909 ParserState::BeginSection { .. } => self.read_section_body()?, 910 ParserState::SkippingSection => { 911 self.position_to_section_end()?; 912 self.read_next_section()?; 913 } 914 ParserState::TypeSectionEntry(_) => self.read_type_entry()?, 915 ParserState::ImportSectionEntry { .. } => self.read_import_entry()?, 916 ParserState::FunctionSectionEntry(_) => self.read_function_entry()?, 917 ParserState::MemorySectionEntry(_) => self.read_memory_entry()?, 918 ParserState::TableSectionEntry(_) => self.read_table_entry()?, 919 ParserState::ExportSectionEntry { .. } => self.read_export_entry()?, 920 ParserState::BeginGlobalSectionEntry(_) => { 921 self.read_init_expression_body(InitExpressionContinuationSection::Global) 922 } 923 ParserState::EndGlobalSectionEntry => self.read_global_entry()?, 924 ParserState::BeginElementSectionEntry { 925 table: ElemSectionEntryTable::Active(_), 926 .. 927 } => self.read_init_expression_body(InitExpressionContinuationSection::Element), 928 ParserState::BeginElementSectionEntry { .. } => self.read_element_entry_body()?, 929 ParserState::BeginInitExpressionBody | ParserState::InitExpressionOperator(_) => { 930 self.read_init_expression_operator()? 931 } 932 ParserState::BeginPassiveDataSectionEntry => self.read_data_entry_body()?, 933 ParserState::BeginActiveDataSectionEntry(_) => { 934 self.read_init_expression_body(InitExpressionContinuationSection::Data) 935 } 936 ParserState::EndInitExpressionBody => { 937 match self.init_expr_continuation { 938 Some(InitExpressionContinuationSection::Global) => { 939 self.state = ParserState::EndGlobalSectionEntry 940 } 941 Some(InitExpressionContinuationSection::Element) => { 942 self.read_element_entry_body()? 943 } 944 Some(InitExpressionContinuationSection::Data) => self.read_data_entry_body()?, 945 None => unreachable!(), 946 } 947 self.init_expr_continuation = None; 948 } 949 ParserState::BeginFunctionBody { .. } => self.read_function_body_locals()?, 950 ParserState::FunctionBodyLocals { .. } | ParserState::CodeOperator(_) => { 951 self.read_code_operator()? 952 } 953 ParserState::EndFunctionBody => self.read_function_body()?, 954 ParserState::SkippingFunctionBody => { 955 self.current_function_body = None; 956 self.read_function_body()?; 957 } 958 ParserState::EndDataSectionEntry => self.read_data_entry()?, 959 ParserState::BeginDataSectionEntryBody(_) 960 | ParserState::DataSectionEntryBodyChunk(_) => self.read_data_chunk()?, 961 ParserState::EndDataSectionEntryBody => { 962 self.state = ParserState::EndDataSectionEntry; 963 } 964 ParserState::ElementSectionEntryBody(_) => { 965 self.state = ParserState::EndElementSectionEntry; 966 } 967 ParserState::EndElementSectionEntry => self.read_element_entry()?, 968 ParserState::StartSectionEntry(_) => self.position_to_section_end()?, 969 ParserState::DataCountSectionEntry(_) => self.position_to_section_end()?, 970 ParserState::NameSectionEntry(_) => self.read_name_entry()?, 971 ParserState::SourceMappingURL(_) => self.position_to_section_end()?, 972 ParserState::RelocSectionHeader(_) => { 973 let mut reader = self 974 .current_section 975 .as_ref() 976 .expect("section") 977 .get_binary_reader(); 978 self.section_entries_left = reader.read_var_u32()?; 979 self.binary_reader = Some(reader); 980 self.read_reloc_entry()?; 981 } 982 ParserState::RelocSectionEntry(_) => self.read_reloc_entry()?, 983 ParserState::LinkingSectionEntry(_) => self.read_linking_entry()?, 984 ParserState::ReadingCustomSection(_) => self.read_custom_section_body()?, 985 ParserState::ReadingSectionRawData | ParserState::SectionRawData(_) => { 986 self.read_section_body_bytes()? 987 } 988 } 989 Ok(()) 990 } 991 skip_section(&mut self)992 fn skip_section(&mut self) { 993 match self.state { 994 ParserState::Initial 995 | ParserState::EndWasm 996 | ParserState::Error(_) 997 | ParserState::BeginWasm { .. } 998 | ParserState::EndSection => panic!("Invalid reader state during skip section"), 999 _ => self.state = ParserState::SkippingSection, 1000 } 1001 } 1002 skip_function_body(&mut self)1003 fn skip_function_body(&mut self) { 1004 match self.state { 1005 ParserState::BeginFunctionBody { .. } 1006 | ParserState::FunctionBodyLocals { .. } 1007 | ParserState::CodeOperator(_) => self.state = ParserState::SkippingFunctionBody, 1008 _ => panic!("Invalid reader state during skip function body"), 1009 } 1010 } 1011 read_custom_section(&mut self)1012 fn read_custom_section(&mut self) { 1013 match self.state { 1014 ParserState::BeginSection { 1015 code: SectionCode::Custom { kind, .. }, 1016 .. 1017 } => { 1018 self.state = ParserState::ReadingCustomSection(kind); 1019 } 1020 _ => panic!("Invalid reader state during reading custom section"), 1021 } 1022 } 1023 read_raw_section_data(&mut self)1024 fn read_raw_section_data(&mut self) { 1025 match self.state { 1026 ParserState::BeginSection { .. } => { 1027 self.binary_reader = Some( 1028 self.current_section 1029 .as_ref() 1030 .expect("section") 1031 .get_binary_reader(), 1032 ); 1033 self.state = ParserState::ReadingSectionRawData; 1034 } 1035 _ => panic!("Invalid reader state during reading raw section data"), 1036 } 1037 } 1038 } 1039 1040 impl<'a> WasmDecoder<'a> for Parser<'a> { 1041 /// Reads next record from the WebAssembly binary data. The methods returns 1042 /// reference to current state of the parser. See `ParserState` num. 1043 /// 1044 /// # Examples 1045 /// ``` 1046 /// # let data: &[u8] = &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 1047 /// # 0x01, 0x4, 0x01, 0x60, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 1048 /// # 0x0a, 0x05, 0x01, 0x03, 0x00, 0x01, 0x0b]; 1049 /// use wasmparser::WasmDecoder; 1050 /// let mut parser = wasmparser::Parser::new(data); 1051 /// { 1052 /// let state = parser.read(); 1053 /// println!("First state {:?}", state); 1054 /// } 1055 /// { 1056 /// let state = parser.read(); 1057 /// println!("Second state {:?}", state); 1058 /// } 1059 /// ``` read(&mut self) -> &ParserState<'a>1060 fn read(&mut self) -> &ParserState<'a> { 1061 let result = self.read_wrapped(); 1062 if result.is_err() { 1063 self.state = ParserState::Error(result.err().unwrap()); 1064 } 1065 &self.state 1066 } 1067 push_input(&mut self, input: ParserInput)1068 fn push_input(&mut self, input: ParserInput) { 1069 match input { 1070 ParserInput::Default => (), 1071 ParserInput::SkipSection => self.skip_section(), 1072 ParserInput::SkipFunctionBody => self.skip_function_body(), 1073 ParserInput::ReadCustomSection => self.read_custom_section(), 1074 ParserInput::ReadSectionRawData => self.read_raw_section_data(), 1075 } 1076 } 1077 1078 /// Creates a BinaryReader when current state is ParserState::BeginSection 1079 /// or ParserState::BeginFunctionBody. 1080 /// 1081 /// # Examples 1082 /// ``` 1083 /// # let data = &[0x0, 0x61, 0x73, 0x6d, 0x1, 0x0, 0x0, 0x0, 0x1, 0x84, 1084 /// # 0x80, 0x80, 0x80, 0x0, 0x1, 0x60, 0x0, 0x0, 0x3, 0x83, 1085 /// # 0x80, 0x80, 0x80, 0x0, 0x2, 0x0, 0x0, 0x6, 0x81, 0x80, 1086 /// # 0x80, 0x80, 0x0, 0x0, 0xa, 0x91, 0x80, 0x80, 0x80, 0x0, 1087 /// # 0x2, 0x83, 0x80, 0x80, 0x80, 0x0, 0x0, 0x1, 0xb, 0x83, 1088 /// # 0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0xb]; 1089 /// use wasmparser::{WasmDecoder, Parser, ParserState}; 1090 /// let mut parser = Parser::new(data); 1091 /// let mut types = Vec::new(); 1092 /// let mut function_types = Vec::new(); 1093 /// let mut function_readers = Vec::new(); 1094 /// loop { 1095 /// match parser.read() { 1096 /// ParserState::Error(_) | 1097 /// ParserState::EndWasm => break, 1098 /// ParserState::TypeSectionEntry(ty) => { 1099 /// types.push(ty.clone()); 1100 /// } 1101 /// ParserState::FunctionSectionEntry(id) => { 1102 /// function_types.push(id.clone()); 1103 /// } 1104 /// ParserState::BeginFunctionBody {..} => { 1105 /// let reader = parser.create_binary_reader(); 1106 /// function_readers.push(reader); 1107 /// } 1108 /// _ => continue 1109 /// } 1110 /// } 1111 /// for (i, reader) in function_readers.iter_mut().enumerate() { 1112 /// // Access the function type through the types table. 1113 /// let ty = &types[function_types[i] as usize]; 1114 /// println!("\nFunction {} of type {:?}", i, ty); 1115 /// // Read the local declarations required by the function body. 1116 /// let local_decls_len = reader.read_local_count().unwrap(); 1117 /// let mut local_decls = Vec::with_capacity(local_decls_len); 1118 /// let mut local_count = ty.params.len(); 1119 /// for _ in 0..local_decls_len { 1120 /// let local_decl = reader.read_local_decl(&mut local_count).unwrap(); 1121 /// local_decls.push(local_decl); 1122 /// } 1123 /// println!("Function locals: vars {:?}; total {} ", local_decls, local_count); 1124 /// // Read the operations of the function body. 1125 /// while let Ok(ref op) = reader.read_operator() { 1126 /// println!(" {:?}", op); 1127 /// } 1128 /// } 1129 /// ``` create_binary_reader<'b>(&mut self) -> BinaryReader<'b> where 'a: 'b,1130 fn create_binary_reader<'b>(&mut self) -> BinaryReader<'b> 1131 where 1132 'a: 'b, 1133 { 1134 match self.state { 1135 ParserState::BeginSection { .. } => self 1136 .current_section 1137 .as_ref() 1138 .expect("section") 1139 .get_binary_reader(), 1140 ParserState::BeginFunctionBody { .. } | ParserState::FunctionBodyLocals { .. } => self 1141 .current_function_body 1142 .as_ref() 1143 .expect("function body") 1144 .get_binary_reader(), 1145 _ => panic!("Invalid reader state during get binary reader operation"), 1146 } 1147 } 1148 1149 /// Reads next record from the WebAssembly binary data. It also allows to 1150 /// control how parser will treat the next record(s). The method accepts the 1151 /// `ParserInput` parameter that allows e.g. to skip section or function 1152 /// operators. The methods returns reference to current state of the parser. 1153 /// 1154 /// # Examples 1155 /// ``` 1156 /// # let data: &[u8] = &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 1157 /// # 0x01, 0x4, 0x01, 0x60, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 1158 /// # 0x0a, 0x05, 0x01, 0x03, 0x00, 0x01, 0x0b]; 1159 /// use wasmparser::WasmDecoder; 1160 /// let mut parser = wasmparser::Parser::new(data); 1161 /// let mut next_input = wasmparser::ParserInput::Default; 1162 /// loop { 1163 /// let state = parser.read_with_input(next_input); 1164 /// match *state { 1165 /// wasmparser::ParserState::EndWasm => break, 1166 /// wasmparser::ParserState::BeginWasm { .. } | 1167 /// wasmparser::ParserState::EndSection => 1168 /// next_input = wasmparser::ParserInput::Default, 1169 /// wasmparser::ParserState::BeginSection { ref code, .. } => { 1170 /// println!("Found section: {:?}", code); 1171 /// next_input = wasmparser::ParserInput::SkipSection; 1172 /// }, 1173 /// _ => unreachable!() 1174 /// } 1175 /// } 1176 /// ``` read_with_input(&mut self, input: ParserInput) -> &ParserState<'a>1177 fn read_with_input(&mut self, input: ParserInput) -> &ParserState<'a> { 1178 self.push_input(input); 1179 self.read() 1180 } 1181 last_state(&self) -> &ParserState<'a>1182 fn last_state(&self) -> &ParserState<'a> { 1183 &self.state 1184 } 1185 } 1186