Skip to content

Commit c3039e9

Browse files
committed
wasmpaser: Validate nested modules
This commit implements recursive validation of nested modules in wasmparser. Previously nested modules were simply skipped but now they're recursed into and actually checked. This commit also comes with a more complete implementation of handling `alias` directives. Internally this required quite a bit of refactoring. The validator now retains a stack of modules which are being validated and remembers parent-relationships between them. Indices into this stack are then used for recording type definitions. The type of a function/instance/module/etc can be defined the current module or any previous module on the stack. New helper functiosn were added to help resolve this new `Def` type to ensure it's handled correctly.
1 parent 3efb2da commit c3039e9

File tree

10 files changed

+622
-348
lines changed

10 files changed

+622
-348
lines changed

crates/wasmparser/src/module_resources.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ pub trait WasmModuleResources {
302302
/// Returns the global variable at given index.
303303
fn global_at(&self, at: u32) -> Option<&Self::GlobalType>;
304304
/// Returns the function signature ID at given index.
305-
fn func_type_id_at(&self, at: u32) -> Option<u32>;
305+
fn func_type_at(&self, at: u32) -> Option<&<Self::TypeDef as WasmTypeDef>::FuncType>;
306306
/// Returns the element type at the given index.
307307
fn element_type_at(&self, at: u32) -> Option<crate::Type>;
308308

@@ -336,8 +336,8 @@ where
336336
fn global_at(&self, at: u32) -> Option<&Self::GlobalType> {
337337
T::global_at(self, at)
338338
}
339-
fn func_type_id_at(&self, at: u32) -> Option<u32> {
340-
T::func_type_id_at(self, at)
339+
fn func_type_at(&self, at: u32) -> Option<&<T::TypeDef as WasmTypeDef>::FuncType> {
340+
T::func_type_at(self, at)
341341
}
342342
fn element_type_at(&self, at: u32) -> Option<crate::Type> {
343343
T::element_type_at(self, at)

crates/wasmparser/src/operators_validator.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ impl OperatorValidator {
523523
function_index: u32,
524524
resources: impl WasmModuleResources,
525525
) -> OperatorValidatorResult<()> {
526-
let type_index = match resources.func_type_id_at(function_index) {
526+
let ty = match resources.func_type_at(function_index) {
527527
Some(i) => i,
528528
None => {
529529
bail_op_err!(
@@ -532,7 +532,6 @@ impl OperatorValidator {
532532
);
533533
}
534534
};
535-
let ty = func_type_at(&resources, type_index)?;
536535
self.check_operands(wasm_func_type_inputs(ty).map(WasmType::to_parser_type))?;
537536
self.func_state.change_frame_with_types(
538537
ty.len_inputs(),
@@ -1557,7 +1556,7 @@ impl OperatorValidator {
15571556
}
15581557
Operator::RefFunc { function_index } => {
15591558
self.check_reference_types_enabled()?;
1560-
if resources.func_type_id_at(function_index).is_none() {
1559+
if resources.func_type_at(function_index).is_none() {
15611560
return Err(OperatorValidatorError::new(
15621561
"unknown function: function index out of bounds",
15631562
));

crates/wasmparser/src/parser.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,3 +1294,20 @@ impl<'a> WasmDecoder<'a> for Parser<'a> {
12941294
&self.state
12951295
}
12961296
}
1297+
1298+
impl<'a> From<ModuleReader<'a>> for Parser<'a> {
1299+
fn from(reader: ModuleReader<'a>) -> Parser<'a> {
1300+
let mut parser = Parser::default();
1301+
parser.state = ParserState::BeginWasm {
1302+
version: reader.get_version(),
1303+
};
1304+
parser.module_reader = Some(reader);
1305+
return parser;
1306+
}
1307+
}
1308+
1309+
impl<'a> Default for Parser<'a> {
1310+
fn default() -> Parser<'a> {
1311+
Parser::new(&[])
1312+
}
1313+
}

0 commit comments

Comments
 (0)