Skip to content

Commit

Permalink
fix: fix handling trailing slash in symbolic link files
Browse files Browse the repository at this point in the history
  • Loading branch information
imlk0 authored and oxr463 committed Jul 28, 2021
1 parent 7da26dd commit 11e63b2
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/filesystem/canonicalization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use crate::filesystem::binding::Side;
use crate::filesystem::substitution::Substitutor;
use crate::filesystem::FileSystem;

use super::ext::{PathBufExt, PathExt};

pub trait Canonicalizer {
fn canonicalize<P: AsRef<Path>>(&self, path: P, deref_final: bool) -> Result<PathBuf>;
}
Expand Down Expand Up @@ -59,6 +61,8 @@ impl Canonicalizer for FileSystem {
));
}

let trailing_slash = guest_path.with_trailing_slash();

// build guest_path_new from user_path
let mut guest_path_new = PathBuf::new();

Expand Down Expand Up @@ -133,13 +137,22 @@ impl Canonicalizer for FileSystem {
if let Some(comp) = next_comp {
new_user_path.push(comp);
}
new_user_path.push(it);
it.for_each(|comp| new_user_path.push(comp));
if trailing_slash {
// recover the trailing slash
new_user_path.try_add_trailing_slash();
}
// use new_user_path to call this function again and return
// TODO: Can be optimized by replacing `it`
return self.canonicalize(&new_user_path, deref_final);
}
// we cannot go through a path which is neither a directory nor a symlink
if !is_last_component {
if !is_last_component
|| (is_last_component
&& !file_type.is_dir()
&& !file_type.is_symlink()
&& trailing_slash)
{
return Err(Error::errno_with_msg(
Errno::ENOTDIR,
"when canonicalizing an intermediate path",
Expand Down
27 changes: 27 additions & 0 deletions tests/applets.bats
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,30 @@ function script_test_should_not_follow {
[ "$status" -eq 0 ]

}



function script_test_trailing_slash_in_symlink {
PATH=/bin

cd /tmp/test_trailing_slash_in_symlink

echo "hello world" > file
ln -s file link1
ln -s file/ link2
ln -s file/. link3

[[ "$(stat -L -c "%F" link1 2>&1)" == *"regular file"* ]]
[[ "$(stat -L -c "%F" link2 2>&1)" == *"Not a directory"* ]]
[[ "$(stat -L -c "%F" link3 2>&1)" == *"Not a directory"* ]]

}

@test "test trailing slash in symlink" {
local test_dir="$ROOTFS/tmp/test_trailing_slash_in_symlink"
mkdir "$test_dir"
runp proot-rs --rootfs "$ROOTFS" -- /bin/sh -e -x -c "$(declare -f script_test_trailing_slash_in_symlink); script_test_trailing_slash_in_symlink"
rm -rf "$test_dir"
[ "$status" -eq 0 ]

}

0 comments on commit 11e63b2

Please sign in to comment.