Skip to content

Commit

Permalink
fix: fast_transfer_file API 分发文件,如果源文件中的文件名包含空格,会报错 TencentBlueKing#812
Browse files Browse the repository at this point in the history
  • Loading branch information
liuliaozhong committed May 12, 2023
1 parent 6869f7d commit 80980e7
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
package com.tencent.bk.job.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.regex.Pattern;

/**
* 文件路径合法性校验工具类
*/
@Slf4j
public class FilePathValidateUtil {
// 传统DOS正则表达式
private static final String CONVENTIONAL_DOS_PATH_REGEX = "(^[A-Za-z]:\\\\([^\\\\])(([^\\\\/:*?\"<>|])*\\\\?)*)|" +
"(^[A-Za-z]:[\\\\])";
private static final String CONVENTIONAL_DOS_PATH_REGEX = "(^[A-Za-z]:\\\\([^\\\\])(([^\\\\/:?\"<>|]" +
"|REGEX:(.*))*\\\\?)*)|(^[A-Za-z]:[\\\\])";

// Linux路径正则表达式
private static final String LINUX_PATH_REGEX = "^/(((../)*|(./)*)|(\\.?[^.].*/{0,1}))+";

// 内置变量或全局变量正则表达式
private static final String VARIABLE_REGEX = "(([A-Za-z]:\\\\)|(/)).*\\[[a-zA-Z0-9:/_-]*\\].*" +
"|.*\\$\\{[a-zA-Z_][a-zA-Z0-9_-]*\\}.*";

// 传统DOS Pattern
private static final Pattern CONVENTIONAL_DOS_PATH_PATTERN = Pattern.compile(CONVENTIONAL_DOS_PATH_REGEX);
// Linux路径Pattern
private static final Pattern LINUX_PATH_PATTERN = Pattern.compile(LINUX_PATH_REGEX);
// 内置变量或全局变量Pattern
private static final Pattern VARIABLE_PATTERN = Pattern.compile(VARIABLE_REGEX);

/**
* 验证文件系统绝对路径的合法性
Expand All @@ -28,11 +37,24 @@ public static boolean validateFileSystemAbsolutePath(String path) {
if (StringUtils.isBlank(path)) {
return false;
}

// 路径中有合法的内置变量或全局变量通过校验
if (validateVariable(path)) {
log.warn("The path {} contains legal variables", path);
return true;
}

boolean result;
if (isLinuxAbsolutePath(path)) {
return validateLinuxFileSystemAbsolutePath(path);
result = validateLinuxFileSystemAbsolutePath(path);
} else {
return validateWindowsFileSystemAbsolutePath(path);
result = validateWindowsFileSystemAbsolutePath(path);
}
if (!result) {
// 路径不合法
log.error("The path {} is invalid and the verification fails", path);
}
return result;
}

/**
Expand Down Expand Up @@ -77,4 +99,19 @@ private static boolean validateLinuxFileSystemAbsolutePath(String path) {
}
return false;
}

/**
* 验证路径中变量合法性
* 1 ${全局变量},其中变量只能是英文字符、下划线开头;只允许英文字符、数字、下划线、和-
* 2 [内置变量],根路径开头
*
* @param path
* @return boolean
*/
private static boolean validateVariable(String path) {
if (VARIABLE_PATTERN.matcher(path).matches()) {
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@ void testFileSystemAbsolutePath(){
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\logs\\..\\access.log")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\.config\\conf")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\user\\abc>a")).isFalse();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\user\\abc:a")).isFalse();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\user\\abc|a")).isFalse();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\user\\abc?a")).isFalse();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\user\\abc<a")).isFalse();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\logs/logs")).isFalse();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\logs\\log*.log")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\tmp\\REGEX:myfile-[A-Za-z]{0,10}.tar.gz")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\tmp\\REGE:a|b")).isFalse();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\tmp\\REGEX:a|b")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\tmp\\REGEX:^[a-zA-Z0-9]")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("[FILESRCIP]\\logs")).isFalse();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\[FILESRCIP]\\logs")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\[DATE:yyyy-MM-dd]\\logs")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("${path}")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("${!#path}")).isFalse();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("${_path}")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("${path}\\test.txt")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\tmp\\${path}")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\${date}\\${path}")).isTrue();

// linux路径
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/data/test_2022-04-12.apk")).isTrue();
Expand All @@ -30,7 +49,21 @@ void testFileSystemAbsolutePath(){
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("///")).isTrue(); // 根目录
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp////")).isTrue(); // /tmp/
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp//test/")).isTrue();// /tmp/test/
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("///")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/abc>a")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/abc:a")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/abc|a")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/abc?a")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/abc<a")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/logs/log*.log")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/REGEX:myfile-[A-Za-z]{0,10}.tar.gz")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/REGEX:aa|bb")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("[FILESRCIP]/logs")).isFalse();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/[FILESRCIP]/logs")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/[DATE:yyyy-MM-dd]/logs")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("${path}/test.txt")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("${path}/../test.txt")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/[FILESRCIP]/${path}")).isTrue();
assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/${path}")).isTrue();
}

}

0 comments on commit 80980e7

Please sign in to comment.