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