Closed d0nutptr closed 4 months ago
That's interesting. I'll look into this.
Just trying that test and set it to run in a loop, I haven't seen it fail yet. I'm using ubuntu, which OS did you use ? & Does it take several runs to fail ?
Hey! Yea it can take a few goes in practice to crash.
It is exceedingly rare to find a situation where this happens in practice.
I fuzzed millions of configurations of files to see if i could make a smaller poc to send and came up with nothing.
If you run the above provided test case, though, it should be 100% reproducible.
Oh, and yes I use ubuntu :)
I see how this could happen. So this is genuine. (I just can't yet reproduce it). Going to have to think about this.
We could catch the panic and sort by name if that happens.
This is helping me think about it: I codifed your description in the issue:
#[test]
fn test_total_ordering_of_sort_by_inode() {
let a = Node {
name: PathBuf::from_str("a").unwrap(),
size: 0,
children: vec![],
inode_device: Some((3, 66310)),
depth: 0,
};
let b = Node {
name: PathBuf::from_str("b").unwrap(),
size: 0,
children: vec![],
inode_device: None,
depth: 0,
};
let c = Node {
name: PathBuf::from_str("c").unwrap(),
size: 0,
children: vec![],
inode_device: Some((1, 66310)),
depth: 0,
};
assert_eq!(sort_by_inode(&a, &b), Ordering::Less); //a < b
assert_eq!(sort_by_inode(&a, &c), Ordering::Greater); // a > c
assert_eq!(sort_by_inode(&c, &b), Ordering::Greater); // c > b
// Transitivity fail
assert_eq!(sort_by_inode(&c, &a), Ordering::Less);
assert_eq!(sort_by_inode(&a, &c), Ordering::Greater);
assert_eq!(sort_by_inode(&c, &a), Ordering::Less);
}
https://github.com/bootandy/dust/pull/408
does this look like it would fix it ?
I think it would!
I wrote a simple hardness to formally verify the Ord property so let me try this new implementation to see if it can find a violation.
I assume I wrote a relatively reasonable definition to check total order here, but it looks like it verified! :ship: it
Hello!
I happened to run into an interesting edge-case while cleaning up a few projects. While running
dust
in a folder containing both files and symlinks I encountered this odd panic.I debugged the issue and discovered the issue is caused by
sort_by_inode
indir_walker.rs
. The problem is that the implementation provided does not guarantee a total ordering if both files and symlinks are present. For example:Assume the folder contains the following nodes with names and
inode_device
s:There does not exist a total order as there exists no way to order these three files in a way where the following comparisons are satisfied:
I tried to make as small of a testcase as possible, but it was actually really hard to trigger the behavior. This is the smallest test I could create that exhibited the crash: