pub struct Validator { /* private fields */ }
Expand description
Validator for a WebAssembly binary module or component.
This structure encapsulates state necessary to validate a WebAssembly
binary. This implements validation as defined by the core
specification. A Validator
is designed, like
Parser
, to accept incremental input over time.
Additionally a Validator
is also designed for parallel validation of
functions as they are received.
It’s expected that you’ll be using a Parser
in tandem with a
Validator
. As each Payload
is received from a
Parser
you’ll pass it into a Validator
to test the validity of the
payload. Note that all payloads received from a Parser
are expected to
be passed to a Validator
. For example if you receive
Payload::TypeSection
you’ll call
Validator::type_section
to validate this.
The design of Validator
is intended that you’ll interleave, in your own
application’s processing, calls to validation. Each variant, after it’s
received, will be validated and then your application would proceed as
usual. At all times, however, you’ll have access to the Validator
and
the validation context up to that point. This enables applications to check
the types of functions and learn how many globals there are, for example.
Implementations§
source§impl Validator
impl Validator
sourcepub fn new_with_features(features: WasmFeatures) -> Validator
pub fn new_with_features(features: WasmFeatures) -> Validator
Creates a new Validator
which has the specified set of wasm
features activated for validation.
This function is the same as Validator::new
except it also allows
you to customize the active wasm features in use for validation. This
can allow enabling experimental proposals or also turning off
on-by-default wasm proposals.
sourcepub fn features(&self) -> &WasmFeatures
pub fn features(&self) -> &WasmFeatures
Returns the wasm features used for this validator.
sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Reset this validator’s state such that it is ready to validate a new Wasm module or component.
This does not clear or reset the internal state keeping track of
validated (and deduplicated and canonicalized) types, allowing you to
use the same type identifiers (such as
CoreTypeId
) for the same types that are
defined multiple times across different modules and components.
fn foo() -> anyhow::Result<()> {
use wasmparser::Validator;
let mut validator = Validator::default();
// Two wasm modules, both of which define the same type, but at
// different indices in their respective types index spaces.
let wasm1 = wat::parse_str("
(module
(type $same_type (func (param i32) (result f64)))
)
")?;
let wasm2 = wat::parse_str("
(module
(type $different_type (func))
(type $same_type (func (param i32) (result f64)))
)
")?;
// Validate the first Wasm module and get the ID of its type.
let types = validator.validate_all(&wasm1)?;
let id1 = types.core_type_at(0);
// Reset the validator so we can parse the second wasm module inside
// this validator's same context.
validator.reset();
// Validate the second Wasm module and get the ID of its second type,
// which is the same type as the first Wasm module's only type.
let types = validator.validate_all(&wasm2)?;
let id2 = types.core_type_at(1);
// Because both modules were processed in the same `Validator`, they
// share the same types context and therefore the same type defined
// multiple times across different modules will be deduplicated and
// assigned the same identifier!
assert_eq!(id1, id2);
assert_eq!(types[id1.unwrap_sub()], types[id2.unwrap_sub()]);
sourcepub fn id(&self) -> ValidatorId
pub fn id(&self) -> ValidatorId
Get this validator’s unique identifier.
Allows you to assert that you are always working with the same
Validator
instance, when you can’t otherwise statically ensure that
property by e.g. storing a reference to the validator inside your
structure.
sourcepub fn validate_all(&mut self, bytes: &[u8]) -> Result<Types, BinaryReaderError>
pub fn validate_all(&mut self, bytes: &[u8]) -> Result<Types, BinaryReaderError>
Validates an entire in-memory module or component with this validator.
This function will internally create a Parser
to parse the bytes
provided. The entire module or component specified by bytes
will be
parsed and validated.
Upon success, the type information for the top-level module or component will be returned.
sourcepub fn types(&self, level: usize) -> Option<TypesRef<'_>>
pub fn types(&self, level: usize) -> Option<TypesRef<'_>>
Gets the types known by the validator so far within the
module/component level
modules/components up from the
module/component currently being parsed.
For instance, calling validator.types(0)
will get the types of the
module/component currently being parsed, and validator.types(1)
will
get the types of the component containing that module/component.
Returns None
if there is no module/component that many levels up.
sourcepub fn payload<'a>(
&mut self,
payload: &Payload<'a>,
) -> Result<ValidPayload<'a>, BinaryReaderError>
pub fn payload<'a>( &mut self, payload: &Payload<'a>, ) -> Result<ValidPayload<'a>, BinaryReaderError>
Convenience function to validate a single Payload
.
This function is intended to be used as a convenience. It will
internally perform any validation necessary to validate the Payload
provided. The convenience part is that you’re likely already going to
be matching on Payload
in your application, at which point it’s more
appropriate to call the individual methods on Validator
per-variant
in Payload
, such as Validator::type_section
.
This function returns a ValidPayload
variant on success, indicating
one of a few possible actions that need to be taken after a payload is
validated. For example function contents are not validated here, they’re
returned through ValidPayload
for validation by the caller.
sourcepub fn version(
&mut self,
num: u16,
encoding: Encoding,
range: &Range<usize>,
) -> Result<(), BinaryReaderError>
pub fn version( &mut self, num: u16, encoding: Encoding, range: &Range<usize>, ) -> Result<(), BinaryReaderError>
Validates Payload::Version
.
sourcepub fn type_section(
&mut self,
section: &SectionLimited<'_, RecGroup>,
) -> Result<(), BinaryReaderError>
pub fn type_section( &mut self, section: &SectionLimited<'_, RecGroup>, ) -> Result<(), BinaryReaderError>
Validates Payload::TypeSection
.
sourcepub fn import_section(
&mut self,
section: &SectionLimited<'_, Import<'_>>,
) -> Result<(), BinaryReaderError>
pub fn import_section( &mut self, section: &SectionLimited<'_, Import<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::ImportSection
.
This method should only be called when parsing a module.
sourcepub fn function_section(
&mut self,
section: &SectionLimited<'_, u32>,
) -> Result<(), BinaryReaderError>
pub fn function_section( &mut self, section: &SectionLimited<'_, u32>, ) -> Result<(), BinaryReaderError>
Validates Payload::FunctionSection
.
This method should only be called when parsing a module.
sourcepub fn table_section(
&mut self,
section: &SectionLimited<'_, Table<'_>>,
) -> Result<(), BinaryReaderError>
pub fn table_section( &mut self, section: &SectionLimited<'_, Table<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::TableSection
.
This method should only be called when parsing a module.
sourcepub fn memory_section(
&mut self,
section: &SectionLimited<'_, MemoryType>,
) -> Result<(), BinaryReaderError>
pub fn memory_section( &mut self, section: &SectionLimited<'_, MemoryType>, ) -> Result<(), BinaryReaderError>
Validates Payload::MemorySection
.
This method should only be called when parsing a module.
sourcepub fn tag_section(
&mut self,
section: &SectionLimited<'_, TagType>,
) -> Result<(), BinaryReaderError>
pub fn tag_section( &mut self, section: &SectionLimited<'_, TagType>, ) -> Result<(), BinaryReaderError>
Validates Payload::TagSection
.
This method should only be called when parsing a module.
sourcepub fn global_section(
&mut self,
section: &SectionLimited<'_, Global<'_>>,
) -> Result<(), BinaryReaderError>
pub fn global_section( &mut self, section: &SectionLimited<'_, Global<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::GlobalSection
.
This method should only be called when parsing a module.
sourcepub fn export_section(
&mut self,
section: &SectionLimited<'_, Export<'_>>,
) -> Result<(), BinaryReaderError>
pub fn export_section( &mut self, section: &SectionLimited<'_, Export<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::ExportSection
.
This method should only be called when parsing a module.
sourcepub fn start_section(
&mut self,
func: u32,
range: &Range<usize>,
) -> Result<(), BinaryReaderError>
pub fn start_section( &mut self, func: u32, range: &Range<usize>, ) -> Result<(), BinaryReaderError>
Validates Payload::StartSection
.
This method should only be called when parsing a module.
sourcepub fn element_section(
&mut self,
section: &SectionLimited<'_, Element<'_>>,
) -> Result<(), BinaryReaderError>
pub fn element_section( &mut self, section: &SectionLimited<'_, Element<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::ElementSection
.
This method should only be called when parsing a module.
sourcepub fn data_count_section(
&mut self,
count: u32,
range: &Range<usize>,
) -> Result<(), BinaryReaderError>
pub fn data_count_section( &mut self, count: u32, range: &Range<usize>, ) -> Result<(), BinaryReaderError>
Validates Payload::DataCountSection
.
This method should only be called when parsing a module.
sourcepub fn code_section_start(
&mut self,
count: u32,
range: &Range<usize>,
) -> Result<(), BinaryReaderError>
pub fn code_section_start( &mut self, count: u32, range: &Range<usize>, ) -> Result<(), BinaryReaderError>
Validates Payload::CodeSectionStart
.
This method should only be called when parsing a module.
sourcepub fn code_section_entry(
&mut self,
body: &FunctionBody<'_>,
) -> Result<FuncToValidate<ValidatorResources>, BinaryReaderError>
pub fn code_section_entry( &mut self, body: &FunctionBody<'_>, ) -> Result<FuncToValidate<ValidatorResources>, BinaryReaderError>
Validates Payload::CodeSectionEntry
.
This function will prepare a FuncToValidate
which can be used to
create a FuncValidator
to validate the function. The function body
provided will not be parsed or validated by this function.
Note that the returned FuncToValidate
is “connected” to this
Validator
in that it uses the internal context of this validator for
validating the function. The FuncToValidate
can be sent to another
thread, for example, to offload actual processing of functions
elsewhere.
This method should only be called when parsing a module.
sourcepub fn data_section(
&mut self,
section: &SectionLimited<'_, Data<'_>>,
) -> Result<(), BinaryReaderError>
pub fn data_section( &mut self, section: &SectionLimited<'_, Data<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::DataSection
.
This method should only be called when parsing a module.
sourcepub fn module_section(
&mut self,
range: &Range<usize>,
) -> Result<(), BinaryReaderError>
pub fn module_section( &mut self, range: &Range<usize>, ) -> Result<(), BinaryReaderError>
Validates Payload::ModuleSection
.
This method should only be called when parsing a component.
sourcepub fn instance_section(
&mut self,
section: &SectionLimited<'_, Instance<'_>>,
) -> Result<(), BinaryReaderError>
pub fn instance_section( &mut self, section: &SectionLimited<'_, Instance<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::InstanceSection
.
This method should only be called when parsing a component.
sourcepub fn core_type_section(
&mut self,
section: &SectionLimited<'_, CoreType<'_>>,
) -> Result<(), BinaryReaderError>
pub fn core_type_section( &mut self, section: &SectionLimited<'_, CoreType<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::CoreTypeSection
.
This method should only be called when parsing a component.
sourcepub fn component_section(
&mut self,
range: &Range<usize>,
) -> Result<(), BinaryReaderError>
pub fn component_section( &mut self, range: &Range<usize>, ) -> Result<(), BinaryReaderError>
Validates Payload::ComponentSection
.
This method should only be called when parsing a component.
sourcepub fn component_instance_section(
&mut self,
section: &SectionLimited<'_, ComponentInstance<'_>>,
) -> Result<(), BinaryReaderError>
pub fn component_instance_section( &mut self, section: &SectionLimited<'_, ComponentInstance<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::ComponentInstanceSection
.
This method should only be called when parsing a component.
sourcepub fn component_alias_section(
&mut self,
section: &SectionLimited<'_, ComponentAlias<'_>>,
) -> Result<(), BinaryReaderError>
pub fn component_alias_section( &mut self, section: &SectionLimited<'_, ComponentAlias<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::ComponentAliasSection
.
This method should only be called when parsing a component.
sourcepub fn component_type_section(
&mut self,
section: &SectionLimited<'_, ComponentType<'_>>,
) -> Result<(), BinaryReaderError>
pub fn component_type_section( &mut self, section: &SectionLimited<'_, ComponentType<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::ComponentTypeSection
.
This method should only be called when parsing a component.
sourcepub fn component_canonical_section(
&mut self,
section: &SectionLimited<'_, CanonicalFunction>,
) -> Result<(), BinaryReaderError>
pub fn component_canonical_section( &mut self, section: &SectionLimited<'_, CanonicalFunction>, ) -> Result<(), BinaryReaderError>
Validates Payload::ComponentCanonicalSection
.
This method should only be called when parsing a component.
sourcepub fn component_start_section(
&mut self,
f: &ComponentStartFunction,
range: &Range<usize>,
) -> Result<(), BinaryReaderError>
pub fn component_start_section( &mut self, f: &ComponentStartFunction, range: &Range<usize>, ) -> Result<(), BinaryReaderError>
Validates Payload::ComponentStartSection
.
This method should only be called when parsing a component.
sourcepub fn component_import_section(
&mut self,
section: &SectionLimited<'_, ComponentImport<'_>>,
) -> Result<(), BinaryReaderError>
pub fn component_import_section( &mut self, section: &SectionLimited<'_, ComponentImport<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::ComponentImportSection
.
This method should only be called when parsing a component.
sourcepub fn component_export_section(
&mut self,
section: &SectionLimited<'_, ComponentExport<'_>>,
) -> Result<(), BinaryReaderError>
pub fn component_export_section( &mut self, section: &SectionLimited<'_, ComponentExport<'_>>, ) -> Result<(), BinaryReaderError>
Validates Payload::ComponentExportSection
.
This method should only be called when parsing a component.
sourcepub fn unknown_section(
&mut self,
id: u8,
range: &Range<usize>,
) -> Result<(), BinaryReaderError>
pub fn unknown_section( &mut self, id: u8, range: &Range<usize>, ) -> Result<(), BinaryReaderError>
Validates Payload::UnknownSection
.
Currently always returns an error.
sourcepub fn end(&mut self, offset: usize) -> Result<Types, BinaryReaderError>
pub fn end(&mut self, offset: usize) -> Result<Types, BinaryReaderError>
Validates Payload::End
.
Returns the types known to the validator for the module or component.