From dbbbcd58e57ecc75c5f1123aa9cdb6159526e7ad Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sun, 27 Apr 2025 18:37:40 +0100 Subject: [PATCH] Remove check that paths are inside game path It didn't work correctly for OpenMW or for additional data paths, fixing it would be significantly more complicated, and it doesn't really add any value. --- src/function/parse.rs | 111 +++--------------------------------------- src/lib.rs | 10 ---- 2 files changed, 8 insertions(+), 113 deletions(-) diff --git a/src/function/parse.rs b/src/function/parse.rs index 987904d..ebb39c0 100644 --- a/src/function/parse.rs +++ b/src/function/parse.rs @@ -1,4 +1,4 @@ -use std::path::{Component, Path, PathBuf}; +use std::path::PathBuf; use std::str; use nom::branch::alt; @@ -12,7 +12,7 @@ use regex::{Regex, RegexBuilder}; use super::{ComparisonOperator, Function}; use crate::error::ParsingErrorKind; -use crate::{map_err, whitespace, ParsingError, ParsingResult}; +use crate::{map_err, whitespace, ParsingResult}; impl ComparisonOperator { pub fn parse(input: &str) -> IResult<&str, ComparisonOperator> { @@ -32,20 +32,6 @@ const INVALID_PATH_CHARS: &str = "\":*?<>|"; const INVALID_NON_REGEX_PATH_CHARS: &str = "\":*?<>|\\"; // \ is treated as invalid to distinguish regex strings. const INVALID_REGEX_PATH_CHARS: &str = "\"<>"; -fn is_in_game_path(path: &Path) -> bool { - let mut previous_component = Component::CurDir; - for component in path.components() { - match (component, previous_component) { - (Component::Prefix(_) | Component::RootDir, _) - | (Component::ParentDir, Component::ParentDir) => return false, - (Component::CurDir, _) => {} - _ => previous_component = component, - } - } - - true -} - fn build_regex(input: &str) -> Result<(&'static str, Regex), regex::Error> { RegexBuilder::new(input) .case_insensitive(true) @@ -62,10 +48,6 @@ fn parse_anchored_regex(input: &str) -> ParsingResult { .map_err(|e| Err::Failure(ParsingErrorKind::from(e).at(input))) } -fn not_in_game_directory(input: &str, path: PathBuf) -> Err> { - Err::Failure(ParsingErrorKind::PathIsNotInGameDirectory(path).at(input)) -} - fn parse_path(input: &str) -> IResult<&str, PathBuf> { map( delimited(tag("\""), is_not(INVALID_PATH_CHARS), tag("\"")), @@ -89,11 +71,7 @@ fn parse_file_size_args(input: &str) -> ParsingResult<(PathBuf, u64)> { let (remaining_input, (path, _, size)) = parser.parse(input)?; - if is_in_game_path(&path) { - Ok((remaining_input, (path, size))) - } else { - Err(not_in_game_directory(input, path)) - } + Ok((remaining_input, (path, size))) } fn parse_version(input: &str) -> IResult<&str, String> { @@ -115,11 +93,7 @@ fn parse_version_args(input: &str) -> ParsingResult<(PathBuf, String, Comparison let (remaining_input, (path, _, version, _, comparator)) = map_err(parser).parse(input)?; - if is_in_game_path(&path) { - Ok((remaining_input, (path, version, comparator))) - } else { - Err(not_in_game_directory(input, path)) - } + Ok((remaining_input, (path, version, comparator))) } fn parse_filename_version_args( @@ -175,11 +149,7 @@ fn parse_checksum_args(input: &str) -> ParsingResult<(PathBuf, u32)> { let (remaining_input, (path, _, crc)) = parser.parse(input)?; - if is_in_game_path(&path) { - Ok((remaining_input, (path, crc))) - } else { - Err(not_in_game_directory(input, path)) - } + Ok((remaining_input, (path, crc))) } fn parse_non_regex_path(input: &str) -> ParsingResult { @@ -188,11 +158,7 @@ fn parse_non_regex_path(input: &str) -> ParsingResult { }) .parse(input)?; - if is_in_game_path(&path) { - Ok((remaining_input, path)) - } else { - Err(not_in_game_directory(input, path)) - } + Ok((remaining_input, path)) } /// Parse a string that is a path where the last component is a regex string @@ -210,10 +176,6 @@ fn parse_regex_path(input: &str) -> ParsingResult<(PathBuf, Regex)> { let parent_path = PathBuf::from(parent_path_slice); - if !is_in_game_path(&parent_path) { - return Err(not_in_game_directory(input, parent_path)); - } - let regex = parse_anchored_regex(regex_slice)?.1; Ok((remaining_input, (parent_path, regex))) @@ -356,6 +318,8 @@ impl Function { #[cfg(test)] mod tests { + use std::path::Path; + use super::*; #[test] @@ -397,11 +361,6 @@ mod tests { } } - #[test] - fn function_parse_should_error_if_the_file_path_is_outside_the_game_directory() { - assert!(Function::parse("file(\"../../Cargo.toml\")").is_err()); - } - #[test] fn function_parse_should_parse_a_file_regex_function_with_no_parent_path() { let output = Function::parse("file(\"Cargo.*\")").unwrap(); @@ -435,11 +394,6 @@ mod tests { assert!(Function::parse("file(\"sub\\dir/\")").is_err()); } - #[test] - fn function_parse_should_error_if_the_file_regex_parent_path_is_outside_the_game_directory() { - assert!(Function::parse("file(\"../../Cargo.*\")").is_err()); - } - #[test] fn function_parse_should_parse_a_file_size_function() { let output = Function::parse("file_size(\"Cargo.toml\", 1234)").unwrap(); @@ -454,11 +408,6 @@ mod tests { } } - #[test] - fn function_parse_should_error_if_the_file_size_is_outside_the_game_directory() { - assert!(Function::parse("file_size(\"../../Cargo.toml\", 1234)").is_err()); - } - #[test] fn function_parse_should_parse_a_readable_function() { let output = Function::parse("readable(\"Cargo.toml\")").unwrap(); @@ -470,11 +419,6 @@ mod tests { } } - #[test] - fn function_parse_should_error_if_the_readable_path_is_outside_the_game_directory() { - assert!(Function::parse("readable(\"../../Cargo.toml\")").is_err()); - } - #[test] fn function_parse_should_parse_an_is_executable_function() { let output = Function::parse("is_executable(\"Cargo.toml\")").unwrap(); @@ -486,11 +430,6 @@ mod tests { } } - #[test] - fn function_parse_should_error_if_the_is_executable_path_is_outside_the_game_directory() { - assert!(Function::parse("is_executable(\"../../Cargo.toml\")").is_err()); - } - #[test] fn function_parse_should_parse_an_active_path_function() { let output = Function::parse("active(\"Cargo.toml\")").unwrap(); @@ -502,13 +441,6 @@ mod tests { } } - #[test] - fn function_parse_should_error_if_the_active_path_is_outside_the_game_directory() { - // Trying to check if a path that isn't a plugin in the data folder is - // active is pointless, but it's not worth having a more specific check. - assert!(Function::parse("active(\"../../Cargo.toml\")").is_err()); - } - #[test] fn function_parse_should_parse_an_active_regex_function() { let output = Function::parse("active(\"Cargo.*\")").unwrap(); @@ -533,13 +465,6 @@ mod tests { } } - #[test] - fn function_parse_should_error_if_the_is_master_path_is_outside_the_game_directory() { - // Trying to check if a path that isn't a plugin in the data folder is - // active is pointless, but it's not worth having a more specific check. - assert!(Function::parse("is_master(\"../../Blank.esm\")").is_err()); - } - #[test] fn function_parse_should_parse_a_many_function_with_no_parent_path() { let output = Function::parse("many(\"Cargo.*\")").unwrap(); @@ -573,11 +498,6 @@ mod tests { assert!(Function::parse("many(\"subdir/\")").is_err()); } - #[test] - fn function_parse_should_error_if_the_many_parent_path_is_outside_the_game_directory() { - assert!(Function::parse("file(\"../../Cargo.*\")").is_err()); - } - #[test] fn function_parse_should_parse_a_many_active_function() { let output = Function::parse("many_active(\"Cargo.*\")").unwrap(); @@ -605,11 +525,6 @@ mod tests { } } - #[test] - fn function_parse_should_error_if_the_checksum_path_is_outside_the_game_directory() { - assert!(Function::parse("checksum(\"../../Cargo.toml\", DEADBEEF)").is_err()); - } - #[test] fn function_parse_should_parse_a_version_equals_function() { let output = Function::parse("version(\"Cargo.toml\", \"1.2\", ==)").unwrap(); @@ -715,11 +630,6 @@ mod tests { } } - #[test] - fn function_parse_should_error_if_the_version_path_is_outside_the_game_directory() { - assert!(Function::parse("version(\"../../Cargo.toml\", \"1.2\", ==)").is_err()); - } - #[test] fn function_parse_should_parse_a_product_version_equals_function() { let output = Function::parse("product_version(\"Cargo.toml\", \"1.2\", ==)").unwrap(); @@ -735,11 +645,6 @@ mod tests { } } - #[test] - fn function_parse_should_error_if_the_product_version_path_is_outside_the_game_directory() { - assert!(Function::parse("product_version(\"../../Cargo.toml\", \"1.2\", ==)").is_err()); - } - #[test] fn function_parse_should_parse_a_filename_version_equals_function() { let output = diff --git a/src/lib.rs b/src/lib.rs index fa200c3..3847195 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -488,16 +488,6 @@ mod tests { ); } - #[test] - fn expression_from_str_should_error_with_input_on_path_outside_game_directory() { - let error = Expression::from_str("file(\"../../Cargo.toml\")").unwrap_err(); - - assert_eq!( - "An error was encountered while parsing the expression \"../../Cargo.toml\\\")\": \"../../Cargo.toml\" is not in the game directory", - error.to_string() - ); - } - #[test] fn expression_parse_should_handle_a_single_compound_condition() { let result = Expression::from_str("file(\"Cargo.toml\")").unwrap();