From 565824aea89c3256e20578cfbbf609a51a95ec5a Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 17 Dec 2018 12:20:56 +0000 Subject: [PATCH 1/4] Introduce dropsection --- README.md | 4 ++ libchisel/src/dropsection.rs | 116 +++++++++++++++++++++++++++++++++++ libchisel/src/lib.rs | 1 + 3 files changed, 121 insertions(+) create mode 100644 libchisel/src/dropsection.rs diff --git a/README.md b/README.md index f9ccc68..029cc60 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,10 @@ Can be set to allow or prohibit unlisted additional exports. The following presets are provided: - `ewasm`: Verifies that the `main` function and `memory` is exported. Disallows any unlisted exports. +### dropsection + +Removes selected sections from the module. + ### deployer Wraps module into an ewasm-compatible constructor. It has two presets: diff --git a/libchisel/src/dropsection.rs b/libchisel/src/dropsection.rs new file mode 100644 index 0000000..df83ea0 --- /dev/null +++ b/libchisel/src/dropsection.rs @@ -0,0 +1,116 @@ +use super::{ModuleError, ModuleTranslator}; + +use parity_wasm::builder::*; +use parity_wasm::elements::*; + +/// Enum on which ModuleTranslator is implemented. +pub enum DropSection<'a> { + NamesSection, + /// Name of the custom section. + CustomSectionByName(&'a String), + /// Index of the custom section. + CustomSectionByIndex(usize), + /// Index of the unknown section. + UnknownSectionByIndex(usize), +} + +fn names_section_index_for(module: &Module) -> Result { + for (index, section) in module.sections().iter().enumerate() { + if let Section::Name(_section) = section { + return Ok(index); + } + } + Err("Not found".to_string()) +} + +fn custom_section_index_for(module: &Module, name: &String) -> Result { + for (index, section) in module.sections().iter().enumerate() { + if let Section::Custom(_section) = section { + if _section.name() == name { + return Ok(index); + } + } + } + Err("Not found".to_string()) +} + +impl<'a> DropSection<'a> { + fn find_index(&self, module: &Module) -> Result { + Ok(match &self { + DropSection::NamesSection => names_section_index_for(module)?, + DropSection::CustomSectionByName(name) => custom_section_index_for(module, &name)?, + DropSection::CustomSectionByIndex(index) => *index, + DropSection::UnknownSectionByIndex(index) => *index, + }) + } + + fn drop_section(&self, module: &mut Module) -> Result { + let index = self.find_index(&module)?; + + let sections = module.sections_mut(); + if index > sections.len() { + return Err(ModuleError::NotFound); + } + sections.remove(index); + + Ok(true) + } +} + +impl<'a> ModuleTranslator for DropSection<'a> { + fn translate_inplace(&self, module: &mut Module) -> Result { + Ok(self.drop_section(module)?) + } + + fn translate(&self, module: &Module) -> Result, ModuleError> { + let mut ret = module.clone(); + if self.drop_section(&mut ret)? { + Ok(Some(ret)) + } else { + Ok(None) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use parity_wasm::builder; + + #[test] + fn keep_intact() { + let mut module = builder::module().build(); + let name = "empty".to_string(); + let dropper = DropSection::CustomSectionByName(&name); + let did_change = dropper.translate_inplace(&mut module).unwrap(); + assert_eq!(did_change, false); + } + + #[test] + fn keep_intact_custom_section() { + let mut module = builder::module() + .with_section(Section::Custom(CustomSection::new( + "test".to_string(), + vec![], + ))) + .build(); + let name = "empty".to_string(); + let dropper = DropSection::CustomSectionByName(&name); + let did_change = dropper.translate_inplace(&mut module).unwrap(); + assert_eq!(did_change, false); + } + + #[test] + fn remove_custom_section() { + let mut module = builder::module() + .with_section(Section::Custom(CustomSection::new( + "test".to_string(), + vec![], + ))) + .build(); + let name = "test".to_string(); + let dropper = DropSection::CustomSectionByName(&name); + let did_change = dropper.translate_inplace(&mut module).unwrap(); + assert_eq!(did_change, true); + } +} diff --git a/libchisel/src/lib.rs b/libchisel/src/lib.rs index ceede3e..135e141 100644 --- a/libchisel/src/lib.rs +++ b/libchisel/src/lib.rs @@ -8,6 +8,7 @@ pub mod imports; pub mod checkstartfunc; pub mod deployer; +pub mod dropsection; pub mod remapimports; pub mod remapstart; pub mod repack; From 9ea90a5bf240da903a62e30b20278b06501fddcf Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 4 Jun 2019 13:04:51 +0100 Subject: [PATCH 2/4] Use Option instead of Result in dropsection --- libchisel/src/dropsection.rs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/libchisel/src/dropsection.rs b/libchisel/src/dropsection.rs index df83ea0..eae1299 100644 --- a/libchisel/src/dropsection.rs +++ b/libchisel/src/dropsection.rs @@ -14,38 +14,42 @@ pub enum DropSection<'a> { UnknownSectionByIndex(usize), } -fn names_section_index_for(module: &Module) -> Result { +fn names_section_index_for(module: &Module) -> Option { for (index, section) in module.sections().iter().enumerate() { if let Section::Name(_section) = section { - return Ok(index); + return Some(index); } } - Err("Not found".to_string()) + None } -fn custom_section_index_for(module: &Module, name: &String) -> Result { +fn custom_section_index_for(module: &Module, name: &String) -> Option { for (index, section) in module.sections().iter().enumerate() { if let Section::Custom(_section) = section { if _section.name() == name { - return Ok(index); + return Some(index); } } } - Err("Not found".to_string()) + None } impl<'a> DropSection<'a> { - fn find_index(&self, module: &Module) -> Result { - Ok(match &self { - DropSection::NamesSection => names_section_index_for(module)?, - DropSection::CustomSectionByName(name) => custom_section_index_for(module, &name)?, - DropSection::CustomSectionByIndex(index) => *index, - DropSection::UnknownSectionByIndex(index) => *index, - }) + fn find_index(&self, module: &Module) -> Option { + match &self { + DropSection::NamesSection => names_section_index_for(module), + DropSection::CustomSectionByName(name) => custom_section_index_for(module, &name), + DropSection::CustomSectionByIndex(index) => Some(*index), + DropSection::UnknownSectionByIndex(index) => Some(*index), + } } fn drop_section(&self, module: &mut Module) -> Result { - let index = self.find_index(&module)?; + let index = self.find_index(&module); + if index.is_none() { + return Err(ModuleError::NotFound); + } + let index = index.unwrap(); let sections = module.sections_mut(); if index > sections.len() { From 72384aab9084e3ab1cd798592f8e3ea20161e5c5 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 4 Jun 2019 13:20:09 +0100 Subject: [PATCH 3/4] Consider missing section as ok and add more tests --- libchisel/src/dropsection.rs | 58 ++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/libchisel/src/dropsection.rs b/libchisel/src/dropsection.rs index eae1299..3b6edee 100644 --- a/libchisel/src/dropsection.rs +++ b/libchisel/src/dropsection.rs @@ -47,13 +47,13 @@ impl<'a> DropSection<'a> { fn drop_section(&self, module: &mut Module) -> Result { let index = self.find_index(&module); if index.is_none() { - return Err(ModuleError::NotFound); + return Ok(false); } let index = index.unwrap(); let sections = module.sections_mut(); - if index > sections.len() { - return Err(ModuleError::NotFound); + if index >= sections.len() { + return Ok(false); } sections.remove(index); @@ -117,4 +117,56 @@ mod tests { let did_change = dropper.translate_inplace(&mut module).unwrap(); assert_eq!(did_change, true); } + + #[test] + fn remove_custom_section_by_index() { + let mut module = builder::module() + .with_section(Section::Custom(CustomSection::new( + "test".to_string(), + vec![], + ))) + .build(); + let dropper = DropSection::CustomSectionByIndex(0); + let did_change = dropper.translate_inplace(&mut module).unwrap(); + assert_eq!(did_change, true); + } + + #[test] + fn remove_oob_custom_section_by_index() { + let mut module = builder::module() + .with_section(Section::Custom(CustomSection::new( + "test".to_string(), + vec![], + ))) + .build(); + let dropper = DropSection::CustomSectionByIndex(1); + let did_change = dropper.translate_inplace(&mut module).unwrap(); + assert_eq!(did_change, false); + } + + #[test] + fn remove_custom_unknown_by_index() { + let mut module = builder::module() + .with_section(Section::Custom(CustomSection::new( + "test".to_string(), + vec![], + ))) + .build(); + let dropper = DropSection::UnknownSectionByIndex(0); + let did_change = dropper.translate_inplace(&mut module).unwrap(); + assert_eq!(did_change, true); + } + + #[test] + fn remove_oob_unknown_section_by_index() { + let mut module = builder::module() + .with_section(Section::Custom(CustomSection::new( + "test".to_string(), + vec![], + ))) + .build(); + let dropper = DropSection::UnknownSectionByIndex(1); + let did_change = dropper.translate_inplace(&mut module).unwrap(); + assert_eq!(did_change, false); + } } From 885bc5a3d817c071ba324ff5436f1ff7e6a1d72f Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 20 Jun 2019 12:19:24 +0100 Subject: [PATCH 4/4] Use Iterator.position() in dropsection to simplify code --- libchisel/src/dropsection.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/libchisel/src/dropsection.rs b/libchisel/src/dropsection.rs index 3b6edee..28e7276 100644 --- a/libchisel/src/dropsection.rs +++ b/libchisel/src/dropsection.rs @@ -15,23 +15,17 @@ pub enum DropSection<'a> { } fn names_section_index_for(module: &Module) -> Option { - for (index, section) in module.sections().iter().enumerate() { - if let Section::Name(_section) = section { - return Some(index); - } - } - None + module.sections().iter().position(|e| match e { + Section::Name(_) => true, + _ => false, + }) } fn custom_section_index_for(module: &Module, name: &String) -> Option { - for (index, section) in module.sections().iter().enumerate() { - if let Section::Custom(_section) = section { - if _section.name() == name { - return Some(index); - } - } - } - None + module.sections().iter().position(|e| match e { + Section::Custom(_section) => _section.name() == name, + _ => false, + }) } impl<'a> DropSection<'a> {