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