Skip to content

Commit 0241ea3

Browse files
authored
Fix testing for errors during fuzzing (#1814)
Create a first-class error instead of testing for error strings to ensure this is more resilient over time.
1 parent 1058100 commit 0241ea3

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

crates/wit-parser/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub use ast::{parse_use_path, ParsedUsePath};
2121
mod sizealign;
2222
pub use sizealign::*;
2323
mod resolve;
24-
pub use resolve::{Package, PackageId, Remap, Resolve};
24+
pub use resolve::{InvalidTransitiveDependency, Package, PackageId, Remap, Resolve};
2525
mod live;
2626
pub use live::{LiveTypes, TypeIdVisitor};
2727

crates/wit-parser/src/resolve.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::cmp::Ordering;
22
use std::collections::hash_map;
33
use std::collections::{BTreeMap, HashMap, HashSet};
4+
use std::fmt;
45
use std::mem;
56
use std::path::{Path, PathBuf};
67

@@ -1895,8 +1896,7 @@ package {name} is defined in two different locations:\n\
18951896
// more refactoring, so it's left to a future date in the
18961897
// hopes that most folks won't actually run into this for
18971898
// the time being.
1898-
"interface `{name}` transitively depends on an interface in \
1899-
incompatible ways",
1899+
InvalidTransitiveDependency(name),
19001900
);
19011901
}
19021902
}
@@ -3439,6 +3439,34 @@ fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
34393439
bail!("mismatch in stability attributes")
34403440
}
34413441

3442+
/// An error that can be returned during "world elaboration" during various
3443+
/// [`Resolve`] operations.
3444+
///
3445+
/// Methods on [`Resolve`] which mutate its internals, such as
3446+
/// [`Resolve::push_dir`] or [`Resolve::importize`] can fail if `world` imports
3447+
/// in WIT packages are invalid. This error indicates one of these situations
3448+
/// where an invalid dependency graph between imports and exports are detected.
3449+
///
3450+
/// Note that at this time this error is subtle and not easy to understand, and
3451+
/// work needs to be done to explain this better and additionally provide a
3452+
/// better error message. For now though this type enables callers to test for
3453+
/// the exact kind of error emitted.
3454+
#[derive(Debug, Clone)]
3455+
pub struct InvalidTransitiveDependency(String);
3456+
3457+
impl fmt::Display for InvalidTransitiveDependency {
3458+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3459+
write!(
3460+
f,
3461+
"interface `{}` transitively depends on an interface in \
3462+
incompatible ways",
3463+
self.0
3464+
)
3465+
}
3466+
}
3467+
3468+
impl std::error::Error for InvalidTransitiveDependency {}
3469+
34423470
#[cfg(test)]
34433471
mod tests {
34443472
use crate::Resolve;

crates/wit-smith/src/lib.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//! type structures.
77
88
use arbitrary::{Result, Unstructured};
9-
use wit_parser::Resolve;
9+
use wit_parser::{InvalidTransitiveDependency, Resolve};
1010

1111
mod config;
1212
pub use self::config::Config;
@@ -25,10 +25,7 @@ pub fn smith(config: &Config, u: &mut Unstructured<'_>) -> Result<Vec<u8>> {
2525
let id = match resolve.push_group(group) {
2626
Ok(id) => id,
2727
Err(e) => {
28-
if e.to_string().contains(
29-
"interface transitively depends on an interface in \
30-
incompatible ways",
31-
) {
28+
if e.is::<InvalidTransitiveDependency>() {
3229
return Err(arbitrary::Error::IncorrectFormat);
3330
}
3431
panic!("bad wit parse: {e:?}")

0 commit comments

Comments
 (0)