Skip to content

Commit 39eaa28

Browse files
committed
Fix stale exports/imports/definitions after unregister_package
unregister_package() called retain_nodes() to remove nodes associated with a package, but did not clean up the exports, defined, and imports maps. This left stale NodeIndex references that could cause panics or incorrect behavior when those maps were subsequently accessed. Now cleans up all three maps before removing nodes from the graph. Added a test that verifies exports are properly cleaned up after unregistering a package.
1 parent e1e684a commit 39eaa28

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

crates/wac-graph/src/graph.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,15 @@ impl CompositionGraph {
543543
"invalid package id"
544544
);
545545

546+
// Remove exports and definitions associated with the package before
547+
// removing nodes, as retain_nodes invalidates the node indices.
548+
self.exports
549+
.retain(|_, n| self.graph[*n].package != Some(package));
550+
self.defined
551+
.retain(|_, n| self.graph[*n].package != Some(package));
552+
self.imports
553+
.retain(|_, n| self.graph[*n].package != Some(package));
554+
546555
// Remove all nodes associated with the package
547556
self.graph
548557
.retain_nodes(|g, i| g[i].package != Some(package));
@@ -1959,4 +1968,39 @@ mod test {
19591968
UnexportError::MustExportDefinition
19601969
));
19611970
}
1971+
1972+
#[test]
1973+
fn it_cleans_up_exports_on_unregister_package() {
1974+
let mut graph = CompositionGraph::new();
1975+
let bytes = wat::parse_str(
1976+
r#"(component
1977+
(import "f" (func))
1978+
(export "g" (func 0))
1979+
)"#,
1980+
)
1981+
.unwrap();
1982+
1983+
let package = wac_types::Package::from_bytes(
1984+
"test:pkg",
1985+
None,
1986+
bytes,
1987+
graph.types_mut(),
1988+
)
1989+
.unwrap();
1990+
let pkg_id = graph.register_package(package).unwrap();
1991+
1992+
// Create an instantiation and export an alias
1993+
let inst_id = graph.instantiate(pkg_id);
1994+
let alias_id = graph.alias_instance_export(inst_id, "g").unwrap();
1995+
graph.export(alias_id, "g").unwrap();
1996+
1997+
assert!(graph.get_export("g").is_some());
1998+
1999+
// Unregistering the package should clean up exports
2000+
graph.unregister_package(pkg_id);
2001+
assert!(
2002+
graph.get_export("g").is_none(),
2003+
"exports should be cleaned up after unregister_package"
2004+
);
2005+
}
19622006
}

0 commit comments

Comments
 (0)