From 433746e13cce721c01da543850e046cc249ca739 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Tue, 10 Jan 2017 09:19:02 -0700 Subject: [PATCH] Move skipping to loop encompasing entire path --- src/context/context.rs | 88 ++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 42 deletions(-) diff --git a/src/context/context.rs b/src/context/context.rs index b594b60d..54abd3d6 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -124,7 +124,7 @@ impl Context { /// "/foo" will turn into "scheme:/foo" /// "bar:/foo" will be used directly, as it is already absolute pub fn canonicalize(&self, path: &[u8]) -> Vec<u8> { - if path.iter().position(|&b| b == b':').is_none() { + let mut canon = if path.iter().position(|&b| b == b':').is_none() { let cwd = self.cwd.lock(); if path == b"." { cwd.clone() @@ -145,50 +145,54 @@ impl Context { }; canon.extend_from_slice(&path); - // NOTE: assumes the scheme does not include anything like "../" or "./" - let mut result = { - let parts = canon.split(|&c| c == b'/') - .filter(|&part| part != b".") - .rev() - .scan(0, |nskip, part| { - if part == b".." { - *nskip += 1; - Some(None) - } else { - if *nskip > 0 { - *nskip -= 1; - Some(None) - } else { - Some(Some(part)) - } - } - }) - .filter_map(|x| x) - .collect::<Vec<_>>(); - parts - .iter() - .rev() - .fold(Vec::new(), |mut vec, &part| { - vec.extend_from_slice(part); - vec.push(b'/'); - vec - }) - }; - result.pop(); // remove extra '/' - - // replace with the root of the schema if it's empty - if result.len() == 0 { - let pos = canon.iter() - .position(|&b| b == b':') - .map_or(canon.len(), |p| p + 1); - canon.truncate(pos); - canon - } else { - result - } + canon } } else { path.to_vec() + }; + + // NOTE: assumes the scheme does not include anything like "../" or "./" + let mut result = { + let parts = canon.split(|&c| c == b'/') + .filter(|&part| part != b".") + .rev() + .scan(0, |nskip, part| { + if part == b"." { + Some(None) + } else if part == b".." { + *nskip += 1; + Some(None) + } else { + if *nskip > 0 { + *nskip -= 1; + Some(None) + } else { + Some(Some(part)) + } + } + }) + .filter_map(|x| x) + .collect::<Vec<_>>(); + parts + .iter() + .rev() + .fold(Vec::new(), |mut vec, &part| { + vec.extend_from_slice(part); + vec.push(b'/'); + vec + }) + }; + result.pop(); // remove extra '/' + + // replace with the root of the scheme if it's empty + if result.len() == 0 { + let pos = canon.iter() + .position(|&b| b == b':') + .map_or(canon.len(), |p| p + 1); + canon.truncate(pos); + canon + } else { + result } } -- GitLab