diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c4b61d7..2d8102a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - bat mishighlights Users that start with digits in SSH config, see #984 - `--map-syntax` doesn't work with names provided through `--file-name` (@eth-p) - Fix syntax detection for files called 'rails', see #1008 +- Fix potential errors with syntax detection for symlinked files, see #1001 ## Other diff --git a/Cargo.lock b/Cargo.lock index 515aa7c0..0f7f0188 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,6 +107,7 @@ dependencies = [ "globset 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "liquid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "path-absolutize 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -732,6 +733,23 @@ name = "opaque-debug" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "path-absolutize" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "path-dedot 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slash-formatter 2.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "path-dedot" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "percent-encoding" version = "1.0.1" @@ -1034,6 +1052,11 @@ name = "shell-words" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "slash-formatter" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "smallvec" version = "1.3.0" @@ -1390,6 +1413,8 @@ dependencies = [ "checksum onig 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd91ccd8a02fce2f7e8a86655aec67bc6c171e6f8e704118a0e8c4b866a05a8a" "checksum onig_sys 69.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3814583fad89f3c60ae0701d80e87e1fd3028741723deda72d0d4a0ecf0cb0db" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +"checksum path-absolutize 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f75bd79ae25b4cd5c4d4b6d11c11863c2ebee5d1eed4f6d687fcdd232df3a8dc" +"checksum path-dedot 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4cf32f6a3b529384739d9c11c230ad760aeb553061e7834f58de63a7c507f24f" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" "checksum pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" @@ -1427,6 +1452,7 @@ dependencies = [ "checksum serde_yaml 0.8.12 (registry+https://github.com/rust-lang/crates.io-index)" = "16c7a592a1ec97c9c1c68d75b6e537dcbf60c7618e038e7841e00af1d9ccf0c4" "checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" "checksum shell-words 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6fa3938c99da4914afedd13bf3d79bcb6c277d1b2c398d23257a304d9e1b074" +"checksum slash-formatter 2.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f7fb98e76e2022054673f3ebc43a4e12890ec6272530629df6237cafbb70569" "checksum smallvec 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05720e22615919e4734f6a99ceae50d00226c3c5aca406e102ebc33298214e0a" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" diff --git a/Cargo.toml b/Cargo.toml index bc7d07b1..a6c730b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ globset = "0.4" serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.8" semver = "0.9" +path-absolutize = "1.2.0" [dependencies.git2] version = "0.13" diff --git a/src/assets.rs b/src/assets.rs index d265c4c4..0de506f3 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -8,6 +8,8 @@ use syntect::dumps::{dump_to_file, from_binary, from_reader}; use syntect::highlighting::{Theme, ThemeSet}; use syntect::parsing::{SyntaxReference, SyntaxSet, SyntaxSetBuilder}; +use path_absolutize::Absolutize; + use crate::assets_metadata::AssetsMetadata; use crate::error::*; use crate::input::{InputReader, OpenedInput, OpenedInputKind}; @@ -218,7 +220,7 @@ impl HighlightingAssets { if let Some(path_str) = path_str { // If a path was provided, we try and detect the syntax based on extension mappings. let path = Path::new(path_str); - let absolute_path = path.canonicalize().ok().unwrap_or_else(|| path.to_owned()); + let absolute_path = path.absolutize().ok().unwrap_or_else(|| path.to_owned()); match mapping.get_syntax_for(absolute_path) { Some(MappingTarget::MapToUnknown) => line_syntax.ok_or_else(|| { @@ -281,7 +283,7 @@ mod tests { struct SyntaxDetectionTest<'a> { assets: HighlightingAssets, pub syntax_mapping: SyntaxMapping<'a>, - temp_dir: TempDir, + pub temp_dir: TempDir, } impl<'a> SyntaxDetectionTest<'a> { @@ -482,14 +484,32 @@ mod tests { ); } + #[cfg(unix)] #[test] - fn issue_1008() { + fn syntax_detection_for_symlinked_file() { + use std::os::unix::fs::symlink; + let test = SyntaxDetectionTest::new(); + let file_path = test.temp_dir.path().join("my_ssh_config_filename"); + { + File::create(&file_path).unwrap(); + } + let file_path_symlink = test.temp_dir.path().join(".ssh").join("config"); + + std::fs::create_dir(test.temp_dir.path().join(".ssh")) + .expect("creation of directory succeeds"); + symlink(&file_path, &file_path_symlink).expect("creation of symbolic link succeeds"); + + let input = Input::ordinary_file(file_path_symlink.as_os_str()); + let dummy_stdin: &[u8] = &[]; + let mut opened_input = input.open(dummy_stdin).unwrap(); assert_eq!( - test.syntax_for_file_with_content("bin/rails", "#!/usr/bin/env ruby"), - "Ruby" + test.assets + .get_syntax(None, &mut opened_input, &test.syntax_mapping) + .unwrap_or_else(|_| test.assets.syntax_set.find_syntax_plain_text()) + .name, + "SSH Config" ); - assert_eq!(test.syntax_for_file("example.rails"), "HTML (Rails)"); } }