common_utils/
fs.rs

1use std::path::{self, Path, PathBuf};
2
3use crate::strings::is_repeat;
4
5/// ### 路径拼接
6///
7/// 安全路径拼接,会主动忽略跳父目录,从而避免特殊参数注入以夸路径修改特定文件
8#[allow(dead_code)]
9pub fn safe_join_path(path1: String, path2: String) -> PathBuf {
10    Path::new(safe_path(path1).as_str()).join(safe_path(path2))
11}
12
13#[test]
14fn test_path_join() {
15    assert_eq!(
16        PathBuf::from("a/b/c"),
17        safe_join_path(String::from("a"), String::from("../b/..../c"))
18    );
19}
20
21/// 计算安全路径
22///
23/// 可以防止路径访问上级目录,即 ../
24#[allow(dead_code)]
25pub fn safe_path(raw_path: String) -> String {
26    let mut result: String = String::from("");
27    for segment in raw_path.split(path::MAIN_SEPARATOR) {
28        if segment == ""
29            || (is_repeat(segment.to_string())
30                && segment.chars().collect::<Box<[char]>>()[0] == '.')
31        {
32            continue;
33        }
34        result.push_str(segment);
35        result.push_str(&String::from(path::MAIN_SEPARATOR));
36    }
37    result.pop();
38    result
39}
40
41#[test]
42fn test_safe_path() {
43    assert_eq!(String::from("a/b/c"), safe_path(String::from("a/../b/c")));
44}