(vec: Vec<u8>, should_follow: bool, dirfd: HostFd)
| 25 | } |
| 26 | )] |
| 27 | fn expand_path(vec: Vec<u8>, should_follow: bool, dirfd: HostFd) -> RuntimeResult<OwnedComponents> { |
| 28 | let p = to_pathbuf(vec); |
| 29 | let components = get_components(&p); |
| 30 | |
| 31 | let mut out_path = fresh_components(); |
| 32 | let mut num_symlinks = 0; |
| 33 | let mut idx = 0; |
| 34 | |
| 35 | while idx < components.len() { |
| 36 | body_invariant!(!is_symlink(&out_path)); |
| 37 | // out_path should never contain symlinks |
| 38 | body_invariant!(forall(|i: usize| i < out_path.len() ==> !is_symlink(out_path.prefix(i)) ) ); |
| 39 | let comp = components[idx]; |
| 40 | let c = OwnedComponent::from_borrowed(&comp); |
| 41 | // if this is the last element, and we are NO_FOLLOW, then don't expand |
| 42 | if !should_follow && idx + 1 == components.len() { |
| 43 | out_path.push(c); |
| 44 | break; |
| 45 | } |
| 46 | // if comp is a symlink, return path + update num_symlinks |
| 47 | // if not, just extend out_path |
| 48 | let maybe_linkpath = maybe_expand_component(dirfd, &mut out_path, c, &mut num_symlinks); |
| 49 | |
| 50 | if let Some(linkpath) = maybe_linkpath { |
| 51 | expand_symlink(&mut out_path, linkpath, &mut num_symlinks, dirfd); |
| 52 | } |
| 53 | if num_symlinks >= MAXSYMLINKS { |
| 54 | return Err(RuntimeError::Eloop); |
| 55 | } |
| 56 | idx += 1; |
| 57 | } |
| 58 | //assert!(!should_follow || (should_follow && !is_symlink(&out_path))); |
| 59 | Ok(out_path) |
| 60 | } |
| 61 | |
| 62 | #[ensures( |
| 63 | match &result { |
no test coverage detected