|
| 1 | +#![no_main] |
| 2 | + |
| 3 | +use arbitrary::{Arbitrary, Unstructured}; |
| 4 | +use libfuzzer_sys::fuzz_target; |
| 5 | +use rustworkx_core::dictmap::DictMap; |
| 6 | +use rustworkx_core::petgraph::graph::Graph; |
| 7 | +use rustworkx_core::petgraph::prelude::*; |
| 8 | +use rustworkx_core::petgraph::Undirected; |
| 9 | +use rustworkx_core::shortest_path::{bellman_ford, dijkstra}; |
| 10 | +use rustworkx_core::Result; |
| 11 | + |
| 12 | +#[derive(Debug, Arbitrary)] |
| 13 | +struct FuzzGraph { |
| 14 | + edges: Vec<(usize, usize, u32)>, |
| 15 | + node_count: usize, |
| 16 | +} |
| 17 | + |
| 18 | +fuzz_target!(|data: &[u8]| { |
| 19 | + if let Ok(input) = FuzzGraph::arbitrary(&mut Unstructured::new(data)) { |
| 20 | + fuzz_check_bellman_vs_dijkstra(&input); |
| 21 | + } |
| 22 | +}); |
| 23 | + |
| 24 | +fn fuzz_check_bellman_vs_dijkstra(input: &FuzzGraph) { |
| 25 | + if input.node_count == 0 || input.edges.is_empty() || input.node_count > 1000 { |
| 26 | + return; |
| 27 | + } |
| 28 | + |
| 29 | + let node_count = input.node_count.min(512); |
| 30 | + |
| 31 | + let mut graph = Graph::<(), i32, Undirected>::new_undirected(); |
| 32 | + let mut nodes = Vec::with_capacity(node_count); |
| 33 | + for _ in 0..node_count { |
| 34 | + nodes.push(graph.add_node(())); |
| 35 | + } |
| 36 | + |
| 37 | + for &(u, v, w) in &input.edges { |
| 38 | + if u < node_count && v < node_count { |
| 39 | + let safe_weight = (w % 10_000) as i32; |
| 40 | + graph.add_edge(nodes[u], nodes[v], safe_weight); |
| 41 | + } |
| 42 | + } |
| 43 | + |
| 44 | + let start_node = nodes[0]; |
| 45 | + |
| 46 | + let bf_res: Result<Option<DictMap<NodeIndex, i32>>> = |
| 47 | + bellman_ford(&graph, start_node, |e| Ok(*e.weight()), None); |
| 48 | + |
| 49 | + let dijk_res: Result<DictMap<NodeIndex, i32>> = |
| 50 | + dijkstra(&graph, start_node, None, |e| Ok(*e.weight()), None); |
| 51 | + |
| 52 | + match (bf_res, dijk_res) { |
| 53 | + (Ok(Some(bf_map)), Ok(dijk_map)) => { |
| 54 | + assert_eq!( |
| 55 | + bf_map, dijk_map, |
| 56 | + "Mismatch between Bellman-Ford and Dijkstra" |
| 57 | + ); |
| 58 | + } |
| 59 | + (Ok(None), _) => { |
| 60 | + panic!("Bellman-Ford returned None (negative cycle) on non-negative-weight graph"); |
| 61 | + } |
| 62 | + (Err(e), _) | (_, Err(e)) => { |
| 63 | + panic!("Fuzzing caused an unexpected error: {e:?}"); |
| 64 | + } |
| 65 | + } |
| 66 | +} |
0 commit comments