1 /* Copyright 2018 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 
16 use crate::limits::*;
17 use crate::ResizableLimits64;
18 use crate::WasmModuleResources;
19 use crate::{Alias, ExternalKind, Import, ImportSectionEntryType};
20 use crate::{BinaryReaderError, EventType, GlobalType, MemoryType, Range, Result, TableType, Type};
21 use crate::{DataKind, ElementItem, ElementKind, InitExpr, Instance, Operator};
22 use crate::{FuncType, ResizableLimits, SectionReader, SectionWithLimitedItems};
23 use crate::{FunctionBody, Parser, Payload};
24 use std::collections::{HashMap, HashSet};
25 use std::mem;
26 use std::sync::Arc;
27 
28 /// Test whether the given buffer contains a valid WebAssembly module,
29 /// analogous to [`WebAssembly.validate`][js] in the JS API.
30 ///
31 /// This functions requires the wasm module is entirely resident in memory and
32 /// is specified by `bytes`. Additionally this validates the given bytes with
33 /// the default set of WebAssembly features implemented by `wasmparser`.
34 ///
35 /// For more fine-tuned control over validation it's recommended to review the
36 /// documentation of [`Validator`].
37 ///
38 /// [js]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/validate
validate(bytes: &[u8]) -> Result<()>39 pub fn validate(bytes: &[u8]) -> Result<()> {
40     Validator::new().validate_all(bytes)
41 }
42 
43 #[test]
test_validate()44 fn test_validate() {
45     assert!(validate(&[0x0, 0x61, 0x73, 0x6d, 0x1, 0x0, 0x0, 0x0]).is_ok());
46     assert!(validate(&[0x0, 0x61, 0x73, 0x6d, 0x2, 0x0, 0x0, 0x0]).is_err());
47 }
48 
49 mod func;
50 pub use func::FuncValidator;
51 
52 /// Validator for a WebAssembly binary module.
53 ///
54 /// This structure encapsulates state necessary to validate a WebAssembly
55 /// binary. This implements validation as defined by the [core
56 /// specification][core]. A `Validator` is designed, like
57 /// [`Parser`], to accept incremental input over time.
58 /// Additionally a `Validator` is also designed for parallel validation of
59 /// functions as they are received.
60 ///
61 /// It's expected that you'll be using a [`Parser`] in tandem with a
62 /// `Validator`. As each [`Payload`](crate::Payload) is received from a
63 /// [`Parser`] you'll pass it into a `Validator` to test the validity of the
64 /// payload. Note that all payloads received from a [`Parser`] are expected to
65 /// be passed to a [`Validator`]. For example if you receive
66 /// [`Payload::TypeSection`](crate::Payload) you'll call
67 /// [`Validator::type_section`] to validate this.
68 ///
69 /// The design of [`Validator`] is intended that you'll interleave, in your own
70 /// application's processing, calls to validation. Each variant, after it's
71 /// received, will be validated and then your application would proceed as
72 /// usual. At all times, however, you'll have access to the [`Validator`] and
73 /// the validation context up to that point. This enables applications to check
74 /// the types of functions and learn how many globals there are, for example.
75 ///
76 /// [core]: https://webassembly.github.io/spec/core/valid/index.html
77 #[derive(Default)]
78 pub struct Validator {
79     /// The current module that we're validating.
80     cur: Module,
81 
82     /// With module linking this is the list of parent modules to this module,
83     /// sorted from oldest to most recent.
84     parents: Vec<Module>,
85 
86     /// This is the global list of all types shared by this validator which all
87     /// modules will reference.
88     types: SnapshotList<TypeDef>,
89 
90     /// Enabled WebAssembly feature flags, dictating what's valid and what
91     /// isn't.
92     features: WasmFeatures,
93 
94     /// The current byte-level offset in the wasm binary. This is updated to
95     /// produce error messages in `create_error`.
96     offset: usize,
97 }
98 
99 #[derive(Default)]
100 struct Module {
101     /// Internal state that is incrementally built-up for the module being
102     /// validate. This houses type information for all wasm items, like
103     /// functions. Note that this starts out as a solely owned `Arc<T>` so we can
104     /// get mutable access, but after we get to the code section this is never
105     /// mutated to we can clone it cheaply and hand it to sub-validators.
106     state: arc::MaybeOwned<ModuleState>,
107 
108     /// Where we are, order-wise, in the wasm binary.
109     order: Order,
110 
111     /// The number of data segments we ended up finding in this module, or 0 if
112     /// they either weren't present or none were found.
113     data_found: u32,
114 
115     /// The number of functions we expect to be defined in the code section, or
116     /// basically the length of the function section if it was found. The next
117     /// index is where we are, in the code section index space, for the next
118     /// entry in the code section (used to figure out what type is next for the
119     /// function being validated).
120     expected_code_bodies: Option<u32>,
121     code_section_index: usize,
122 }
123 
124 #[derive(Default)]
125 struct ModuleState {
126     /// This is a snapshot of `validator.types` when it is created. This is not
127     /// initially filled in but once everything in a module except the code
128     /// section has been parsed then this will be filled in.
129     ///
130     /// Note that this `ModuleState` will be a separately-owned structure living
131     /// in each function's validator. This is done to allow parallel validation
132     /// of functions while the main module is possibly still being parsed.
133     all_types: Option<Arc<SnapshotList<TypeDef>>>,
134 
135     types: Vec<usize>, // pointer into `validator.types`
136     tables: Vec<TableType>,
137     memories: Vec<MemoryType>,
138     globals: Vec<GlobalType>,
139     element_types: Vec<Type>,
140     data_count: Option<u32>,
141     code_type_indexes: Vec<u32>, // pointer into `types` above
142     func_types: Vec<usize>,      // pointer into `validator.types`
143     events: Vec<usize>,          // pointer into `validator.types`
144     submodules: Vec<usize>,      // pointer into `validator.types`
145     instances: Vec<usize>,       // pointer into `validator.types`
146     function_references: HashSet<u32>,
147 
148     // This is populated when we hit the export section
149     exports: NameSet,
150 
151     // This is populated as we visit import sections, which might be
152     // incrementally in the face of a module-linking-using module.
153     imports: NameSet,
154 }
155 
156 /// Flags for features that are enabled for validation.
157 #[derive(Hash, Debug, Copy, Clone)]
158 pub struct WasmFeatures {
159     /// The WebAssembly reference types proposal (enabled by default)
160     pub reference_types: bool,
161     /// The WebAssembly multi-value proposal (enabled by default)
162     pub multi_value: bool,
163     /// The WebAssembly bulk memory operations proposal (enabled by default)
164     pub bulk_memory: bool,
165     /// The WebAssembly module linking proposal
166     pub module_linking: bool,
167     /// The WebAssembly SIMD proposal
168     pub simd: bool,
169     /// The WebAssembly threads proposal
170     pub threads: bool,
171     /// The WebAssembly tail-call proposal
172     pub tail_call: bool,
173     /// Whether or not only deterministic instructions are allowed
174     pub deterministic_only: bool,
175     /// The WebAssembly multi memory proposal
176     pub multi_memory: bool,
177     /// The WebAssembly exception handling proposal
178     pub exceptions: bool,
179     /// The WebAssembly memory64 proposal
180     pub memory64: bool,
181 }
182 
183 impl Default for WasmFeatures {
default() -> WasmFeatures184     fn default() -> WasmFeatures {
185         WasmFeatures {
186             // off-by-default features
187             module_linking: false,
188             simd: false,
189             threads: false,
190             tail_call: false,
191             multi_memory: false,
192             exceptions: false,
193             memory64: false,
194             deterministic_only: cfg!(feature = "deterministic"),
195 
196             // on-by-default features
197             bulk_memory: true,
198             multi_value: true,
199             reference_types: true,
200         }
201     }
202 }
203 
204 #[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug)]
205 enum Order {
206     Initial,
207     AfterHeader,
208     Type,
209     Import,
210     ModuleLinkingHeader,
211     Function,
212     Table,
213     Memory,
214     Event,
215     Global,
216     Export,
217     Start,
218     Element,
219     DataCount,
220     Code,
221     Data,
222 }
223 
224 impl Default for Order {
default() -> Order225     fn default() -> Order {
226         Order::Initial
227     }
228 }
229 
230 enum TypeDef {
231     Func(FuncType),
232     Module(ModuleType),
233     Instance(InstanceType),
234 }
235 
236 impl TypeDef {
unwrap_func(&self) -> &FuncType237     fn unwrap_func(&self) -> &FuncType {
238         match self {
239             TypeDef::Func(f) => f,
240             _ => panic!("not a function type"),
241         }
242     }
243 
unwrap_module(&self) -> &ModuleType244     fn unwrap_module(&self) -> &ModuleType {
245         match self {
246             TypeDef::Module(f) => f,
247             _ => panic!("not a module type"),
248         }
249     }
250 
unwrap_instance(&self) -> &InstanceType251     fn unwrap_instance(&self) -> &InstanceType {
252         match self {
253             TypeDef::Instance(f) => f,
254             _ => panic!("not an instance type"),
255         }
256     }
257 }
258 
259 struct ModuleType {
260     type_size: u32,
261     imports: HashMap<String, EntityType>,
262     exports: HashMap<String, EntityType>,
263 }
264 
265 #[derive(Default)]
266 struct InstanceType {
267     type_size: u32,
268     exports: HashMap<String, EntityType>,
269 }
270 
271 #[derive(Clone)]
272 enum EntityType {
273     Global(GlobalType),
274     Memory(MemoryType),
275     Table(TableType),
276     Func(usize),     // pointer into `validator.types`
277     Module(usize),   // pointer into `validator.types`
278     Instance(usize), // pointer into `validator.types`
279     Event(usize),    // pointer into `validator.types`
280 }
281 
282 /// Possible return values from [`Validator::payload`].
283 pub enum ValidPayload<'a> {
284     /// The payload validated, no further action need be taken.
285     Ok,
286     /// The payload validated, but it started a nested module.
287     ///
288     /// This result indicates that the specified parser should be used instead
289     /// of the currently-used parser until this returned one ends.
290     Submodule(Parser),
291     /// A function was found to be validate.
292     Func(FuncValidator<ValidatorResources>, FunctionBody<'a>),
293 }
294 
295 impl Validator {
296     /// Creates a new [`Validator`] ready to validate a WebAssembly module.
297     ///
298     /// The new validator will receive payloads parsed from
299     /// [`Parser`], and expects the first payload received to be
300     /// the version header from the parser.
new() -> Validator301     pub fn new() -> Validator {
302         Validator::default()
303     }
304 
305     /// Configures the enabled WebAssembly features for this `Validator`.
wasm_features(&mut self, features: WasmFeatures) -> &mut Validator306     pub fn wasm_features(&mut self, features: WasmFeatures) -> &mut Validator {
307         self.features = features;
308         self
309     }
310 
311     /// Validates an entire in-memory module with this validator.
312     ///
313     /// This function will internally create a [`Parser`] to parse the `bytes`
314     /// provided. The entire wasm module specified by `bytes` will be parsed and
315     /// validated. Parse and validation errors will be returned through
316     /// `Err(_)`, and otherwise a successful validation means `Ok(())` is
317     /// returned.
validate_all(&mut self, bytes: &[u8]) -> Result<()>318     pub fn validate_all(&mut self, bytes: &[u8]) -> Result<()> {
319         let mut functions_to_validate = Vec::new();
320         for payload in Parser::new(0).parse_all(bytes) {
321             if let ValidPayload::Func(a, b) = self.payload(&payload?)? {
322                 functions_to_validate.push((a, b));
323             }
324         }
325 
326         for (mut validator, body) in functions_to_validate {
327             validator.validate(&body)?;
328         }
329         Ok(())
330     }
331 
332     /// Convenience function to validate a single [`Payload`].
333     ///
334     /// This function is intended to be used as a convenience. It will
335     /// internally perform any validation necessary to validate the [`Payload`]
336     /// provided. The convenience part is that you're likely already going to
337     /// be matching on [`Payload`] in your application, at which point it's more
338     /// appropriate to call the individual methods on [`Validator`] per-variant
339     /// in [`Payload`], such as [`Validator::type_section`].
340     ///
341     /// This function returns a [`ValidPayload`] variant on success, indicating
342     /// one of a few possible actions that need to be taken after a payload is
343     /// validated. For example function contents are not validated here, they're
344     /// returned through [`ValidPayload`] for validation by the caller.
payload<'a>(&mut self, payload: &Payload<'a>) -> Result<ValidPayload<'a>>345     pub fn payload<'a>(&mut self, payload: &Payload<'a>) -> Result<ValidPayload<'a>> {
346         use crate::Payload::*;
347         match payload {
348             Version { num, range } => self.version(*num, range)?,
349             TypeSection(s) => self.type_section(s)?,
350             ImportSection(s) => self.import_section(s)?,
351             AliasSection(s) => self.alias_section(s)?,
352             InstanceSection(s) => self.instance_section(s)?,
353             FunctionSection(s) => self.function_section(s)?,
354             TableSection(s) => self.table_section(s)?,
355             MemorySection(s) => self.memory_section(s)?,
356             EventSection(s) => self.event_section(s)?,
357             GlobalSection(s) => self.global_section(s)?,
358             ExportSection(s) => self.export_section(s)?,
359             StartSection { func, range } => self.start_section(*func, range)?,
360             ElementSection(s) => self.element_section(s)?,
361             DataCountSection { count, range } => self.data_count_section(*count, range)?,
362             CodeSectionStart {
363                 count,
364                 range,
365                 size: _,
366             } => self.code_section_start(*count, range)?,
367             CodeSectionEntry(body) => {
368                 let func_validator = self.code_section_entry()?;
369                 return Ok(ValidPayload::Func(func_validator, body.clone()));
370             }
371             ModuleSectionStart {
372                 count,
373                 range,
374                 size: _,
375             } => self.module_section_start(*count, range)?,
376             DataSection(s) => self.data_section(s)?,
377             End => self.end()?,
378 
379             CustomSection { .. } => {} // no validation for custom sections
380             UnknownSection { id, range, .. } => self.unknown_section(*id, range)?,
381             ModuleSectionEntry { parser, .. } => {
382                 self.module_section_entry();
383                 return Ok(ValidPayload::Submodule(parser.clone()));
384             }
385         }
386         Ok(ValidPayload::Ok)
387     }
388 
create_error<T>(&self, msg: impl Into<String>) -> Result<T>389     fn create_error<T>(&self, msg: impl Into<String>) -> Result<T> {
390         Err(BinaryReaderError::new(msg.into(), self.offset))
391     }
392 
393     /// Validates [`Payload::Version`](crate::Payload)
version(&mut self, num: u32, range: &Range) -> Result<()>394     pub fn version(&mut self, num: u32, range: &Range) -> Result<()> {
395         self.offset = range.start;
396         if self.cur.order != Order::Initial {
397             return self.create_error("wasm version header out of order");
398         }
399         self.cur.order = Order::AfterHeader;
400         if num != 1 {
401             return self.create_error("bad wasm file version");
402         }
403         Ok(())
404     }
405 
update_order(&mut self, order: Order) -> Result<()>406     fn update_order(&mut self, order: Order) -> Result<()> {
407         let prev = mem::replace(&mut self.cur.order, order);
408         // If the previous section came before this section, then that's always
409         // valid.
410         if prev < order {
411             return Ok(());
412         }
413         // ... otherwise if this is a repeated section then only the "module
414         // linking header" is allows to have repeats
415         if prev == self.cur.order && self.cur.order == Order::ModuleLinkingHeader {
416             return Ok(());
417         }
418         self.create_error("section out of order")
419     }
420 
header_order(&mut self, order: Order) -> Order421     fn header_order(&mut self, order: Order) -> Order {
422         if self.features.module_linking {
423             Order::ModuleLinkingHeader
424         } else {
425             order
426         }
427     }
428 
get_type(&self, idx: u32) -> Result<&TypeDef>429     fn get_type(&self, idx: u32) -> Result<&TypeDef> {
430         match self.cur.state.types.get(idx as usize) {
431             Some(t) => Ok(&self.types[*t]),
432             None => self.create_error(format!("unknown type {}: type index out of bounds", idx)),
433         }
434     }
435 
get_table(&self, idx: u32) -> Result<&TableType>436     fn get_table(&self, idx: u32) -> Result<&TableType> {
437         match self.cur.state.tables.get(idx as usize) {
438             Some(t) => Ok(t),
439             None => self.create_error(format!("unknown table {}: table index out of bounds", idx)),
440         }
441     }
442 
get_memory(&self, idx: u32) -> Result<&MemoryType>443     fn get_memory(&self, idx: u32) -> Result<&MemoryType> {
444         match self.cur.state.memories.get(idx as usize) {
445             Some(t) => Ok(t),
446             None => self.create_error(format!(
447                 "unknown memory {}: memory index out of bounds",
448                 idx,
449             )),
450         }
451     }
452 
get_global(&self, idx: u32) -> Result<&GlobalType>453     fn get_global(&self, idx: u32) -> Result<&GlobalType> {
454         match self.cur.state.globals.get(idx as usize) {
455             Some(t) => Ok(t),
456             None => self.create_error(format!(
457                 "unknown global {}: global index out of bounds",
458                 idx,
459             )),
460         }
461     }
462 
get_func_type(&self, func_idx: u32) -> Result<&FuncType>463     fn get_func_type(&self, func_idx: u32) -> Result<&FuncType> {
464         match self.cur.state.func_types.get(func_idx as usize) {
465             Some(t) => Ok(self.types[*t].unwrap_func()),
466             None => self.create_error(format!(
467                 "unknown function {}: func index out of bounds",
468                 func_idx,
469             )),
470         }
471     }
472 
get_module_type(&self, module_idx: u32) -> Result<&ModuleType>473     fn get_module_type(&self, module_idx: u32) -> Result<&ModuleType> {
474         match self.cur.state.submodules.get(module_idx as usize) {
475             Some(t) => Ok(self.types[*t].unwrap_module()),
476             None => self.create_error("unknown module: module index out of bounds"),
477         }
478     }
479 
get_instance_type(&self, instance_idx: u32) -> Result<&InstanceType>480     fn get_instance_type(&self, instance_idx: u32) -> Result<&InstanceType> {
481         match self.cur.state.instances.get(instance_idx as usize) {
482             Some(t) => Ok(self.types[*t].unwrap_instance()),
483             None => self.create_error("unknown instance: instance index out of bounds"),
484         }
485     }
486 
func_type_at(&self, type_index: u32) -> Result<&FuncType>487     fn func_type_at(&self, type_index: u32) -> Result<&FuncType> {
488         let def = self.get_type(type_index)?;
489         match def {
490             TypeDef::Func(item) => Ok(item),
491             _ => self.create_error("type index is not a function"),
492         }
493     }
494 
module_type_at(&self, type_index: u32) -> Result<&ModuleType>495     fn module_type_at(&self, type_index: u32) -> Result<&ModuleType> {
496         if !self.features.module_linking {
497             return self.create_error("module linking proposal not enabled");
498         }
499         let ty = self.get_type(type_index)?;
500         match ty {
501             TypeDef::Module(item) => Ok(item),
502             _ => self.create_error("type index is not a module"),
503         }
504     }
505 
instance_type_at(&self, type_index: u32) -> Result<&InstanceType>506     fn instance_type_at(&self, type_index: u32) -> Result<&InstanceType> {
507         if !self.features.module_linking {
508             return self.create_error("module linking proposal not enabled");
509         }
510         let ty = self.get_type(type_index)?;
511         match ty {
512             TypeDef::Instance(item) => Ok(item),
513             _ => self.create_error("type index is not an instance"),
514         }
515     }
516 
check_max(&self, cur_len: usize, amt_added: u32, max: usize, desc: &str) -> Result<()>517     fn check_max(&self, cur_len: usize, amt_added: u32, max: usize, desc: &str) -> Result<()> {
518         let overflow = max
519             .checked_sub(cur_len)
520             .and_then(|amt| amt.checked_sub(amt_added as usize))
521             .is_none();
522         if overflow {
523             return if max == 1 {
524                 self.create_error(format!("multiple {}", desc))
525             } else {
526                 self.create_error(format!("{} count is out of bounds", desc))
527             };
528         }
529         Ok(())
530     }
531 
section<T>( &mut self, order: Order, section: &T, mut validate_item: impl FnMut(&mut Self, T::Item) -> Result<()>, ) -> Result<()> where T: SectionReader + Clone + SectionWithLimitedItems,532     fn section<T>(
533         &mut self,
534         order: Order,
535         section: &T,
536         mut validate_item: impl FnMut(&mut Self, T::Item) -> Result<()>,
537     ) -> Result<()>
538     where
539         T: SectionReader + Clone + SectionWithLimitedItems,
540     {
541         self.offset = section.range().start;
542         self.update_order(order)?;
543 
544         let mut section = section.clone();
545         for _ in 0..section.get_count() {
546             self.offset = section.original_position();
547             let item = section.read()?;
548             validate_item(self, item)?;
549         }
550         self.offset = section.range().end;
551         section.ensure_end()?;
552         Ok(())
553     }
554 
555     /// Validates [`Payload::TypeSection`](crate::Payload)
type_section(&mut self, section: &crate::TypeSectionReader<'_>) -> Result<()>556     pub fn type_section(&mut self, section: &crate::TypeSectionReader<'_>) -> Result<()> {
557         let order = self.header_order(Order::Type);
558         self.check_max(
559             self.cur.state.types.len(),
560             section.get_count(),
561             MAX_WASM_TYPES,
562             "types",
563         )?;
564         self.section(order, section, |me, item| me.type_def(item))
565     }
566 
type_def(&mut self, def: crate::TypeDef<'_>) -> Result<()>567     fn type_def(&mut self, def: crate::TypeDef<'_>) -> Result<()> {
568         let def = match def {
569             crate::TypeDef::Func(t) => {
570                 for ty in t.params.iter().chain(t.returns.iter()) {
571                     self.value_type(*ty)?;
572                 }
573                 if t.returns.len() > 1 && !self.features.multi_value {
574                     return self
575                         .create_error("invalid result arity: func type returns multiple values");
576                 }
577                 TypeDef::Func(t)
578             }
579             crate::TypeDef::Module(t) => {
580                 if !self.features.module_linking {
581                     return self.create_error("module linking proposal not enabled");
582                 }
583                 let mut imports = NameSet::default();
584                 for i in t.imports.iter() {
585                     let ty = self.import_entry_type(&i.ty)?;
586                     imports.push(
587                         self.offset,
588                         i.module,
589                         i.field,
590                         ty,
591                         &mut self.types,
592                         "import",
593                     )?;
594                 }
595 
596                 let mut exports = NameSet::default();
597                 for e in t.exports.iter() {
598                     let ty = self.import_entry_type(&e.ty)?;
599                     exports.push(self.offset, e.name, None, ty, &mut self.types, "export")?;
600                 }
601                 TypeDef::Module(ModuleType {
602                     type_size: combine_type_sizes(
603                         self.offset,
604                         imports.type_size,
605                         exports.type_size,
606                     )?,
607                     imports: imports.set,
608                     exports: exports.set,
609                 })
610             }
611             crate::TypeDef::Instance(t) => {
612                 if !self.features.module_linking {
613                     return self.create_error("module linking proposal not enabled");
614                 }
615                 let mut exports = NameSet::default();
616                 for e in t.exports.iter() {
617                     let ty = self.import_entry_type(&e.ty)?;
618                     exports.push(self.offset, e.name, None, ty, &mut self.types, "export")?;
619                 }
620                 TypeDef::Instance(InstanceType {
621                     type_size: exports.type_size,
622                     exports: exports.set,
623                 })
624             }
625         };
626         self.cur.state.assert_mut().types.push(self.types.len());
627         self.types.push(def);
628         Ok(())
629     }
630 
value_type(&self, ty: Type) -> Result<()>631     fn value_type(&self, ty: Type) -> Result<()> {
632         match self.features.check_value_type(ty) {
633             Ok(()) => Ok(()),
634             Err(e) => self.create_error(e),
635         }
636     }
637 
import_entry_type(&self, import_type: &ImportSectionEntryType) -> Result<EntityType>638     fn import_entry_type(&self, import_type: &ImportSectionEntryType) -> Result<EntityType> {
639         match import_type {
640             ImportSectionEntryType::Function(type_index) => {
641                 self.func_type_at(*type_index)?;
642                 Ok(EntityType::Func(self.cur.state.types[*type_index as usize]))
643             }
644             ImportSectionEntryType::Table(t) => {
645                 self.table_type(t)?;
646                 Ok(EntityType::Table(t.clone()))
647             }
648             ImportSectionEntryType::Memory(t) => {
649                 self.memory_type(t)?;
650                 Ok(EntityType::Memory(t.clone()))
651             }
652             ImportSectionEntryType::Event(t) => {
653                 self.event_type(t)?;
654                 Ok(EntityType::Event(
655                     self.cur.state.types[t.type_index as usize],
656                 ))
657             }
658             ImportSectionEntryType::Global(t) => {
659                 self.global_type(t)?;
660                 Ok(EntityType::Global(t.clone()))
661             }
662             ImportSectionEntryType::Module(type_index) => {
663                 self.module_type_at(*type_index)?;
664                 Ok(EntityType::Module(
665                     self.cur.state.types[*type_index as usize],
666                 ))
667             }
668             ImportSectionEntryType::Instance(type_index) => {
669                 self.instance_type_at(*type_index)?;
670                 Ok(EntityType::Instance(
671                     self.cur.state.types[*type_index as usize],
672                 ))
673             }
674         }
675     }
676 
table_type(&self, ty: &TableType) -> Result<()>677     fn table_type(&self, ty: &TableType) -> Result<()> {
678         match ty.element_type {
679             Type::FuncRef => {}
680             Type::ExternRef => {
681                 if !self.features.reference_types {
682                     return self.create_error("element is not anyfunc");
683                 }
684             }
685             _ => return self.create_error("element is not reference type"),
686         }
687         self.limits(&ty.limits)?;
688         if ty.limits.initial > MAX_WASM_TABLE_ENTRIES as u32 {
689             return self.create_error("minimum table size is out of bounds");
690         }
691         Ok(())
692     }
693 
memory_type(&self, ty: &MemoryType) -> Result<()>694     fn memory_type(&self, ty: &MemoryType) -> Result<()> {
695         match ty {
696             MemoryType::M32 { limits, shared } => {
697                 self.limits(limits)?;
698                 let initial = limits.initial;
699                 if initial as usize > MAX_WASM_MEMORY_PAGES {
700                     return self.create_error("memory size must be at most 65536 pages (4GiB)");
701                 }
702                 if let Some(maximum) = limits.maximum {
703                     if maximum as usize > MAX_WASM_MEMORY_PAGES {
704                         return self.create_error("memory size must be at most 65536 pages (4GiB)");
705                     }
706                 }
707                 if *shared {
708                     if !self.features.threads {
709                         return self.create_error("threads must be enabled for shared memories");
710                     }
711                     if limits.maximum.is_none() {
712                         return self.create_error("shared memory must have maximum size");
713                     }
714                 }
715             }
716             MemoryType::M64 { limits, shared } => {
717                 if !self.features.memory64 {
718                     return self.create_error("memory64 must be enabled for 64-bit memories");
719                 }
720                 self.limits64(&limits)?;
721                 let initial = limits.initial;
722                 if initial > MAX_WASM_MEMORY64_PAGES {
723                     return self.create_error("memory initial size too large");
724                 }
725                 if let Some(maximum) = limits.maximum {
726                     if maximum > MAX_WASM_MEMORY64_PAGES {
727                         return self.create_error("memory initial size too large");
728                     }
729                 }
730                 if *shared {
731                     if !self.features.threads {
732                         return self.create_error("threads must be enabled for shared memories");
733                     }
734                     if limits.maximum.is_none() {
735                         return self.create_error("shared memory must have maximum size");
736                     }
737                 }
738             }
739         }
740         Ok(())
741     }
742 
event_type(&self, ty: &EventType) -> Result<()>743     fn event_type(&self, ty: &EventType) -> Result<()> {
744         let ty = self.func_type_at(ty.type_index)?;
745         if ty.returns.len() > 0 {
746             return self.create_error("invalid result arity for exception type");
747         }
748         Ok(())
749     }
750 
global_type(&self, ty: &GlobalType) -> Result<()>751     fn global_type(&self, ty: &GlobalType) -> Result<()> {
752         self.value_type(ty.content_type)
753     }
754 
limits(&self, limits: &ResizableLimits) -> Result<()>755     fn limits(&self, limits: &ResizableLimits) -> Result<()> {
756         if let Some(max) = limits.maximum {
757             if limits.initial > max {
758                 return self.create_error("size minimum must not be greater than maximum");
759             }
760         }
761         Ok(())
762     }
763 
limits64(&self, limits: &ResizableLimits64) -> Result<()>764     fn limits64(&self, limits: &ResizableLimits64) -> Result<()> {
765         if let Some(max) = limits.maximum {
766             if limits.initial > max {
767                 return self.create_error("size minimum must not be greater than maximum");
768             }
769         }
770         Ok(())
771     }
772 
773     /// Validates [`Payload::ImportSection`](crate::Payload)
import_section(&mut self, section: &crate::ImportSectionReader<'_>) -> Result<()>774     pub fn import_section(&mut self, section: &crate::ImportSectionReader<'_>) -> Result<()> {
775         let order = self.header_order(Order::Import);
776         self.section(order, section, |me, item| me.import(item))?;
777 
778         // Clear the list of implicit imports after the import section is
779         // finished since later import sections cannot append further to the
780         // pseudo-instances defined in this import section.
781         self.cur.state.assert_mut().imports.implicit.drain();
782         Ok(())
783     }
784 
import(&mut self, entry: Import<'_>) -> Result<()>785     fn import(&mut self, entry: Import<'_>) -> Result<()> {
786         if !self.features.module_linking && entry.field.is_none() {
787             return self.create_error("module linking proposal is not enabled");
788         }
789         let ty = self.import_entry_type(&entry.ty)?;
790         let state = self.cur.state.assert_mut();
791 
792         // Build up a map of what this module imports, for when this module is a
793         // nested module it'll be needed to infer the type signature of the
794         // nested module. Note that this does not happen unless the module
795         // linking proposal is enabled.
796         //
797         // This is a breaking change! This will disallow multiple imports that
798         // import from the same item twice. We can't turn module linking
799         // on-by-default as-is without some sort of recourse for consumers that
800         // want to backwards-compatibly parse older modules still. Unclear how
801         // to do this.
802         if self.features.module_linking {
803             let implicit_instance_type = state.imports.push(
804                 self.offset,
805                 entry.module,
806                 entry.field,
807                 ty,
808                 &mut self.types,
809                 "import",
810             )?;
811             if let Some(idx) = implicit_instance_type {
812                 state.instances.push(idx);
813             }
814         }
815         let (len, max, desc) = match entry.ty {
816             ImportSectionEntryType::Function(type_index) => {
817                 let ty = state.types[type_index as usize];
818                 state.func_types.push(ty);
819                 (state.func_types.len(), MAX_WASM_FUNCTIONS, "funcs")
820             }
821             ImportSectionEntryType::Table(ty) => {
822                 state.tables.push(ty);
823                 (state.tables.len(), self.max_tables(), "tables")
824             }
825             ImportSectionEntryType::Memory(ty) => {
826                 state.memories.push(ty);
827                 (state.memories.len(), self.max_memories(), "memories")
828             }
829             ImportSectionEntryType::Event(ty) => {
830                 let ty = state.types[ty.type_index as usize];
831                 state.events.push(ty);
832                 (state.events.len(), MAX_WASM_EVENTS, "events")
833             }
834             ImportSectionEntryType::Global(ty) => {
835                 state.globals.push(ty);
836                 (state.globals.len(), MAX_WASM_GLOBALS, "globals")
837             }
838             ImportSectionEntryType::Instance(type_idx) => {
839                 let index = state.types[type_idx as usize];
840                 state.instances.push(index);
841                 (state.instances.len(), MAX_WASM_INSTANCES, "instances")
842             }
843             ImportSectionEntryType::Module(type_index) => {
844                 let index = state.types[type_index as usize];
845                 state.submodules.push(index);
846                 (state.submodules.len(), MAX_WASM_MODULES, "modules")
847             }
848         };
849         self.check_max(len, 0, max, desc)?;
850         Ok(())
851     }
852 
853     /// Validates [`Payload::ModuleSectionStart`](crate::Payload)
module_section_start(&mut self, count: u32, range: &Range) -> Result<()>854     pub fn module_section_start(&mut self, count: u32, range: &Range) -> Result<()> {
855         drop(count);
856         if !self.features.module_linking {
857             return self.create_error("module linking proposal not enabled");
858         }
859         self.offset = range.start;
860         self.update_order(Order::ModuleLinkingHeader)?;
861         self.check_max(
862             self.cur.state.submodules.len(),
863             count,
864             MAX_WASM_MODULES,
865             "modules",
866         )?;
867         Ok(())
868     }
869 
870     /// Validates [`Payload::ModuleSectionEntry`](crate::Payload).
871     ///
872     /// Note that this does not actually perform any validation itself. The
873     /// `ModuleSectionEntry` payload is associated with a sub-parser for the
874     /// sub-module, and it's expected that the events from the [`Parser`]
875     /// are fed into this validator.
module_section_entry(&mut self)876     pub fn module_section_entry(&mut self) {
877         // Start a new module...
878         let prev = mem::replace(&mut self.cur, Module::default());
879         // ... and record the current module as its parent.
880         self.parents.push(prev);
881     }
882 
883     /// Validates [`Payload::AliasSection`](crate::Payload)
alias_section(&mut self, section: &crate::AliasSectionReader<'_>) -> Result<()>884     pub fn alias_section(&mut self, section: &crate::AliasSectionReader<'_>) -> Result<()> {
885         if !self.features.module_linking {
886             return self.create_error("module linking proposal not enabled");
887         }
888         self.section(Order::ModuleLinkingHeader, section, |me, a| me.alias(a))
889     }
890 
alias(&mut self, alias: Alias) -> Result<()>891     fn alias(&mut self, alias: Alias) -> Result<()> {
892         match alias {
893             Alias::InstanceExport {
894                 instance,
895                 kind,
896                 export,
897             } => {
898                 let ty = self.get_instance_type(instance)?;
899                 let export = match ty.exports.get(export) {
900                     Some(e) => e,
901                     None => {
902                         return self.create_error(format!(
903                             "aliased name `{}` does not exist in instance",
904                             export
905                         ));
906                     }
907                 };
908                 match (export, kind) {
909                     (EntityType::Func(ty), ExternalKind::Function) => {
910                         let ty = *ty;
911                         self.cur.state.assert_mut().func_types.push(ty);
912                     }
913                     (EntityType::Table(ty), ExternalKind::Table) => {
914                         let ty = ty.clone();
915                         self.cur.state.assert_mut().tables.push(ty);
916                     }
917                     (EntityType::Memory(ty), ExternalKind::Memory) => {
918                         let ty = ty.clone();
919                         self.cur.state.assert_mut().memories.push(ty);
920                     }
921                     (EntityType::Event(ty), ExternalKind::Event) => {
922                         let ty = *ty;
923                         self.cur.state.assert_mut().events.push(ty);
924                     }
925                     (EntityType::Global(ty), ExternalKind::Global) => {
926                         let ty = ty.clone();
927                         self.cur.state.assert_mut().globals.push(ty);
928                     }
929                     (EntityType::Instance(ty), ExternalKind::Instance) => {
930                         let ty = *ty;
931                         self.cur.state.assert_mut().instances.push(ty);
932                     }
933                     (EntityType::Module(ty), ExternalKind::Module) => {
934                         let ty = *ty;
935                         self.cur.state.assert_mut().submodules.push(ty);
936                     }
937                     _ => return self.create_error("alias kind mismatch with export kind"),
938                 }
939             }
940             Alias::OuterType {
941                 relative_depth,
942                 index,
943             } => {
944                 let i = self
945                     .parents
946                     .len()
947                     .checked_sub(relative_depth as usize)
948                     .and_then(|i| i.checked_sub(1))
949                     .ok_or_else(|| {
950                         BinaryReaderError::new("relative depth too large", self.offset)
951                     })?;
952                 let ty = match self.parents[i].state.types.get(index as usize) {
953                     Some(m) => *m,
954                     None => return self.create_error("alias to type not defined in parent yet"),
955                 };
956                 self.cur.state.assert_mut().types.push(ty);
957             }
958             Alias::OuterModule {
959                 relative_depth,
960                 index,
961             } => {
962                 let i = self
963                     .parents
964                     .len()
965                     .checked_sub(relative_depth as usize)
966                     .and_then(|i| i.checked_sub(1))
967                     .ok_or_else(|| {
968                         BinaryReaderError::new("relative depth too large", self.offset)
969                     })?;
970                 let module = match self.parents[i].state.submodules.get(index as usize) {
971                     Some(m) => *m,
972                     None => return self.create_error("alias to module not defined in parent yet"),
973                 };
974                 self.cur.state.assert_mut().submodules.push(module);
975             }
976         }
977 
978         Ok(())
979     }
980 
981     /// Validates [`Payload::InstanceSection`](crate::Payload)
instance_section(&mut self, section: &crate::InstanceSectionReader<'_>) -> Result<()>982     pub fn instance_section(&mut self, section: &crate::InstanceSectionReader<'_>) -> Result<()> {
983         if !self.features.module_linking {
984             return self.create_error("module linking proposal not enabled");
985         }
986         self.check_max(
987             self.cur.state.instances.len(),
988             section.get_count(),
989             MAX_WASM_INSTANCES,
990             "instances",
991         )?;
992         self.section(Order::ModuleLinkingHeader, section, |me, i| me.instance(i))
993     }
994 
instance(&mut self, instance: Instance<'_>) -> Result<()>995     fn instance(&mut self, instance: Instance<'_>) -> Result<()> {
996         // Fetch the type of the instantiated module so we can typecheck all of
997         // the import items.
998         let module_idx = instance.module();
999 
1000         // Build up the set of what we're providing as imports.
1001         let mut set = NameSet::default();
1002         for arg in instance.args()? {
1003             let arg = arg?;
1004             let ty = self.check_external_kind("instance argument", arg.kind, arg.index)?;
1005             set.push(self.offset, arg.name, None, ty, &mut self.types, "arg")?;
1006         }
1007 
1008         // Check our provided `set` to ensure it's a subtype of the expected set
1009         // of imports from the module's import types.
1010         let ty = self.get_module_type(module_idx)?;
1011         self.check_type_sets_match(&set.set, &ty.imports, "import")?;
1012 
1013         // Create a synthetic type declaration for this instance's type and
1014         // record its type in the global type list. We might not have another
1015         // `TypeDef::Instance` to point to if the module was locally declared.
1016         //
1017         // Note that the predicted size of this type is inflated due to
1018         // accounting for the imports on the original module, but that should be
1019         // ok for now since it's only used to limit the size of larger types.
1020         let instance_ty = InstanceType {
1021             type_size: ty.type_size,
1022             exports: ty.exports.clone(),
1023         };
1024         self.cur.state.assert_mut().instances.push(self.types.len());
1025         self.types.push(TypeDef::Instance(instance_ty));
1026         Ok(())
1027     }
1028 
1029     // Note that this function is basically implementing
1030     // https://webassembly.github.io/spec/core/exec/modules.html#import-matching
check_subtypes(&self, a: &EntityType, b: &EntityType) -> Result<()>1031     fn check_subtypes(&self, a: &EntityType, b: &EntityType) -> Result<()> {
1032         macro_rules! limits_match {
1033             ($a:expr, $b:expr) => {{
1034                 let a = $a;
1035                 let b = $b;
1036                 a.initial >= b.initial
1037                     && match b.maximum {
1038                         Some(b_max) => match a.maximum {
1039                             Some(a_max) => a_max <= b_max,
1040                             None => false,
1041                         },
1042                         None => true,
1043                     }
1044             }};
1045         }
1046         match a {
1047             EntityType::Global(a) => {
1048                 let b = match b {
1049                     EntityType::Global(b) => b,
1050                     _ => return self.create_error("item type mismatch"),
1051                 };
1052                 if a == b {
1053                     Ok(())
1054                 } else {
1055                     self.create_error("global type mismatch")
1056                 }
1057             }
1058             EntityType::Table(a) => {
1059                 let b = match b {
1060                     EntityType::Table(b) => b,
1061                     _ => return self.create_error("item type mismatch"),
1062                 };
1063                 if a.element_type == b.element_type && limits_match!(&a.limits, &b.limits) {
1064                     Ok(())
1065                 } else {
1066                     self.create_error("table type mismatch")
1067                 }
1068             }
1069             EntityType::Func(a) => {
1070                 let b = match b {
1071                     EntityType::Func(b) => b,
1072                     _ => return self.create_error("item type mismatch"),
1073                 };
1074                 if self.types[*a].unwrap_func() == self.types[*b].unwrap_func() {
1075                     Ok(())
1076                 } else {
1077                     self.create_error("func type mismatch")
1078                 }
1079             }
1080             EntityType::Event(a) => {
1081                 let b = match b {
1082                     EntityType::Event(b) => b,
1083                     _ => return self.create_error("item type mismatch"),
1084                 };
1085                 if self.types[*a].unwrap_func() == self.types[*b].unwrap_func() {
1086                     Ok(())
1087                 } else {
1088                     self.create_error("event type mismatch")
1089                 }
1090             }
1091             EntityType::Memory(MemoryType::M32 { limits, shared }) => {
1092                 let (b_limits, b_shared) = match b {
1093                     EntityType::Memory(MemoryType::M32 { limits, shared }) => (limits, shared),
1094                     _ => return self.create_error("item type mismatch"),
1095                 };
1096                 if limits_match!(limits, b_limits) && shared == b_shared {
1097                     Ok(())
1098                 } else {
1099                     self.create_error("memory type mismatch")
1100                 }
1101             }
1102             EntityType::Memory(MemoryType::M64 { limits, shared }) => {
1103                 let (b_limits, b_shared) = match b {
1104                     EntityType::Memory(MemoryType::M64 { limits, shared }) => (limits, shared),
1105                     _ => return self.create_error("item type mismatch"),
1106                 };
1107                 if limits_match!(limits, b_limits) && shared == b_shared {
1108                     Ok(())
1109                 } else {
1110                     self.create_error("memory type mismatch")
1111                 }
1112             }
1113             EntityType::Instance(a) => {
1114                 let b = match b {
1115                     EntityType::Instance(b) => b,
1116                     _ => return self.create_error("item type mismatch"),
1117                 };
1118                 let a = self.types[*a].unwrap_instance();
1119                 let b = self.types[*b].unwrap_instance();
1120                 self.check_type_sets_match(&a.exports, &b.exports, "export")?;
1121                 Ok(())
1122             }
1123             EntityType::Module(a) => {
1124                 let b = match b {
1125                     EntityType::Module(b) => b,
1126                     _ => return self.create_error("item type mismatch"),
1127                 };
1128                 let a = self.types[*a].unwrap_module();
1129                 let b = self.types[*b].unwrap_module();
1130                 // Note the order changing between imports and exports! This is
1131                 // a live demonstration of variance in action.
1132                 self.check_type_sets_match(&b.imports, &a.imports, "import")?;
1133                 self.check_type_sets_match(&a.exports, &b.exports, "export")?;
1134                 Ok(())
1135             }
1136         }
1137     }
1138 
check_type_sets_match( &self, a: &HashMap<String, EntityType>, b: &HashMap<String, EntityType>, desc: &str, ) -> Result<()>1139     fn check_type_sets_match(
1140         &self,
1141         a: &HashMap<String, EntityType>,
1142         b: &HashMap<String, EntityType>,
1143         desc: &str,
1144     ) -> Result<()> {
1145         for (name, b) in b {
1146             match a.get(name) {
1147                 Some(a) => self.check_subtypes(a, b)?,
1148                 None => return self.create_error(&format!("no {} named `{}`", desc, name)),
1149             }
1150         }
1151         Ok(())
1152     }
1153 
1154     /// Validates [`Payload::FunctionSection`](crate::Payload)
function_section(&mut self, section: &crate::FunctionSectionReader<'_>) -> Result<()>1155     pub fn function_section(&mut self, section: &crate::FunctionSectionReader<'_>) -> Result<()> {
1156         self.cur.expected_code_bodies = Some(section.get_count());
1157         self.check_max(
1158             self.cur.state.func_types.len(),
1159             section.get_count(),
1160             MAX_WASM_FUNCTIONS,
1161             "funcs",
1162         )?;
1163         // Assert that each type index is indeed a function type, and otherwise
1164         // just push it for handling later.
1165         self.section(Order::Function, section, |me, i| {
1166             me.func_type_at(i)?;
1167             let state = me.cur.state.assert_mut();
1168             state.func_types.push(state.types[i as usize]);
1169             state.code_type_indexes.push(i);
1170             Ok(())
1171         })
1172     }
1173 
max_tables(&self) -> usize1174     fn max_tables(&self) -> usize {
1175         if self.features.reference_types || self.features.module_linking {
1176             MAX_WASM_TABLES
1177         } else {
1178             1
1179         }
1180     }
1181 
1182     /// Validates [`Payload::TableSection`](crate::Payload)
table_section(&mut self, section: &crate::TableSectionReader<'_>) -> Result<()>1183     pub fn table_section(&mut self, section: &crate::TableSectionReader<'_>) -> Result<()> {
1184         self.check_max(
1185             self.cur.state.tables.len(),
1186             section.get_count(),
1187             self.max_tables(),
1188             "tables",
1189         )?;
1190         self.section(Order::Table, section, |me, ty| {
1191             me.table_type(&ty)?;
1192             me.cur.state.assert_mut().tables.push(ty);
1193             Ok(())
1194         })
1195     }
1196 
max_memories(&self) -> usize1197     fn max_memories(&self) -> usize {
1198         if self.features.multi_memory {
1199             MAX_WASM_MEMORIES
1200         } else {
1201             1
1202         }
1203     }
1204 
memory_section(&mut self, section: &crate::MemorySectionReader<'_>) -> Result<()>1205     pub fn memory_section(&mut self, section: &crate::MemorySectionReader<'_>) -> Result<()> {
1206         self.check_max(
1207             self.cur.state.memories.len(),
1208             section.get_count(),
1209             self.max_memories(),
1210             "memories",
1211         )?;
1212         self.section(Order::Memory, section, |me, ty| {
1213             me.memory_type(&ty)?;
1214             me.cur.state.assert_mut().memories.push(ty);
1215             Ok(())
1216         })
1217     }
1218 
event_section(&mut self, section: &crate::EventSectionReader<'_>) -> Result<()>1219     pub fn event_section(&mut self, section: &crate::EventSectionReader<'_>) -> Result<()> {
1220         self.check_max(
1221             self.cur.state.events.len(),
1222             section.get_count(),
1223             MAX_WASM_EVENTS,
1224             "events",
1225         )?;
1226         self.section(Order::Event, section, |me, ty| {
1227             me.event_type(&ty)?;
1228             let state = me.cur.state.assert_mut();
1229             state.events.push(state.types[ty.type_index as usize]);
1230             Ok(())
1231         })
1232     }
1233 
1234     /// Validates [`Payload::GlobalSection`](crate::Payload)
global_section(&mut self, section: &crate::GlobalSectionReader<'_>) -> Result<()>1235     pub fn global_section(&mut self, section: &crate::GlobalSectionReader<'_>) -> Result<()> {
1236         self.check_max(
1237             self.cur.state.globals.len(),
1238             section.get_count(),
1239             MAX_WASM_GLOBALS,
1240             "globals",
1241         )?;
1242         self.section(Order::Global, section, |me, g| {
1243             me.global_type(&g.ty)?;
1244             me.init_expr(&g.init_expr, g.ty.content_type)?;
1245             me.cur.state.assert_mut().globals.push(g.ty);
1246             Ok(())
1247         })
1248     }
1249 
init_expr(&mut self, expr: &InitExpr<'_>, expected_ty: Type) -> Result<()>1250     fn init_expr(&mut self, expr: &InitExpr<'_>, expected_ty: Type) -> Result<()> {
1251         let mut ops = expr.get_operators_reader().into_iter_with_offsets();
1252         let (op, offset) = match ops.next() {
1253             Some(Err(e)) => return Err(e),
1254             Some(Ok(pair)) => pair,
1255             None => return self.create_error("type mismatch: init_expr is empty"),
1256         };
1257         self.offset = offset;
1258         let mut function_reference = None;
1259         let ty = match op {
1260             Operator::I32Const { .. } => Type::I32,
1261             Operator::I64Const { .. } => Type::I64,
1262             Operator::F32Const { .. } => Type::F32,
1263             Operator::F64Const { .. } => Type::F64,
1264             Operator::RefNull { ty } => ty,
1265             Operator::V128Const { .. } => Type::V128,
1266             Operator::GlobalGet { global_index } => {
1267                 let global = self.get_global(global_index)?;
1268                 if global.mutable {
1269                     return self.create_error(
1270                         "constant expression required: global.get of mutable global",
1271                     );
1272                 }
1273                 global.content_type
1274             }
1275             Operator::RefFunc { function_index } => {
1276                 function_reference = Some(function_index);
1277                 self.get_func_type(function_index)?;
1278                 Type::FuncRef
1279             }
1280             Operator::End => return self.create_error("type mismatch: init_expr is empty"),
1281             _ => {
1282                 return self
1283                     .create_error("constant expression required: invalid init_expr operator")
1284             }
1285         };
1286         if ty != expected_ty {
1287             return self.create_error("type mismatch: invalid init_expr type");
1288         }
1289 
1290         if let Some(index) = function_reference {
1291             self.cur
1292                 .state
1293                 .assert_mut()
1294                 .function_references
1295                 .insert(index);
1296         }
1297 
1298         // Make sure the next instruction is an `end`
1299         match ops.next() {
1300             Some(Err(e)) => return Err(e),
1301             Some(Ok((Operator::End, _))) => {}
1302             Some(Ok(_)) => {
1303                 return self
1304                     .create_error("constant expression required: type mismatch: only one init_expr operator is expected")
1305             }
1306             None => return self.create_error("type mismatch: init_expr is not terminated"),
1307         }
1308 
1309         // ... and verify we're done after that
1310         match ops.next() {
1311             Some(Err(e)) => Err(e),
1312             Some(Ok(_)) => {
1313                 self.create_error("constant expression required: invalid init_expr operator")
1314             }
1315             None => Ok(()),
1316         }
1317     }
1318 
1319     /// Validates [`Payload::ExportSection`](crate::Payload)
export_section(&mut self, section: &crate::ExportSectionReader<'_>) -> Result<()>1320     pub fn export_section(&mut self, section: &crate::ExportSectionReader<'_>) -> Result<()> {
1321         self.section(Order::Export, section, |me, e| {
1322             if let ExternalKind::Type = e.kind {
1323                 return me.create_error("cannot export types");
1324             }
1325             let ty = me.check_external_kind("exported", e.kind, e.index)?;
1326             let state = me.cur.state.assert_mut();
1327             state
1328                 .exports
1329                 .push(me.offset, e.field, None, ty, &mut me.types, "export")?;
1330             Ok(())
1331         })
1332     }
1333 
check_external_kind( &mut self, desc: &str, kind: ExternalKind, index: u32, ) -> Result<EntityType>1334     fn check_external_kind(
1335         &mut self,
1336         desc: &str,
1337         kind: ExternalKind,
1338         index: u32,
1339     ) -> Result<EntityType> {
1340         let check = |ty: &str, total: usize| {
1341             if index as usize >= total {
1342                 self.create_error(&format!(
1343                     "unknown {ty} {index}: {desc} {ty} index out of bounds",
1344                     desc = desc,
1345                     index = index,
1346                     ty = ty,
1347                 ))
1348             } else {
1349                 Ok(())
1350             }
1351         };
1352         Ok(match kind {
1353             ExternalKind::Function => {
1354                 check("function", self.cur.state.func_types.len())?;
1355                 self.cur
1356                     .state
1357                     .assert_mut()
1358                     .function_references
1359                     .insert(index);
1360                 EntityType::Func(self.cur.state.func_types[index as usize])
1361             }
1362             ExternalKind::Table => {
1363                 check("table", self.cur.state.tables.len())?;
1364                 EntityType::Table(self.cur.state.tables[index as usize].clone())
1365             }
1366             ExternalKind::Memory => {
1367                 check("memory", self.cur.state.memories.len())?;
1368                 EntityType::Memory(self.cur.state.memories[index as usize].clone())
1369             }
1370             ExternalKind::Global => {
1371                 check("global", self.cur.state.globals.len())?;
1372                 EntityType::Global(self.cur.state.globals[index as usize].clone())
1373             }
1374             ExternalKind::Event => {
1375                 check("event", self.cur.state.events.len())?;
1376                 EntityType::Event(self.cur.state.events[index as usize])
1377             }
1378             ExternalKind::Module => {
1379                 check("module", self.cur.state.submodules.len())?;
1380                 EntityType::Module(self.cur.state.submodules[index as usize])
1381             }
1382             ExternalKind::Instance => {
1383                 check("instance", self.cur.state.instances.len())?;
1384                 EntityType::Instance(self.cur.state.instances[index as usize])
1385             }
1386             ExternalKind::Type => return self.create_error("cannot export types"),
1387         })
1388     }
1389 
1390     /// Validates [`Payload::StartSection`](crate::Payload)
start_section(&mut self, func: u32, range: &Range) -> Result<()>1391     pub fn start_section(&mut self, func: u32, range: &Range) -> Result<()> {
1392         self.offset = range.start;
1393         self.update_order(Order::Start)?;
1394         let ty = self.get_func_type(func)?;
1395         if !ty.params.is_empty() || !ty.returns.is_empty() {
1396             return self.create_error("invalid start function type");
1397         }
1398         Ok(())
1399     }
1400 
1401     /// Validates [`Payload::ElementSection`](crate::Payload)
element_section(&mut self, section: &crate::ElementSectionReader<'_>) -> Result<()>1402     pub fn element_section(&mut self, section: &crate::ElementSectionReader<'_>) -> Result<()> {
1403         self.section(Order::Element, section, |me, e| {
1404             match e.ty {
1405                 Type::FuncRef => {}
1406                 Type::ExternRef if me.features.reference_types => {}
1407                 Type::ExternRef => {
1408                     return me
1409                         .create_error("reference types must be enabled for anyref elem segment");
1410                 }
1411                 _ => return me.create_error("invalid reference type"),
1412             }
1413             match e.kind {
1414                 ElementKind::Active {
1415                     table_index,
1416                     init_expr,
1417                 } => {
1418                     let table = me.get_table(table_index)?;
1419                     if e.ty != table.element_type {
1420                         return me.create_error("element_type != table type");
1421                     }
1422                     me.init_expr(&init_expr, Type::I32)?;
1423                 }
1424                 ElementKind::Passive | ElementKind::Declared => {
1425                     if !me.features.bulk_memory {
1426                         return me.create_error("reference types must be enabled");
1427                     }
1428                 }
1429             }
1430             let mut items = e.items.get_items_reader()?;
1431             if items.get_count() > MAX_WASM_TABLE_ENTRIES as u32 {
1432                 return me.create_error("num_elements is out of bounds");
1433             }
1434             for _ in 0..items.get_count() {
1435                 me.offset = items.original_position();
1436                 match items.read()? {
1437                     ElementItem::Null(ty) => {
1438                         if ty != e.ty {
1439                             return me.create_error(
1440                                 "type mismatch: null type doesn't match element type",
1441                             );
1442                         }
1443                     }
1444                     ElementItem::Func(f) => {
1445                         if e.ty != Type::FuncRef {
1446                             return me
1447                                 .create_error("type mismatch: segment does not have funcref type");
1448                         }
1449                         me.get_func_type(f)?;
1450                         me.cur.state.assert_mut().function_references.insert(f);
1451                     }
1452                 }
1453             }
1454 
1455             me.cur.state.assert_mut().element_types.push(e.ty);
1456             Ok(())
1457         })
1458     }
1459 
1460     /// Validates [`Payload::DataCountSection`](crate::Payload)
data_count_section(&mut self, count: u32, range: &Range) -> Result<()>1461     pub fn data_count_section(&mut self, count: u32, range: &Range) -> Result<()> {
1462         self.offset = range.start;
1463         self.update_order(Order::DataCount)?;
1464         self.cur.state.assert_mut().data_count = Some(count);
1465         if count > MAX_WASM_DATA_SEGMENTS as u32 {
1466             return self.create_error("data count section specifies too many data segments");
1467         }
1468         Ok(())
1469     }
1470 
1471     /// Validates [`Payload::CodeSectionStart`](crate::Payload).
code_section_start(&mut self, count: u32, range: &Range) -> Result<()>1472     pub fn code_section_start(&mut self, count: u32, range: &Range) -> Result<()> {
1473         self.offset = range.start;
1474         self.update_order(Order::Code)?;
1475         match self.cur.expected_code_bodies.take() {
1476             Some(n) if n == count => {}
1477             Some(_) => {
1478                 return self.create_error("function and code section have inconsistent lengths");
1479             }
1480             // empty code sections are allowed even if the function section is
1481             // missing
1482             None if count == 0 => {}
1483             None => return self.create_error("code section without function section"),
1484         }
1485 
1486         // Prepare our module's view into the global `types` array. This enables
1487         // parallel function validation to accesss our built-so-far list off
1488         // types. Note that all the `WasmModuleResources` methods rely on
1489         // `all_types` being filled in, and this is the point at which they're
1490         // filled in.
1491         let types = self.types.commit();
1492         self.cur.state.assert_mut().all_types = Some(Arc::new(types));
1493 
1494         Ok(())
1495     }
1496 
1497     /// Validates [`Payload::CodeSectionEntry`](crate::Payload).
1498     ///
1499     /// This function will prepare a [`FuncValidator`] which can be used to
1500     /// validate the function. The function body provided will be parsed only
1501     /// enough to create the function validation context. After this the
1502     /// [`OperatorsReader`](crate::readers::OperatorsReader) returned can be used to read the
1503     /// opcodes of the function as well as feed information into the validator.
1504     ///
1505     /// Note that the returned [`FuncValidator`] is "connected" to this
1506     /// [`Validator`] in that it uses the internal context of this validator for
1507     /// validating the function. The [`FuncValidator`] can be sent to
1508     /// another thread, for example, to offload actual processing of functions
1509     /// elsewhere.
code_section_entry(&mut self) -> Result<FuncValidator<ValidatorResources>>1510     pub fn code_section_entry(&mut self) -> Result<FuncValidator<ValidatorResources>> {
1511         let ty = self.cur.state.code_type_indexes[self.cur.code_section_index];
1512         self.cur.code_section_index += 1;
1513         let resources = ValidatorResources(self.cur.state.arc().clone());
1514         Ok(FuncValidator::new(ty, 0, resources, &self.features).unwrap())
1515     }
1516 
1517     /// Validates [`Payload::DataSection`](crate::Payload).
data_section(&mut self, section: &crate::DataSectionReader<'_>) -> Result<()>1518     pub fn data_section(&mut self, section: &crate::DataSectionReader<'_>) -> Result<()> {
1519         self.cur.data_found = section.get_count();
1520         self.check_max(0, section.get_count(), MAX_WASM_DATA_SEGMENTS, "segments")?;
1521         let mut section = section.clone();
1522         section.forbid_bulk_memory(!self.features.bulk_memory);
1523         self.section(Order::Data, &section, |me, d| {
1524             match d.kind {
1525                 DataKind::Passive => {}
1526                 DataKind::Active {
1527                     memory_index,
1528                     init_expr,
1529                 } => {
1530                     let ty = me.get_memory(memory_index)?.index_type();
1531                     me.init_expr(&init_expr, ty)?;
1532                 }
1533             }
1534             Ok(())
1535         })
1536     }
1537 
1538     /// Validates [`Payload::UnknownSection`](crate::Payload).
1539     ///
1540     /// Currently always returns an error.
unknown_section(&mut self, id: u8, range: &Range) -> Result<()>1541     pub fn unknown_section(&mut self, id: u8, range: &Range) -> Result<()> {
1542         self.offset = range.start;
1543         self.create_error(format!("invalid section code: {}", id))
1544     }
1545 
1546     /// Validates [`Payload::End`](crate::Payload).
end(&mut self) -> Result<()>1547     pub fn end(&mut self) -> Result<()> {
1548         // Ensure that the data count section, if any, was correct.
1549         if let Some(data_count) = self.cur.state.data_count {
1550             if data_count != self.cur.data_found {
1551                 return self.create_error("data count section and passive data mismatch");
1552             }
1553         }
1554         // Ensure that the function section, if nonzero, was paired with a code
1555         // section with the appropriate length.
1556         if let Some(n) = self.cur.expected_code_bodies.take() {
1557             if n > 0 {
1558                 return self.create_error("function and code sections have inconsistent lengths");
1559             }
1560         }
1561 
1562         // Ensure that the effective type size of this module is of a bounded
1563         // size. This is primarily here for the module linking proposal, and
1564         // we'll record this in the module type below if we're part of a nested
1565         // module.
1566         let type_size = combine_type_sizes(
1567             self.offset,
1568             self.cur.state.imports.type_size,
1569             self.cur.state.exports.type_size,
1570         )?;
1571 
1572         // If we have a parent then we're going to exit this module's context
1573         // and resume where we left off in the parent. We inject a new type for
1574         // our module we just validated in the parent's module index space, and
1575         // then we reset our current state to the parent.
1576         if let Some(mut parent) = self.parents.pop() {
1577             let module_type = self.types.len();
1578             self.types.push(TypeDef::Module(ModuleType {
1579                 type_size,
1580                 imports: self.cur.state.imports.set.clone(),
1581                 exports: self.cur.state.exports.set.clone(),
1582             }));
1583             parent.state.assert_mut().submodules.push(module_type);
1584             self.cur = parent;
1585         }
1586         Ok(())
1587     }
1588 }
1589 
1590 impl WasmModuleResources for Validator {
1591     type FuncType = crate::FuncType;
1592 
table_at(&self, at: u32) -> Option<TableType>1593     fn table_at(&self, at: u32) -> Option<TableType> {
1594         self.cur.state.table_at(at)
1595     }
1596 
memory_at(&self, at: u32) -> Option<MemoryType>1597     fn memory_at(&self, at: u32) -> Option<MemoryType> {
1598         self.cur.state.memory_at(at)
1599     }
1600 
event_at(&self, at: u32) -> Option<&Self::FuncType>1601     fn event_at(&self, at: u32) -> Option<&Self::FuncType> {
1602         self.cur.state.event_at(at)
1603     }
1604 
global_at(&self, at: u32) -> Option<GlobalType>1605     fn global_at(&self, at: u32) -> Option<GlobalType> {
1606         self.cur.state.global_at(at)
1607     }
1608 
func_type_at(&self, type_idx: u32) -> Option<&Self::FuncType>1609     fn func_type_at(&self, type_idx: u32) -> Option<&Self::FuncType> {
1610         self.cur.state.func_type_at(type_idx)
1611     }
1612 
type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType>1613     fn type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType> {
1614         self.cur.state.type_of_function(func_idx)
1615     }
1616 
element_type_at(&self, at: u32) -> Option<Type>1617     fn element_type_at(&self, at: u32) -> Option<Type> {
1618         self.cur.state.element_type_at(at)
1619     }
1620 
element_count(&self) -> u321621     fn element_count(&self) -> u32 {
1622         self.cur.state.element_count()
1623     }
1624 
data_count(&self) -> u321625     fn data_count(&self) -> u32 {
1626         self.cur.state.data_count()
1627     }
1628 
is_function_referenced(&self, idx: u32) -> bool1629     fn is_function_referenced(&self, idx: u32) -> bool {
1630         self.cur.state.is_function_referenced(idx)
1631     }
1632 }
1633 
combine_type_sizes(offset: usize, a: u32, b: u32) -> Result<u32>1634 fn combine_type_sizes(offset: usize, a: u32, b: u32) -> Result<u32> {
1635     match a.checked_add(b) {
1636         Some(sum) if sum < MAX_TYPE_SIZE => Ok(sum),
1637         _ => Err(BinaryReaderError::new(
1638             "effective type size too large".to_string(),
1639             offset,
1640         )),
1641     }
1642 }
1643 
1644 impl WasmFeatures {
check_value_type(&self, ty: Type) -> Result<(), &'static str>1645     pub(crate) fn check_value_type(&self, ty: Type) -> Result<(), &'static str> {
1646         match ty {
1647             Type::I32 | Type::I64 | Type::F32 | Type::F64 => Ok(()),
1648             Type::FuncRef | Type::ExternRef => {
1649                 if self.reference_types {
1650                     Ok(())
1651                 } else {
1652                     Err("reference types support is not enabled")
1653                 }
1654             }
1655             Type::ExnRef => {
1656                 if self.exceptions {
1657                     Ok(())
1658                 } else {
1659                     Err("exceptions support is not enabled")
1660                 }
1661             }
1662             Type::V128 => {
1663                 if self.simd {
1664                     Ok(())
1665                 } else {
1666                     Err("SIMD support is not enabled")
1667                 }
1668             }
1669             _ => Err("invalid value type"),
1670         }
1671     }
1672 }
1673 
1674 impl WasmModuleResources for ModuleState {
1675     type FuncType = crate::FuncType;
1676 
table_at(&self, at: u32) -> Option<TableType>1677     fn table_at(&self, at: u32) -> Option<TableType> {
1678         self.tables.get(at as usize).cloned()
1679     }
1680 
memory_at(&self, at: u32) -> Option<MemoryType>1681     fn memory_at(&self, at: u32) -> Option<MemoryType> {
1682         self.memories.get(at as usize).cloned()
1683     }
1684 
event_at(&self, at: u32) -> Option<&Self::FuncType>1685     fn event_at(&self, at: u32) -> Option<&Self::FuncType> {
1686         let types = self.all_types.as_ref().unwrap();
1687         let i = *self.events.get(at as usize)?;
1688         match &types[i] {
1689             TypeDef::Func(f) => Some(f),
1690             _ => None,
1691         }
1692     }
1693 
global_at(&self, at: u32) -> Option<GlobalType>1694     fn global_at(&self, at: u32) -> Option<GlobalType> {
1695         self.globals.get(at as usize).cloned()
1696     }
1697 
func_type_at(&self, at: u32) -> Option<&Self::FuncType>1698     fn func_type_at(&self, at: u32) -> Option<&Self::FuncType> {
1699         let types = self.all_types.as_ref().unwrap();
1700         let i = *self.types.get(at as usize)?;
1701         match &types[i] {
1702             TypeDef::Func(f) => Some(f),
1703             _ => None,
1704         }
1705     }
1706 
type_of_function(&self, at: u32) -> Option<&Self::FuncType>1707     fn type_of_function(&self, at: u32) -> Option<&Self::FuncType> {
1708         let types = self.all_types.as_ref().unwrap();
1709         let i = *self.func_types.get(at as usize)?;
1710         match &types[i] {
1711             TypeDef::Func(f) => Some(f),
1712             _ => None,
1713         }
1714     }
1715 
element_type_at(&self, at: u32) -> Option<Type>1716     fn element_type_at(&self, at: u32) -> Option<Type> {
1717         self.element_types.get(at as usize).cloned()
1718     }
1719 
element_count(&self) -> u321720     fn element_count(&self) -> u32 {
1721         self.element_types.len() as u32
1722     }
1723 
data_count(&self) -> u321724     fn data_count(&self) -> u32 {
1725         self.data_count.unwrap_or(0)
1726     }
1727 
is_function_referenced(&self, idx: u32) -> bool1728     fn is_function_referenced(&self, idx: u32) -> bool {
1729         self.function_references.contains(&idx)
1730     }
1731 }
1732 
1733 /// The implementation of [`WasmModuleResources`] used by [`Validator`].
1734 pub struct ValidatorResources(Arc<ModuleState>);
1735 
1736 impl WasmModuleResources for ValidatorResources {
1737     type FuncType = crate::FuncType;
1738 
table_at(&self, at: u32) -> Option<TableType>1739     fn table_at(&self, at: u32) -> Option<TableType> {
1740         self.0.table_at(at)
1741     }
1742 
memory_at(&self, at: u32) -> Option<MemoryType>1743     fn memory_at(&self, at: u32) -> Option<MemoryType> {
1744         self.0.memory_at(at)
1745     }
1746 
event_at(&self, at: u32) -> Option<&Self::FuncType>1747     fn event_at(&self, at: u32) -> Option<&Self::FuncType> {
1748         self.0.event_at(at)
1749     }
1750 
global_at(&self, at: u32) -> Option<GlobalType>1751     fn global_at(&self, at: u32) -> Option<GlobalType> {
1752         self.0.global_at(at)
1753     }
1754 
func_type_at(&self, at: u32) -> Option<&Self::FuncType>1755     fn func_type_at(&self, at: u32) -> Option<&Self::FuncType> {
1756         self.0.func_type_at(at)
1757     }
1758 
type_of_function(&self, at: u32) -> Option<&Self::FuncType>1759     fn type_of_function(&self, at: u32) -> Option<&Self::FuncType> {
1760         self.0.type_of_function(at)
1761     }
1762 
element_type_at(&self, at: u32) -> Option<Type>1763     fn element_type_at(&self, at: u32) -> Option<Type> {
1764         self.0.element_type_at(at)
1765     }
1766 
element_count(&self) -> u321767     fn element_count(&self) -> u32 {
1768         self.0.element_count()
1769     }
1770 
data_count(&self) -> u321771     fn data_count(&self) -> u32 {
1772         self.0.data_count()
1773     }
1774 
is_function_referenced(&self, idx: u32) -> bool1775     fn is_function_referenced(&self, idx: u32) -> bool {
1776         self.0.is_function_referenced(idx)
1777     }
1778 }
1779 
1780 mod arc {
1781     use std::ops::Deref;
1782     use std::sync::Arc;
1783 
1784     pub struct MaybeOwned<T> {
1785         owned: bool,
1786         arc: Arc<T>,
1787     }
1788 
1789     impl<T> MaybeOwned<T> {
as_mut(&mut self) -> Option<&mut T>1790         pub fn as_mut(&mut self) -> Option<&mut T> {
1791             if !self.owned {
1792                 return None;
1793             }
1794             debug_assert!(Arc::get_mut(&mut self.arc).is_some());
1795             Some(unsafe { &mut *(&*self.arc as *const T as *mut T) })
1796         }
1797 
assert_mut(&mut self) -> &mut T1798         pub fn assert_mut(&mut self) -> &mut T {
1799             self.as_mut().unwrap()
1800         }
1801 
arc(&mut self) -> &Arc<T>1802         pub fn arc(&mut self) -> &Arc<T> {
1803             self.owned = false;
1804             &self.arc
1805         }
1806     }
1807 
1808     impl<T: Default> Default for MaybeOwned<T> {
default() -> MaybeOwned<T>1809         fn default() -> MaybeOwned<T> {
1810             MaybeOwned {
1811                 owned: true,
1812                 arc: Arc::default(),
1813             }
1814         }
1815     }
1816 
1817     impl<T> Deref for MaybeOwned<T> {
1818         type Target = T;
1819 
deref(&self) -> &T1820         fn deref(&self) -> &T {
1821             &self.arc
1822         }
1823     }
1824 }
1825 
1826 /// This is a helper structure to create a map from names to types.
1827 ///
1828 /// The main purpose of this structure is to handle the two-level imports found
1829 /// in wasm modules pre-module-linking. A two-level import is equivalent to a
1830 /// single-level import of an instance, and that mapping happens here.
1831 #[derive(Default)]
1832 struct NameSet {
1833     set: HashMap<String, EntityType>,
1834     implicit: HashSet<String>,
1835     type_size: u32,
1836 }
1837 
1838 impl NameSet {
1839     /// Pushes a new name into this typed set off names, internally handling the
1840     /// mapping of two-level namespaces into a single-level namespace.
1841     ///
1842     /// * `offset` - the binary offset in the original wasm file of where to
1843     ///   report errors about.
1844     /// * `module` - the first-level name in the namespace
1845     /// * `name` - the optional second-level namespace
1846     /// * `ty` - the type of the item being pushed
1847     /// * `types` - our global list of types
1848     /// * `desc` - a human-readable description of the item being pushed, used
1849     ///   for generating errors.
1850     ///
1851     /// Returns an error if the name was a duplicate. Returns `Ok(Some(idx))` if
1852     /// this push was the first push to define an implicit instance with the
1853     /// type `idx` into the global list of types. Returns `Ok(None)` otherwise.
push( &mut self, offset: usize, module: &str, name: Option<&str>, ty: EntityType, types: &mut SnapshotList<TypeDef>, desc: &str, ) -> Result<Option<usize>>1854     fn push(
1855         &mut self,
1856         offset: usize,
1857         module: &str,
1858         name: Option<&str>,
1859         ty: EntityType,
1860         types: &mut SnapshotList<TypeDef>,
1861         desc: &str,
1862     ) -> Result<Option<usize>> {
1863         self.type_size = combine_type_sizes(offset, self.type_size, ty.size(types))?;
1864         let name = match name {
1865             Some(name) => name,
1866             // If the `name` is not provided then this is a module-linking style
1867             // definition with only one level of a name rather than two. This
1868             // means we can insert the `ty` into the set of imports directly,
1869             // error-ing out on duplicates.
1870             None => {
1871                 let prev = self.set.insert(module.to_string(), ty);
1872                 return if prev.is_some() {
1873                     Err(BinaryReaderError::new(
1874                         format!("duplicate {} name `{}` already defined", desc, module),
1875                         offset,
1876                     ))
1877                 } else {
1878                     Ok(None)
1879                 };
1880             }
1881         };
1882         match self.set.get(module) {
1883             // If `module` was previously defined and we implicitly defined it,
1884             // then we know that it points to an instance type. We update the
1885             // set of exports of the instance type here since we're adding a new
1886             // entry. Note that nothing, at the point that we're building this
1887             // set, should point to this instance type so it should be safe to
1888             // mutate.
1889             Some(instance) if self.implicit.contains(module) => {
1890                 let instance = match instance {
1891                     EntityType::Instance(i) => match &mut types[*i] {
1892                         TypeDef::Instance(i) => i,
1893                         _ => unreachable!(),
1894                     },
1895                     _ => unreachable!(),
1896                 };
1897                 let prev = instance.exports.insert(name.to_string(), ty);
1898                 if prev.is_some() {
1899                     return Err(BinaryReaderError::new(
1900                         format!(
1901                             "duplicate {} name `{}::{}` already defined",
1902                             desc, module, name
1903                         ),
1904                         offset,
1905                     ));
1906                 }
1907                 Ok(None)
1908             }
1909 
1910             // Otherwise `module` was previously defined, but it *wasn't*
1911             // implicitly defined through a two level import (rather was
1912             // explicitly defined with a single-level import), then that's an
1913             // error.
1914             Some(_) => {
1915                 return Err(BinaryReaderError::new(
1916                     format!("cannot define the {} `{}` twice", desc, module),
1917                     offset,
1918                 ))
1919             }
1920 
1921             // And finally if `module` wasn't already defined then we go ahead
1922             // and define it here as a instance type with a single export, our
1923             // `name`.
1924             None => {
1925                 let idx = types.len();
1926                 let mut instance = InstanceType::default();
1927                 instance.exports.insert(name.to_string(), ty);
1928                 types.push(TypeDef::Instance(instance));
1929                 assert!(self.implicit.insert(module.to_string()));
1930                 self.set
1931                     .insert(module.to_string(), EntityType::Instance(idx));
1932                 Ok(Some(idx))
1933             }
1934         }
1935     }
1936 }
1937 
1938 impl EntityType {
size(&self, list: &SnapshotList<TypeDef>) -> u321939     fn size(&self, list: &SnapshotList<TypeDef>) -> u32 {
1940         let recursive_size = match self {
1941             // Note that this function computes the size of the *type*, not the
1942             // size of the value, so these "leaves" all count as 1
1943             EntityType::Global(_) | EntityType::Memory(_) | EntityType::Table(_) => 1,
1944 
1945             // These types have recursive sizes so we look up the size in the
1946             // type tables.
1947             EntityType::Func(i)
1948             | EntityType::Module(i)
1949             | EntityType::Instance(i)
1950             | EntityType::Event(i) => match &list[*i] {
1951                 TypeDef::Func(f) => (f.params.len() + f.returns.len()) as u32,
1952                 TypeDef::Module(m) => m.type_size,
1953                 TypeDef::Instance(i) => i.type_size,
1954             },
1955         };
1956         recursive_size.saturating_add(1)
1957     }
1958 }
1959 
1960 /// This is a type which mirrors a subset of the `Vec<T>` API, but is intended
1961 /// to be able to be cheaply snapshotted and cloned.
1962 ///
1963 /// When each module's code sections start we "commit" the current list of types
1964 /// in the global list of types. This means that the temporary `cur` vec here is
1965 /// pushed onto `snapshots` and wrapped up in an `Arc`. At that point we clone
1966 /// this entire list (which is then O(modules), not O(types in all modules)) and
1967 /// pass out as a context to each function validator.
1968 ///
1969 /// Otherwise, though, this type behaves as if it were a large `Vec<T>`, but
1970 /// it's represented by lists of contiguous chunks.
1971 struct SnapshotList<T> {
1972     // All previous snapshots, the "head" of the list that this type represents.
1973     // The first entry in this pair is the starting index for all elements
1974     // contained in the list, and the second element is the list itself. Note
1975     // the `Arc` wrapper around sub-lists, which makes cloning time for this
1976     // `SnapshotList` O(snapshots) rather than O(snapshots_total), which for
1977     // us in this context means the number of modules, not types.
1978     //
1979     // Note that this list is sorted least-to-greatest in order of the index for
1980     // binary searching.
1981     snapshots: Vec<(usize, Arc<Vec<T>>)>,
1982 
1983     // This is the total length of all lists in the `snapshots` array.
1984     snapshots_total: usize,
1985 
1986     // The current list of types for the current snapshot that are being built.
1987     cur: Vec<T>,
1988 }
1989 
1990 impl<T> SnapshotList<T> {
1991     /// Same as `<&[T]>::get`
get(&self, index: usize) -> Option<&T>1992     fn get(&self, index: usize) -> Option<&T> {
1993         // Check to see if this index falls on our local list
1994         if index >= self.snapshots_total {
1995             return self.cur.get(index - self.snapshots_total);
1996         }
1997         // ... and failing that we do a binary search to figure out which bucket
1998         // it's in. Note the `i-1` in the `Err` case because if we don't find an
1999         // exact match the type is located in the previous bucket.
2000         let i = match self.snapshots.binary_search_by_key(&index, |(i, _)| *i) {
2001             Ok(i) => i,
2002             Err(i) => i - 1,
2003         };
2004         let (len, list) = &self.snapshots[i];
2005         Some(&list[index - len])
2006     }
2007 
2008     /// Same as `<&mut [T]>::get_mut`, except only works for indexes into the
2009     /// current snapshot being built.
2010     ///
2011     /// # Panics
2012     ///
2013     /// Panics if an index is passed in which falls within the
2014     /// previously-snapshotted list of types. This should never happen in our
2015     /// contesxt and the panic is intended to weed out possible bugs in
2016     /// wasmparser.
get_mut(&mut self, index: usize) -> Option<&mut T>2017     fn get_mut(&mut self, index: usize) -> Option<&mut T> {
2018         if index >= self.snapshots_total {
2019             return self.cur.get_mut(index - self.snapshots_total);
2020         }
2021         panic!("cannot get a mutable reference in snapshotted part of list")
2022     }
2023 
2024     /// Same as `Vec::push`
push(&mut self, val: T)2025     fn push(&mut self, val: T) {
2026         self.cur.push(val);
2027     }
2028 
2029     /// Same as `<[T]>::len`
len(&self) -> usize2030     fn len(&self) -> usize {
2031         self.cur.len() + self.snapshots_total
2032     }
2033 
2034     /// Commits previously pushed types into this snapshot vector, and returns a
2035     /// clone of this list.
2036     ///
2037     /// The returned `SnapshotList` can be used to access all the same types as
2038     /// this list itself. This list also is not changed (from an external
2039     /// perspective) and can continue to access all the same types.
commit(&mut self) -> SnapshotList<T>2040     fn commit(&mut self) -> SnapshotList<T> {
2041         // If the current chunk has new elements, commit them in to an
2042         // `Arc`-wrapped vector in the snapshots list. Note the `shrink_to_fit`
2043         // ahead of time to hopefully keep memory usage lower than it would
2044         // otherwise be.
2045         let len = self.cur.len();
2046         if len > 0 {
2047             self.cur.shrink_to_fit();
2048             self.snapshots
2049                 .push((self.snapshots_total, Arc::new(mem::take(&mut self.cur))));
2050             self.snapshots_total += len;
2051         }
2052         SnapshotList {
2053             snapshots: self.snapshots.clone(),
2054             snapshots_total: self.snapshots_total,
2055             cur: Vec::new(),
2056         }
2057     }
2058 }
2059 
2060 impl<T> std::ops::Index<usize> for SnapshotList<T> {
2061     type Output = T;
2062 
index(&self, index: usize) -> &T2063     fn index(&self, index: usize) -> &T {
2064         self.get(index).unwrap()
2065     }
2066 }
2067 
2068 impl<T> std::ops::IndexMut<usize> for SnapshotList<T> {
index_mut(&mut self, index: usize) -> &mut T2069     fn index_mut(&mut self, index: usize) -> &mut T {
2070         self.get_mut(index).unwrap()
2071     }
2072 }
2073 
2074 impl<T> Default for SnapshotList<T> {
default() -> SnapshotList<T>2075     fn default() -> SnapshotList<T> {
2076         SnapshotList {
2077             snapshots: Vec::new(),
2078             snapshots_total: 0,
2079             cur: Vec::new(),
2080         }
2081     }
2082 }
2083