Skip to content

Commit 6b85ae2

Browse files
itsrainyfitzgen
andauthored
- Add a ReorderCustomSectionMutator (#954)
- Move AddCustomSectionMutator to custom.rs - Add CustomSectionMutator to lib.rs so it starts getting used Co-authored-by: Nick Fitzgerald <[email protected]>
1 parent 861bfaa commit 6b85ae2

File tree

5 files changed

+140
-64
lines changed

5 files changed

+140
-64
lines changed

crates/wasm-mutate/src/info.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,31 @@ impl<'a> ModuleInfo<'a> {
309309
module
310310
}
311311

312+
/// Move a section from index `src_idx` to `dest_idx` in the Wasm module
313+
pub fn move_section(&self, src_idx: usize, dest_idx: usize) -> wasm_encoder::Module {
314+
log::trace!(
315+
"moving section from index {} to index {}",
316+
src_idx,
317+
dest_idx
318+
);
319+
assert!(src_idx < self.raw_sections.len());
320+
assert!(dest_idx < self.raw_sections.len());
321+
assert_ne!(src_idx, dest_idx);
322+
let mut module = wasm_encoder::Module::new();
323+
self.raw_sections.iter().enumerate().for_each(|(i, s)| {
324+
if src_idx < dest_idx && i == dest_idx {
325+
module.section(&self.raw_sections[src_idx]);
326+
}
327+
if i != src_idx {
328+
module.section(s);
329+
}
330+
if dest_idx < src_idx && i == dest_idx {
331+
module.section(&self.raw_sections[src_idx]);
332+
}
333+
});
334+
module
335+
}
336+
312337
/// Replace the `i`th section in this module with the given new section.
313338
pub fn replace_section(
314339
&self,

crates/wasm-mutate/src/lib.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ mod mutators;
1717
pub use error::*;
1818

1919
use crate::mutators::{
20-
add_custom::AddCustomSectionMutator, add_function::AddFunctionMutator,
21-
add_type::AddTypeMutator, codemotion::CodemotionMutator,
22-
function_body_unreachable::FunctionBodyUnreachable, modify_const_exprs::ConstExpressionMutator,
23-
modify_data::ModifyDataMutator, peephole::PeepholeMutator, remove_export::RemoveExportMutator,
24-
remove_item::RemoveItemMutator, remove_section::RemoveSection,
25-
rename_export::RenameExportMutator, snip_function::SnipMutator, Item,
20+
add_function::AddFunctionMutator, add_type::AddTypeMutator, codemotion::CodemotionMutator,
21+
custom::AddCustomSectionMutator, custom::CustomSectionMutator,
22+
custom::ReorderCustomSectionMutator, function_body_unreachable::FunctionBodyUnreachable,
23+
modify_const_exprs::ConstExpressionMutator, modify_data::ModifyDataMutator,
24+
peephole::PeepholeMutator, remove_export::RemoveExportMutator, remove_item::RemoveItemMutator,
25+
remove_section::RemoveSection, rename_export::RenameExportMutator, snip_function::SnipMutator,
26+
Item,
2627
};
2728
use info::ModuleInfo;
2829
use mutators::Mutator;
@@ -213,6 +214,8 @@ impl<'wasm> WasmMutate<'wasm> {
213214
&CodemotionMutator,
214215
&FunctionBodyUnreachable,
215216
&AddCustomSectionMutator,
217+
&ReorderCustomSectionMutator,
218+
&CustomSectionMutator,
216219
&AddTypeMutator {
217220
max_params: 20,
218221
max_results: 20,

crates/wasm-mutate/src/mutators.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
//! functions is processed in order to construct an equivalent piece of code.
2121
//!
2222
23-
pub mod add_custom;
2423
pub mod add_function;
2524
pub mod add_type;
2625
pub mod codemotion;

crates/wasm-mutate/src/mutators/add_custom.rs

Lines changed: 0 additions & 57 deletions
This file was deleted.

crates/wasm-mutate/src/mutators/custom.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,97 @@ impl Mutator for CustomSectionMutator {
7272
}
7373
}
7474

75+
#[derive(Clone, Copy)]
76+
pub struct AddCustomSectionMutator;
77+
78+
const MAX_NEW_DATA_LEN: usize = 100;
79+
const MAX_NEW_NAME_LEN: usize = 20;
80+
81+
impl Mutator for AddCustomSectionMutator {
82+
fn can_mutate(&self, config: &crate::WasmMutate) -> bool {
83+
!config.reduce
84+
}
85+
86+
fn mutate<'a>(
87+
&self,
88+
config: &'a mut crate::WasmMutate,
89+
) -> crate::Result<Box<dyn Iterator<Item = crate::Result<wasm_encoder::Module>> + 'a>> {
90+
let num_sections = config.info().raw_sections.len();
91+
let new_custom_section_idx = config.rng().gen_range(0..=num_sections);
92+
let mut name = vec![];
93+
config.raw_mutate(&mut name, MAX_NEW_NAME_LEN)?;
94+
let name = String::from_utf8_lossy(&name);
95+
let mut data = vec![];
96+
config.raw_mutate(&mut data, MAX_NEW_DATA_LEN)?;
97+
98+
Ok(Box::new(std::iter::once(Ok(config.info().insert_section(
99+
new_custom_section_idx,
100+
&wasm_encoder::CustomSection {
101+
name: &name,
102+
data: &data,
103+
},
104+
)))))
105+
}
106+
}
107+
108+
#[derive(Copy, Clone)]
109+
pub struct ReorderCustomSectionMutator;
110+
111+
impl Mutator for ReorderCustomSectionMutator {
112+
fn can_mutate(&self, config: &crate::WasmMutate) -> bool {
113+
config.info().has_custom_section() && config.info().raw_sections.len() > 1
114+
}
115+
116+
fn mutate<'a>(
117+
&self,
118+
config: &'a mut crate::WasmMutate,
119+
) -> crate::Result<Box<dyn Iterator<Item = crate::Result<wasm_encoder::Module>> + 'a>> {
120+
let custom_section_indices: Vec<_> = config
121+
.info()
122+
.raw_sections
123+
.iter()
124+
.enumerate()
125+
.filter(|(_i, s)| s.id == wasm_encoder::SectionId::Custom as u8)
126+
.map(|(i, _s)| i)
127+
.collect();
128+
assert!(!custom_section_indices.is_empty());
129+
130+
let src_idx = *custom_section_indices.choose(config.rng()).unwrap();
131+
let num_sections = config.info().raw_sections.len();
132+
let mut dest_idx;
133+
loop {
134+
dest_idx = config.rng().gen_range(0..num_sections);
135+
if dest_idx != src_idx {
136+
break;
137+
}
138+
config.consume_fuel(1)?;
139+
}
140+
141+
Ok(Box::new(std::iter::once(Ok(config
142+
.info()
143+
.move_section(src_idx, dest_idx)))))
144+
}
145+
}
146+
75147
#[cfg(test)]
76148
mod tests {
77149
use super::*;
78150

151+
#[test]
152+
fn test_add_custom_section() {
153+
crate::mutators::match_mutation(
154+
r#"
155+
(module)
156+
"#,
157+
AddCustomSectionMutator,
158+
r#"
159+
(module
160+
(@custom "a" "b")
161+
)
162+
"#,
163+
);
164+
}
165+
79166
#[test]
80167
fn test_grow_custom_section() {
81168
crate::mutators::match_mutation(
@@ -143,4 +230,23 @@ mod tests {
143230
"#,
144231
);
145232
}
233+
234+
#[test]
235+
fn test_reorder_custom_section() {
236+
crate::mutators::match_mutation(
237+
r#"
238+
(module
239+
(@custom "name" "data")
240+
(@custom "name2" "data")
241+
)
242+
"#,
243+
ReorderCustomSectionMutator,
244+
r#"
245+
(module
246+
(@custom "name2" "data")
247+
(@custom "name" "data")
248+
)
249+
"#,
250+
)
251+
}
146252
}

0 commit comments

Comments
 (0)