From ba5922f63c98858b2018deb45ecf187ff4a27d67 Mon Sep 17 00:00:00 2001 From: Filipe Azevedo Date: Thu, 19 May 2022 17:47:25 +0100 Subject: [PATCH] handle unknown sections --- res/cases/v1/global_section.wasm | Bin 0 -> 14072 bytes src/builder/table.rs | 8 +- src/elements/module.rs | 139 +++++++++++++++++++------------ src/elements/name_section.rs | 13 +-- 4 files changed, 93 insertions(+), 67 deletions(-) create mode 100644 res/cases/v1/global_section.wasm diff --git a/res/cases/v1/global_section.wasm b/res/cases/v1/global_section.wasm new file mode 100644 index 0000000000000000000000000000000000000000..5eac6e80ace7c2c0b95840dfe2d7ede3af04b919 GIT binary patch literal 14072 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 Vtofb{ADo*m`cEazC+p(;{{qE{U*P}% literal 0 HcmV?d00001 diff --git a/src/builder/table.rs b/src/builder/table.rs index 6bfcb40c8..54d2c7270 100644 --- a/src/builder/table.rs +++ b/src/builder/table.rs @@ -3,7 +3,7 @@ use crate::elements; use alloc::vec::Vec; /// Table definition -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default)] pub struct TableDefinition { /// Minimum length pub min: u32, @@ -79,9 +79,3 @@ where self.callback.invoke(self.table) } } - -impl Default for TableDefinition { - fn default() -> Self { - TableDefinition { min: 0, max: None, elements: Vec::new() } - } -} diff --git a/src/elements/module.rs b/src/elements/module.rs index 96efa1a90..118949aa6 100644 --- a/src/elements/module.rs +++ b/src/elements/module.rs @@ -95,12 +95,12 @@ impl Module { // Custom sections can be inserted anywhere. Lets always insert them last here. if section.order() == 0 { sections.push(section); - return Ok(()) + return Ok(()); } // Check if the section already exists. if sections.iter().any(|s| s.order() == section.order()) { - return Err(Error::DuplicatedSections(section.order())) + return Err(Error::DuplicatedSections(section.order())); } // Assume that the module is already well-ordered. @@ -117,7 +117,7 @@ impl Module { pub fn code_section(&self) -> Option<&CodeSection> { for section in self.sections() { if let Section::Code(ref code_section) = *section { - return Some(code_section) + return Some(code_section); } } None @@ -127,7 +127,7 @@ impl Module { pub fn code_section_mut(&mut self) -> Option<&mut CodeSection> { for section in self.sections_mut() { if let Section::Code(ref mut code_section) = *section { - return Some(code_section) + return Some(code_section); } } None @@ -137,7 +137,7 @@ impl Module { pub fn type_section(&self) -> Option<&TypeSection> { for section in self.sections() { if let Section::Type(ref type_section) = *section { - return Some(type_section) + return Some(type_section); } } None @@ -147,7 +147,7 @@ impl Module { pub fn type_section_mut(&mut self) -> Option<&mut TypeSection> { for section in self.sections_mut() { if let Section::Type(ref mut type_section) = *section { - return Some(type_section) + return Some(type_section); } } None @@ -157,7 +157,7 @@ impl Module { pub fn import_section(&self) -> Option<&ImportSection> { for section in self.sections() { if let Section::Import(ref import_section) = *section { - return Some(import_section) + return Some(import_section); } } None @@ -167,7 +167,7 @@ impl Module { pub fn import_section_mut(&mut self) -> Option<&mut ImportSection> { for section in self.sections_mut() { if let Section::Import(ref mut import_section) = *section { - return Some(import_section) + return Some(import_section); } } None @@ -177,7 +177,7 @@ impl Module { pub fn global_section(&self) -> Option<&GlobalSection> { for section in self.sections() { if let Section::Global(ref section) = *section { - return Some(section) + return Some(section); } } None @@ -187,7 +187,7 @@ impl Module { pub fn global_section_mut(&mut self) -> Option<&mut GlobalSection> { for section in self.sections_mut() { if let Section::Global(ref mut section) = *section { - return Some(section) + return Some(section); } } None @@ -197,7 +197,7 @@ impl Module { pub fn export_section(&self) -> Option<&ExportSection> { for section in self.sections() { if let Section::Export(ref export_section) = *section { - return Some(export_section) + return Some(export_section); } } None @@ -207,7 +207,7 @@ impl Module { pub fn export_section_mut(&mut self) -> Option<&mut ExportSection> { for section in self.sections_mut() { if let Section::Export(ref mut export_section) = *section { - return Some(export_section) + return Some(export_section); } } None @@ -217,7 +217,7 @@ impl Module { pub fn table_section(&self) -> Option<&TableSection> { for section in self.sections() { if let Section::Table(ref section) = *section { - return Some(section) + return Some(section); } } None @@ -227,7 +227,7 @@ impl Module { pub fn table_section_mut(&mut self) -> Option<&mut TableSection> { for section in self.sections_mut() { if let Section::Table(ref mut section) = *section { - return Some(section) + return Some(section); } } None @@ -237,7 +237,7 @@ impl Module { pub fn data_section(&self) -> Option<&DataSection> { for section in self.sections() { if let Section::Data(ref section) = *section { - return Some(section) + return Some(section); } } None @@ -247,7 +247,7 @@ impl Module { pub fn data_section_mut(&mut self) -> Option<&mut DataSection> { for section in self.sections_mut() { if let Section::Data(ref mut section) = *section { - return Some(section) + return Some(section); } } None @@ -257,7 +257,7 @@ impl Module { pub fn elements_section(&self) -> Option<&ElementSection> { for section in self.sections() { if let Section::Element(ref section) = *section { - return Some(section) + return Some(section); } } None @@ -267,7 +267,7 @@ impl Module { pub fn elements_section_mut(&mut self) -> Option<&mut ElementSection> { for section in self.sections_mut() { if let Section::Element(ref mut section) = *section { - return Some(section) + return Some(section); } } None @@ -277,7 +277,7 @@ impl Module { pub fn memory_section(&self) -> Option<&MemorySection> { for section in self.sections() { if let Section::Memory(ref section) = *section { - return Some(section) + return Some(section); } } None @@ -287,7 +287,7 @@ impl Module { pub fn memory_section_mut(&mut self) -> Option<&mut MemorySection> { for section in self.sections_mut() { if let Section::Memory(ref mut section) = *section { - return Some(section) + return Some(section); } } None @@ -297,7 +297,7 @@ impl Module { pub fn function_section(&self) -> Option<&FunctionSection> { for section in self.sections() { if let Section::Function(ref sect) = *section { - return Some(sect) + return Some(sect); } } None @@ -307,7 +307,7 @@ impl Module { pub fn function_section_mut(&mut self) -> Option<&mut FunctionSection> { for section in self.sections_mut() { if let Section::Function(ref mut sect) = *section { - return Some(sect) + return Some(sect); } } None @@ -317,7 +317,7 @@ impl Module { pub fn start_section(&self) -> Option { for section in self.sections() { if let Section::Start(sect) = *section { - return Some(sect) + return Some(sect); } } None @@ -328,7 +328,7 @@ impl Module { for section in self.sections_mut().iter_mut() { if let Section::Start(_sect) = *section { *section = Section::Start(new_start); - return + return; } } // This should not fail, because we update the existing section above. @@ -343,7 +343,7 @@ impl Module { for (index, section) in sections.iter_mut().enumerate() { if let Section::Start(_sect) = section { rmidx = index; - break + break; } } if rmidx < sections.len() { @@ -366,7 +366,7 @@ impl Module { if let Section::Custom(ref mut sect) = *section { if sect.name() == name { *sect = CustomSection::new(name, payload); - return + return; } } } @@ -422,7 +422,7 @@ impl Module { pub fn names_section(&self) -> Option<&NameSection> { for section in self.sections() { if let Section::Name(ref sect) = *section { - return Some(sect) + return Some(sect); } } None @@ -435,7 +435,7 @@ impl Module { pub fn names_section_mut(&mut self) -> Option<&mut NameSection> { for section in self.sections_mut() { if let Section::Name(ref mut sect) = *section { - return Some(sect) + return Some(sect); } } None @@ -460,7 +460,7 @@ impl Module { Ok(ns) => ns, Err(e) => { parse_errors.push((i, e)); - continue + continue; }, }; Some(name_section) @@ -502,12 +502,12 @@ impl Module { Ok(reloc_section) => reloc_section, Err(e) => { parse_errors.push((i, e)); - continue + continue; }, }; if rdr.position() != custom.payload().len() { parse_errors.push((i, io::Error::InvalidData.into())); - continue + continue; } Some(Section::Reloc(reloc_section)) } else { @@ -537,10 +537,10 @@ impl Module { .filter(|import| { matches!( (count_type, *import.external()), - (ImportCountType::Function, External::Function(_)) | - (ImportCountType::Global, External::Global(_)) | - (ImportCountType::Table, External::Table(_)) | - (ImportCountType::Memory, External::Memory(_)) + (ImportCountType::Function, External::Function(_)) + | (ImportCountType::Global, External::Global(_)) + | (ImportCountType::Table, External::Table(_)) + | (ImportCountType::Memory, External::Memory(_)) ) }) .count() @@ -550,26 +550,26 @@ impl Module { /// Query functions space. pub fn functions_space(&self) -> usize { - self.import_count(ImportCountType::Function) + - self.function_section().map(|fs| fs.entries().len()).unwrap_or(0) + self.import_count(ImportCountType::Function) + + self.function_section().map(|fs| fs.entries().len()).unwrap_or(0) } /// Query globals space. pub fn globals_space(&self) -> usize { - self.import_count(ImportCountType::Global) + - self.global_section().map(|gs| gs.entries().len()).unwrap_or(0) + self.import_count(ImportCountType::Global) + + self.global_section().map(|gs| gs.entries().len()).unwrap_or(0) } /// Query table space. pub fn table_space(&self) -> usize { - self.import_count(ImportCountType::Table) + - self.table_section().map(|ts| ts.entries().len()).unwrap_or(0) + self.import_count(ImportCountType::Table) + + self.table_section().map(|ts| ts.entries().len()).unwrap_or(0) } /// Query memory space. pub fn memory_space(&self) -> usize { - self.import_count(ImportCountType::Memory) + - self.memory_section().map(|ms| ms.entries().len()).unwrap_or(0) + self.import_count(ImportCountType::Memory) + + self.memory_section().map(|ms| ms.entries().len()).unwrap_or(0) } } @@ -582,13 +582,13 @@ impl Deserialize for Module { let mut magic = [0u8; 4]; reader.read(&mut magic)?; if magic != WASM_MAGIC_NUMBER { - return Err(Error::InvalidMagic) + return Err(Error::InvalidMagic); } let version: u32 = Uint32::deserialize(reader)?.into(); if version != 1 { - return Err(Error::UnsupportedVersion(version)) + return Err(Error::UnsupportedVersion(version)); } let mut last_section_order = 0; @@ -601,8 +601,9 @@ impl Deserialize for Module { if section.order() != 0 { match last_section_order { x if x > section.order() => return Err(Error::SectionsOutOfOrder), - x if x == section.order() => - return Err(Error::DuplicatedSections(last_section_order)), + x if x == section.order() => { + return Err(Error::DuplicatedSections(last_section_order)); + }, _ => {}, }; @@ -615,10 +616,10 @@ impl Deserialize for Module { let module = Module { magic: u32::from_le_bytes(magic), version, sections }; - if module.code_section().map(|cs| cs.bodies().len()).unwrap_or(0) != - module.function_section().map(|fs| fs.entries().len()).unwrap_or(0) + if module.code_section().map(|cs| cs.bodies().len()).unwrap_or(0) + != module.function_section().map(|fs| fs.entries().len()).unwrap_or(0) { - return Err(Error::InconsistentCode) + return Err(Error::InconsistentCode); } Ok(module) @@ -649,7 +650,7 @@ impl<'a> io::Read for PeekSection<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result<()> { let available = cmp::min(buf.len(), self.region.len() - self.cursor); if available < buf.len() { - return Err(io::Error::UnexpectedEof) + return Err(io::Error::UnexpectedEof); } let range = self.cursor..self.cursor + buf.len(); @@ -663,7 +664,7 @@ impl<'a> io::Read for PeekSection<'a> { /// Returns size of the module in the provided stream. pub fn peek_size(source: &[u8]) -> usize { if source.len() < 9 { - return 0 + return 0; } let mut cursor = 8; @@ -689,13 +690,13 @@ pub fn peek_size(source: &[u8]) -> usize { x if x > source.len() => break, x if x == source.len() => { cursor = next_cursor; - break + break; }, _ => {}, } cursor = next_cursor; } else { - break + break; } } @@ -774,7 +775,7 @@ mod integration_tests { deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); module.sections_mut().retain(|x| { if let Section::Code(_) = *x { - return true + return true; } matches!(*x, Section::Function(_)) }); @@ -904,6 +905,34 @@ mod integration_tests { assert!(found_section, "Name section should be present in dedicated example"); } + #[test] + fn names_with_global_section() { + let module = deserialize_file("./res/cases/v1/global_section.wasm") + .expect("Should be deserialized") + .parse_names() + .expect("Names to be parsed"); + + let mut found_section = false; + for section in module.sections() { + if let Section::Name(ref name_section) = *section { + let function_name_subsection = + name_section.functions().expect("function_name_subsection should be present"); + assert_eq!( + function_name_subsection.names().get(0).expect("Should be entry #0"), + "~lib/builtins/abort" + ); + assert_eq!( + function_name_subsection.names().get(11).expect("Should be entry #0"), + "~lib/typedarray/Uint8Array#__set" + ); + + found_section = true; + } + } + + assert!(found_section, "Name section should be present in dedicated example"); + } + // This test fixture has FLAG_SHARED so it depends on atomics feature. #[test] fn shared_memory_flag() { diff --git a/src/elements/name_section.rs b/src/elements/name_section.rs index 7b005bd5d..4c2c17d64 100644 --- a/src/elements/name_section.rs +++ b/src/elements/name_section.rs @@ -73,31 +73,34 @@ impl NameSection { while let Ok(raw_subsection_type) = VarUint7::deserialize(rdr) { let subsection_type = raw_subsection_type.into(); // deserialize the section size - VarUint32::deserialize(rdr)?; + let size: usize = VarUint32::deserialize(rdr)?.into(); match subsection_type { NAME_TYPE_MODULE => { if module_name.is_some() { - return Err(Error::DuplicatedNameSubsections(NAME_TYPE_FUNCTION)) + return Err(Error::DuplicatedNameSubsections(NAME_TYPE_FUNCTION)); } module_name = Some(ModuleNameSubsection::deserialize(rdr)?); }, NAME_TYPE_FUNCTION => { if function_names.is_some() { - return Err(Error::DuplicatedNameSubsections(NAME_TYPE_FUNCTION)) + return Err(Error::DuplicatedNameSubsections(NAME_TYPE_FUNCTION)); } function_names = Some(FunctionNameSubsection::deserialize(module, rdr)?); }, NAME_TYPE_LOCAL => { if local_names.is_some() { - return Err(Error::DuplicatedNameSubsections(NAME_TYPE_LOCAL)) + return Err(Error::DuplicatedNameSubsections(NAME_TYPE_LOCAL)); } local_names = Some(LocalNameSubsection::deserialize(module, rdr)?); }, - _ => return Err(Error::UnknownNameSubsectionType(subsection_type)), + _ => { + let mut buf = vec![0; size]; + rdr.read(&mut buf)?; + }, }; }