1
1
mirror of https://github.com/tweag/nickel.git synced 2024-07-07 08:26:29 +03:00

Convert paths to absolute before normalization (#1489)

* Add test

* Fix test

* Convert paths to absolute before normalization

The path normalization function doesn't work on paths starting with '..'.
One fix is to make paths absolute.

* Add comment
This commit is contained in:
jneem 2023-07-31 07:52:20 -05:00 committed by GitHub
parent c4ac9c368a
commit dc76b14556
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 4 deletions

3
.gitignore vendored
View File

@ -27,3 +27,6 @@
# Python virtual env
.venv/
venv/
# helix configuration
.helix/

View File

@ -289,7 +289,7 @@ impl Cache {
pub fn add_file(&mut self, path: impl Into<OsString>) -> io::Result<FileId> {
let path = path.into();
let timestamp = timestamp(&path)?;
let normalized = normalize_path(PathBuf::from(&path).as_path());
let normalized = normalize_path(&path)?;
self.add_file_(normalized, timestamp)
}
@ -298,7 +298,7 @@ impl Cache {
/// If it was not in cache, try to read it from the filesystem and add it as a new entry.
pub fn get_or_add_file(&mut self, path: impl Into<OsString>) -> io::Result<CacheOp<FileId>> {
let path = path.into();
let normalized = normalize_path(PathBuf::from(&path).as_path());
let normalized = normalize_path(&path)?;
match self.id_or_new_timestamp_of(&path)? {
SourceState::UpToDate(id) => Ok(CacheOp::Cached(id)),
SourceState::Stale(timestamp) => {
@ -1241,7 +1241,18 @@ fn with_parent(path: &OsStr, parent: Option<PathBuf>) -> PathBuf {
/// Normalize the path of a file for unique identification in the cache.
///
/// This implementation (including the commend below) was taken from cargo-util.
/// The returned path will be an absolute path.
pub fn normalize_path(path: &OsStr) -> std::io::Result<OsString> {
let mut path = PathBuf::from(path);
if path.is_relative() {
path = std::env::current_dir()?.join(path);
}
Ok(normalize_abs_path(&path))
}
/// Normalize the path (assumed to be absolute) of a file for unique identification in the cache.
///
/// This implementation (including the comment below) was taken from cargo-util.
///
/// CAUTION: This does not resolve symlinks (unlike
/// [`std::fs::canonicalize`]). This may cause incorrect or surprising
@ -1249,7 +1260,7 @@ fn with_parent(path: &OsStr, parent: Option<PathBuf>) -> PathBuf {
/// [`std::fs::canonicalize`] can be hard to use correctly, since it can often
/// fail, or on Windows returns annoying device paths. This is a problem Cargo
/// needs to improve on.
pub fn normalize_path(path: &Path) -> OsString {
fn normalize_abs_path(path: &Path) -> OsString {
use std::path::Component;
let mut components = path.components().peekable();

View File

@ -0,0 +1,2 @@
# test.type = 'pass'
import "../root_path.ncl"

View File

@ -37,6 +37,25 @@ fn check_annotated_nickel_file(path: &str) {
.expect("Failed to join thread")
}
// Like check_annotated_nickel_file, but runs the test from the directory of
// the test file itself (and opens the test file with a relative path). This
// is mainly for integration testing path normalization.
#[test_resources("core/tests/integration/imports/imported/import_parent.ncl")]
fn check_from_dir(path: &str) {
let test: TestCase<Test> =
read_annotated_test_case(path).expect("Failed to parse annotated program");
let path = project_root().join(path);
let dir = std::env::current_dir().unwrap();
let test_dir = path.parent().unwrap();
std::env::set_current_dir(test_dir).unwrap();
run_test(
test,
String::from(path.file_name().unwrap().to_string_lossy()),
);
std::env::set_current_dir(dir).unwrap();
}
fn run_test(test_case: TestCase<Test>, path: String) {
let repeat = test_case.annotation.repeat.unwrap_or(1);
let eval_strategy = test_case.annotation.eval.unwrap_or(EvalStrategy::Standard);