From fe11b9d31971259959f5e6eb14510d9021738d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9lanie=20Chauvel?= Date: Thu, 13 May 2021 02:10:36 +0200 Subject: [PATCH] Fix panic on non UTF-8 file when using Git --- devtools/dev-create-test-filesystem.sh | 20 +++++++++++++++++--- src/fs/feature/git.rs | 8 ++++++++ xtests/git.toml | 12 ++++++++++++ xtests/outputs/git4_long.ansitxt | 1 + 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 xtests/outputs/git4_long.ansitxt diff --git a/devtools/dev-create-test-filesystem.sh b/devtools/dev-create-test-filesystem.sh index 112b569..74d5e2e 100755 --- a/devtools/dev-create-test-filesystem.sh +++ b/devtools/dev-create-test-filesystem.sh @@ -252,7 +252,7 @@ sudo chown $FIXED_USER:$FIXED_USER -R "$TEST_ROOT/attributes" # A sample Git repository # This uses cd because it's easier than telling Git where to go each time -echo -e "\033[1m[10/13]\033[0m Creating Git testcases (1/3)" +echo -e "\033[1m[10/13]\033[0m Creating Git testcases (1/4)" mkdir "$TEST_ROOT/git" cd "$TEST_ROOT/git" git init >/dev/null @@ -281,7 +281,7 @@ sudo chown $FIXED_USER:$FIXED_USER -R "$TEST_ROOT/git" # A second Git repository # for testing two at once -echo -e "\033[1m[11/13]\033[0m Creating Git testcases (2/3)" +echo -e "\033[1m[11/13]\033[0m Creating Git testcases (2/4)" mkdir -p "$TEST_ROOT/git2/deeply/nested/directory" cd "$TEST_ROOT/git2" git init >/dev/null @@ -321,7 +321,7 @@ sudo chown $FIXED_USER:$FIXED_USER -R "$TEST_ROOT/git2" # A third Git repository # Regression test for https://github.com/ogham/exa/issues/526 -echo -e "\033[1m[12/13]\033[0m Creating Git testcases (3/3)" +echo -e "\033[1m[12/13]\033[0m Creating Git testcases (3/4)" mkdir -p "$TEST_ROOT/git3" cd "$TEST_ROOT/git3" git init >/dev/null @@ -334,6 +334,20 @@ find "$TEST_ROOT/git3" -exec touch {} -h -t $FIXED_DATE \; sudo chown $FIXED_USER:$FIXED_USER -R "$TEST_ROOT/git3" +# A fourth Git repository +# Regression test for https://github.com/ogham/exa/issues/698 +echo -e "\033[1m[12/13]\033[0m Creating Git testcases (4/4)" +mkdir -p "$TEST_ROOT/git4" +cd "$TEST_ROOT/git4" +git init >/dev/null + +# Create a non UTF-8 file +touch 'P'$'\b\211''UUU' + +find "$TEST_ROOT/git4" -exec touch {} -h -t $FIXED_DATE \; +sudo chown $FIXED_USER:$FIXED_USER -R "$TEST_ROOT/git4" + + # Hidden and dot file testcases. # We need to set the permissions of `.` and `..` because they actually # get displayed in the output here, so this has to come last. diff --git a/src/fs/feature/git.rs b/src/fs/feature/git.rs index 40bc80d..1a0c60d 100644 --- a/src/fs/feature/git.rs +++ b/src/fs/feature/git.rs @@ -1,5 +1,8 @@ //! Getting the Git status of files and directories. +use std::ffi::OsStr; +#[cfg(target_family = "unix")] +use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; use std::sync::Mutex; @@ -205,6 +208,11 @@ fn repo_to_statuses(repo: &git2::Repository, workdir: &Path) -> Git { match repo.statuses(None) { Ok(es) => { for e in es.iter() { + #[cfg(target_family = "unix")] + let path = workdir.join(Path::new(OsStr::from_bytes(e.path_bytes()))); + // TODO: handle non Unix systems better: + // https://github.com/ogham/exa/issues/698 + #[cfg(not(target_family = "unix"))] let path = workdir.join(Path::new(e.path().unwrap())); let elem = (path, e.status()); statuses.push(elem); diff --git a/xtests/git.toml b/xtests/git.toml index c262e9e..ea64cad 100644 --- a/xtests/git.toml +++ b/xtests/git.toml @@ -144,6 +144,18 @@ status = 0 tags = [ 'long', 'git' ] + +# The forth Git repo: non UTF-8 file + +[[cmd]] +name = "‘exa --git -l’ handles non UTF8 file in Git repositories" +shell = "exa --git -l /testcases/git4" +stdout = { file = "outputs/git4_long.ansitxt" } +stderr = { empty = true } +status = 0 +tags = [ 'long', 'git' ] + + # Both repositories 1 and 2 at once [[cmd]] diff --git a/xtests/outputs/git4_long.ansitxt b/xtests/outputs/git4_long.ansitxt new file mode 100644 index 0000000..3f8fba6 --- /dev/null +++ b/xtests/outputs/git4_long.ansitxt @@ -0,0 +1 @@ +.rw-rw-r-- 0 cassowary  1 Jan 12:34 -N P\u{8}�UUU