From 83fd4ac6091ceb7cfec3cbdb7ec37defda4f5987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cliuliaozhong=E2=80=9D?= <“liuliaozhong@canway.net”> Date: Fri, 30 Dec 2022 16:06:39 +0800 Subject: [PATCH 1/4] =?UTF-8?q?fast=5Ftransfer=5Ffile=20API=20=E5=88=86?= =?UTF-8?q?=E5=8F=91=E6=96=87=E4=BB=B6=EF=BC=8C=E5=A6=82=E6=9E=9C=E6=BA=90?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=AD=E7=9A=84=E6=96=87=E4=BB=B6=E5=90=8D?= =?UTF-8?q?=E5=8C=85=E5=90=AB=E7=A9=BA=E6=A0=BC=EF=BC=8C=E4=BC=9A=E6=8A=A5?= =?UTF-8?q?=E9=94=99=20#812?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/esb/v2/impl/EsbFastPushFileResourceImpl.java | 9 +++------ .../api/esb/v3/EsbFastTransferFileV3ResourceImpl.java | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v2/impl/EsbFastPushFileResourceImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v2/impl/EsbFastPushFileResourceImpl.java index b5e77c8d2f..11d1151f38 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v2/impl/EsbFastPushFileResourceImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v2/impl/EsbFastPushFileResourceImpl.java @@ -187,19 +187,16 @@ private boolean validateFileSystemPath(String path) { if (StringUtils.isBlank(path)) { return false; } - if (path.indexOf(' ') != -1) { - return false; - } Pattern p1 = Pattern.compile("(//|\\\\)+"); Matcher m1 = p1.matcher(path); if (m1.matches()) { return false; } - - Pattern p2 = Pattern.compile("^[a-zA-Z]:(/|\\\\).*");//windows + //windows,以'字母:\\'开头,不包含非法字符 + Pattern p2 = Pattern.compile("^[a-zA-Z]:((/|\\\\)([^<>:\"/\\\\|?*])*)*$"); Matcher m2 = p2.matcher(path); - if (!m2.matches()) { //非windows + if (!m2.matches()) { //非windows,除了/之外所有字符都合法 if (path.charAt(0) == '/') { return !path.contains("\\\\"); } else { diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v3/EsbFastTransferFileV3ResourceImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v3/EsbFastTransferFileV3ResourceImpl.java index 5b51378341..f721c6137c 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v3/EsbFastTransferFileV3ResourceImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v3/EsbFastTransferFileV3ResourceImpl.java @@ -209,19 +209,16 @@ private boolean validateFileSystemPath(String path) { if (StringUtils.isBlank(path)) { return false; } - if (path.indexOf(' ') != -1) { - return false; - } Pattern p1 = Pattern.compile("(//|\\\\)+"); Matcher m1 = p1.matcher(path); if (m1.matches()) { return false; } - - Pattern p2 = Pattern.compile("^[a-zA-Z]:(/|\\\\).*");//windows + //windows,以'字母:\\'开头,不包含非法字符 + Pattern p2 = Pattern.compile("^[a-zA-Z]:((/|\\\\)([^<>:\"/\\\\|?*])*)*$"); Matcher m2 = p2.matcher(path); - if (!m2.matches()) { //非windows + if (!m2.matches()) { //非windows,除了/之外所有字符都合法 if (path.charAt(0) == '/') { return !path.contains("\\\\"); } else { From f843a2a03c694abf4976d9fb4519de5f168b2212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cliuliaozhong=E2=80=9D?= <“liuliaozhong@canway.net”> Date: Thu, 5 Jan 2023 20:09:50 +0800 Subject: [PATCH 2/4] =?UTF-8?q?bugfix:=20fast=5Ftransfer=5Ffile=20API=20?= =?UTF-8?q?=E5=88=86=E5=8F=91=E6=96=87=E4=BB=B6=EF=BC=8C=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E6=BA=90=E6=96=87=E4=BB=B6=E4=B8=AD=E7=9A=84=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E5=8C=85=E5=90=AB=E7=A9=BA=E6=A0=BC=EF=BC=8C=E4=BC=9A?= =?UTF-8?q?=E6=8A=A5=E9=94=99=20#812?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../job/common/util/FilePathValidateUtil.java | 98 +++++++++++++++++++ .../common/util/FilePathValidateUtilTest.java | 34 +++++++ .../v2/impl/EsbFastPushFileResourceImpl.java | 31 +----- .../v3/EsbFastTransferFileV3ResourceImpl.java | 31 +----- 4 files changed, 138 insertions(+), 56 deletions(-) create mode 100644 src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java create mode 100644 src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java diff --git a/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java b/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java new file mode 100644 index 0000000000..44709f2d82 --- /dev/null +++ b/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java @@ -0,0 +1,98 @@ +package com.tencent.bk.job.common.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 文件路径合法性校验工具类 + */ +public class FilePathValidateUtil { + /** + * 验证文件系统绝对路径的合法性 + * @param path 绝对路径 + * @return boolean true合法,false非法 + */ + public static boolean validateFileSystemAbsolutePath(String path) { + if (StringUtils.isBlank(path)) { + return false; + } + if (isLinuxAbsolutePath(path)) { + return validateLinuxFileSystemAbsolutePath(path); + } else { + return validateWindowsFileSystemAbsolutePath(path); + } + } + + /** + * 判断是否Linux绝对路径 + * + * @param path 文件路径 + * @return boolean + */ + private static boolean isLinuxAbsolutePath(String path) { + if (path.startsWith("/")) { + return true; + } + return false; + } + + /** + * 1 DOS设备路径: + * 设备路径说明符(\\.\ 或 \\?\),它将路径标识为DOS设备路径 + * 2 UNC路径 + * 以\\开头的服务器名或主机名,路径必须始终是完全限定的 + * 组成:\\服务器名\共享名\可选目录名\可选文件名 + * 3 传统DOS路径 + * 标准的DOS路径可由以下三部分组成: + * 1)卷号或驱动器号,后跟卷分隔符(:)。 + * 2)目录名称。目录分隔符用来分隔嵌套目录层次结构中的子目录。 + * 3)文件名。目录分隔符用来分隔文件路径和文件名。 + * + * @param path + * @return boolean + */ + private static boolean validateWindowsFileSystemAbsolutePath(String path) { + // DOS设备 + String pattern = "^\\\\\\\\.\\\\.+|\\\\\\\\\\?\\\\.+"; + Pattern r = Pattern.compile(pattern); + Matcher m = r.matcher(path); + if (m.matches()) { + return true; + } + // UNC + pattern = "^\\\\\\\\[^\\\\]+\\\\[^\\\\]+\\\\.*"; + r = Pattern.compile(pattern); + m = r.matcher(path); + if (m.matches()) { + return true; + } + // 传统DOS + pattern = "^[A-Za-z]:\\\\[^\\\\].*"; + r = Pattern.compile(pattern); + m = r.matcher(path); + if (m.matches()) { + return true; + } + return false; + } + + /** + * 文件或目录名,除了/以外,所有的字符都合法 + * + * @param path + * @return boolean + */ + private static boolean validateLinuxFileSystemAbsolutePath(String path) { + String pattern = "^/([^/].*/{0,1})+"; + Pattern r = Pattern.compile(pattern); + Matcher m = r.matcher(path); + if (m.matches()) { + return true; + } + return false; + } +} diff --git a/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java b/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java new file mode 100644 index 0000000000..af5f2ade74 --- /dev/null +++ b/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java @@ -0,0 +1,34 @@ +package com.tencent.bk.job.common.util; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +public class FilePathValidateUtilTest { + @Test + void testFileSystemAbsolutePath(){ + // DOS设备路径 + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\.\\C:\\Test\\Foo.txt")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\?\\C:\\Test\\Foo.txt")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\Test\\Foo.txt")).isFalse(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\?\\C:\\Te st\\嘉Foo.txt")).isTrue(); + + // UNC路径 + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\system07\\C$\\")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\Server2\\Share\\Test\\Foo.txt")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\Server201\\C$\\Test1\\Fo o.txt")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\system07")).isFalse(); + + // 传统DOS路径 + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\Documents\\abc.txt")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("c:\\Documents\\abc.txt")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\Documents\\嘉 abc.txt")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath(":\\abc.txt")).isFalse(); + + // linux路径 + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/data/test_2022-04-12.apk")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/data/test_2022 04 12.apk")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("data/test_2022-04-12.apk")).isFalse(); + } + +} diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v2/impl/EsbFastPushFileResourceImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v2/impl/EsbFastPushFileResourceImpl.java index b5e77c8d2f..dee5d11cbe 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v2/impl/EsbFastPushFileResourceImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v2/impl/EsbFastPushFileResourceImpl.java @@ -38,6 +38,7 @@ import com.tencent.bk.job.common.model.ValidateResult; import com.tencent.bk.job.common.service.AppScopeMappingService; import com.tencent.bk.job.common.util.ArrayUtil; +import com.tencent.bk.job.common.util.FilePathValidateUtil; import com.tencent.bk.job.common.util.date.DateUtils; import com.tencent.bk.job.common.web.metrics.CustomTimed; import com.tencent.bk.job.execute.api.esb.v2.EsbFastPushFileResource; @@ -124,7 +125,7 @@ public EsbResp fastPushFile(EsbFastPushFileRequest request) { } private ValidateResult checkFastPushFileRequest(EsbFastPushFileRequest request) { - if (!validateFileSystemPath(request.getTargetPath())) { + if (!FilePathValidateUtil.validateFileSystemAbsolutePath(request.getTargetPath())) { log.warn("Fast transfer file, target path is invalid!path={}", request.getTargetPath()); return ValidateResult.fail(ErrorCode.MISSING_OR_ILLEGAL_PARAM_WITH_PARAM_NAME, "file_target_path"); } @@ -162,7 +163,7 @@ private ValidateResult validateFileSource(EsbFastPushFileRequest request) { return ValidateResult.fail(ErrorCode.MISSING_PARAM_WITH_PARAM_NAME, "file_source.files"); } for (String file : files) { - if (!validateFileSystemPath(file)) { + if (!FilePathValidateUtil.validateFileSystemAbsolutePath(file)) { log.warn("Invalid path:{}", file); return ValidateResult.fail(ErrorCode.ILLEGAL_PARAM_WITH_PARAM_NAME, "file_source.files"); } @@ -183,32 +184,6 @@ private ValidateResult validateFileSource(EsbFastPushFileRequest request) { return ValidateResult.pass(); } - private boolean validateFileSystemPath(String path) { - if (StringUtils.isBlank(path)) { - return false; - } - if (path.indexOf(' ') != -1) { - return false; - } - Pattern p1 = Pattern.compile("(//|\\\\)+"); - Matcher m1 = p1.matcher(path); - if (m1.matches()) { - return false; - } - - Pattern p2 = Pattern.compile("^[a-zA-Z]:(/|\\\\).*");//windows - Matcher m2 = p2.matcher(path); - - if (!m2.matches()) { //非windows - if (path.charAt(0) == '/') { - return !path.contains("\\\\"); - } else { - return false; - } - } - return true; - } - private TaskInstanceDTO buildFastFileTaskInstance(EsbFastPushFileRequest request) { TaskInstanceDTO taskInstance = new TaskInstanceDTO(); taskInstance.setType(TaskTypeEnum.FILE.getValue()); diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v3/EsbFastTransferFileV3ResourceImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v3/EsbFastTransferFileV3ResourceImpl.java index 5b51378341..c04cd1640a 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v3/EsbFastTransferFileV3ResourceImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/esb/v3/EsbFastTransferFileV3ResourceImpl.java @@ -40,6 +40,7 @@ import com.tencent.bk.job.common.model.InternalResponse; import com.tencent.bk.job.common.model.ValidateResult; import com.tencent.bk.job.common.service.AppScopeMappingService; +import com.tencent.bk.job.common.util.FilePathValidateUtil; import com.tencent.bk.job.common.util.date.DateUtils; import com.tencent.bk.job.common.web.metrics.CustomTimed; import com.tencent.bk.job.execute.client.FileSourceResourceClient; @@ -144,7 +145,7 @@ private ValidateResult checkFileSource(EsbFileSourceV3DTO fileSource) { for (String file : files) { if ((fileType == null || TaskFileTypeEnum.SERVER.getType() == fileType) - && !validateFileSystemPath(file)) { + && !FilePathValidateUtil.validateFileSystemAbsolutePath(file)) { log.warn("Invalid path:{}", file); return ValidateResult.fail(ErrorCode.ILLEGAL_PARAM_WITH_PARAM_NAME, "file_source.file_list"); } @@ -178,7 +179,7 @@ private ValidateResult checkFileSource(EsbFileSourceV3DTO fileSource) { } private ValidateResult checkFastTransferFileRequest(EsbFastTransferFileV3Request request) { - if (!validateFileSystemPath(request.getTargetPath())) { + if (!FilePathValidateUtil.validateFileSystemAbsolutePath(request.getTargetPath())) { log.warn("Fast transfer file, target path is invalid!path={}", request.getTargetPath()); return ValidateResult.fail(ErrorCode.MISSING_OR_ILLEGAL_PARAM_WITH_PARAM_NAME, "file_target_path"); } @@ -205,32 +206,6 @@ private ValidateResult checkFastTransferFileRequest(EsbFastTransferFileV3Request return ValidateResult.pass(); } - private boolean validateFileSystemPath(String path) { - if (StringUtils.isBlank(path)) { - return false; - } - if (path.indexOf(' ') != -1) { - return false; - } - Pattern p1 = Pattern.compile("(//|\\\\)+"); - Matcher m1 = p1.matcher(path); - if (m1.matches()) { - return false; - } - - Pattern p2 = Pattern.compile("^[a-zA-Z]:(/|\\\\).*");//windows - Matcher m2 = p2.matcher(path); - - if (!m2.matches()) { //非windows - if (path.charAt(0) == '/') { - return !path.contains("\\\\"); - } else { - return false; - } - } - return true; - } - private TaskInstanceDTO buildFastFileTaskInstance(EsbFastTransferFileV3Request request) { TaskInstanceDTO taskInstance = new TaskInstanceDTO(); taskInstance.setType(TaskTypeEnum.FILE.getValue()); From 16fec5878aebea0cf5144db4c3f539bcd18bf19c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cliuliaozhong=E2=80=9D?= <“liuliaozhong@canway.net”> Date: Fri, 6 Jan 2023 17:54:01 +0800 Subject: [PATCH 3/4] =?UTF-8?q?bugfix:=20fast=5Ftransfer=5Ffile=20API=20?= =?UTF-8?q?=E5=88=86=E5=8F=91=E6=96=87=E4=BB=B6=EF=BC=8C=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E6=BA=90=E6=96=87=E4=BB=B6=E4=B8=AD=E7=9A=84=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E5=8C=85=E5=90=AB=E7=A9=BA=E6=A0=BC=EF=BC=8C=E4=BC=9A?= =?UTF-8?q?=E6=8A=A5=E9=94=99=20#812?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../job/common/util/FilePathValidateUtil.java | 65 ++++++++++--------- .../common/util/FilePathValidateUtilTest.java | 22 +++++-- 2 files changed, 51 insertions(+), 36 deletions(-) diff --git a/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java b/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java index 44709f2d82..bd50e35e12 100644 --- a/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java +++ b/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java @@ -11,6 +11,24 @@ * 文件路径合法性校验工具类 */ public class FilePathValidateUtil { + // 传统DOS正则表达式 + private static final String CONVENTIONAL_DOS_PATH_REGEX = "(^[A-Za-z]:\\\\[^\\\\].*)|(^[A-Za-z]:[\\\\])"; + // DOS设备路径正则表达式 + private static final String DOS_DEVICE_PATH_REGEX = "^\\\\\\\\.\\\\.+|\\\\\\\\\\?\\\\.+"; + // UNC路径正则表达式 + private static final String UNC_PATH_REGEX = "^\\\\\\\\[^\\\\]+\\\\[^\\\\]+\\\\.*"; + // Linux路径正则表达式 + private static final String LINUX_PATH_REGEX = "(^/([^/].*/{0,1})+)|(/)"; + + // 传统DOS Pattern + private static final Pattern CONVENTIONAL_DOS_PATH_PATTERN = Pattern.compile(CONVENTIONAL_DOS_PATH_REGEX); + // DOS设备Pattern + private static final Pattern DOS_DEVICE_PATH_PATTERN = Pattern.compile(DOS_DEVICE_PATH_REGEX); + // UNC路径Pattern + private static final Pattern UNC_PATH_PATTERN = Pattern.compile(UNC_PATH_REGEX); + // UNC路径Pattern + private static final Pattern LINUX_PATH_PATTERN = Pattern.compile(LINUX_PATH_REGEX); + /** * 验证文件系统绝对路径的合法性 * @param path 绝对路径 @@ -41,40 +59,30 @@ private static boolean isLinuxAbsolutePath(String path) { } /** - * 1 DOS设备路径: - * 设备路径说明符(\\.\ 或 \\?\),它将路径标识为DOS设备路径 - * 2 UNC路径 - * 以\\开头的服务器名或主机名,路径必须始终是完全限定的 - * 组成:\\服务器名\共享名\可选目录名\可选文件名 - * 3 传统DOS路径 - * 标准的DOS路径可由以下三部分组成: - * 1)卷号或驱动器号,后跟卷分隔符(:)。 - * 2)目录名称。目录分隔符用来分隔嵌套目录层次结构中的子目录。 - * 3)文件名。目录分隔符用来分隔文件路径和文件名。 - * + * 1 传统DOS路径 + * 标准的DOS路径可由以下三部分组成: + * 1)卷号或驱动器号,后跟卷分隔符(:)。 + * 2)目录名称。目录分隔符用来分隔嵌套目录层次结构中的子目录。 + * 3)文件名。目录分隔符用来分隔文件路径和文件名。 + * 2 DOS设备路径: + * 设备路径说明符(\\.\ 或 \\?\),它将路径标识为DOS设备路径 + * 3 UNC路径 + * 以\\开头的服务器名或主机名,路径必须始终是完全限定的 + * 组成:\\服务器名\共享名\可选目录名\可选文件名 * @param path * @return boolean */ private static boolean validateWindowsFileSystemAbsolutePath(String path) { - // DOS设备 - String pattern = "^\\\\\\\\.\\\\.+|\\\\\\\\\\?\\\\.+"; - Pattern r = Pattern.compile(pattern); - Matcher m = r.matcher(path); - if (m.matches()) { + // 传统DOS + if (CONVENTIONAL_DOS_PATH_PATTERN.matcher(path).matches()) { return true; } - // UNC - pattern = "^\\\\\\\\[^\\\\]+\\\\[^\\\\]+\\\\.*"; - r = Pattern.compile(pattern); - m = r.matcher(path); - if (m.matches()) { + // DOS设备 + if (DOS_DEVICE_PATH_PATTERN.matcher(path).matches()) { return true; } - // 传统DOS - pattern = "^[A-Za-z]:\\\\[^\\\\].*"; - r = Pattern.compile(pattern); - m = r.matcher(path); - if (m.matches()) { + // UNC + if (UNC_PATH_PATTERN.matcher(path).matches()) { return true; } return false; @@ -87,10 +95,7 @@ private static boolean validateWindowsFileSystemAbsolutePath(String path) { * @return boolean */ private static boolean validateLinuxFileSystemAbsolutePath(String path) { - String pattern = "^/([^/].*/{0,1})+"; - Pattern r = Pattern.compile(pattern); - Matcher m = r.matcher(path); - if (m.matches()) { + if (LINUX_PATH_PATTERN.matcher(path).matches()) { return true; } return false; diff --git a/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java b/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java index af5f2ade74..b809bf75d5 100644 --- a/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java +++ b/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java @@ -7,6 +7,17 @@ public class FilePathValidateUtilTest { @Test void testFileSystemAbsolutePath(){ + // 传统DOS路径 + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\Documents\\abc.txt")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("c:\\Documents\\abc.txt")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\Documents\\嘉 abc.txt")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath(":\\abc.txt")).isFalse(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:")).isFalse(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\\\")).isFalse(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\logs\\..\\access.log")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\.config\\conf")).isTrue(); + // DOS设备路径 assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\.\\C:\\Test\\Foo.txt")).isTrue(); assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\?\\C:\\Test\\Foo.txt")).isTrue(); @@ -19,16 +30,15 @@ void testFileSystemAbsolutePath(){ assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\Server201\\C$\\Test1\\Fo o.txt")).isTrue(); assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\system07")).isFalse(); - // 传统DOS路径 - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\Documents\\abc.txt")).isTrue(); - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("c:\\Documents\\abc.txt")).isTrue(); - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\Documents\\嘉 abc.txt")).isTrue(); - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath(":\\abc.txt")).isFalse(); - // linux路径 assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/data/test_2022-04-12.apk")).isTrue(); assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/data/test_2022 04 12.apk")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/.conf/abc")).isTrue(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/test/../test.log")).isTrue(); assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("data/test_2022-04-12.apk")).isFalse(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("///")).isFalse(); } } From 3e64ca37922d6f2f2ece714189a2701c80b5615c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cliuliaozhong=E2=80=9D?= Date: Mon, 9 Jan 2023 19:39:40 +0800 Subject: [PATCH 4/4] =?UTF-8?q?bugfix:=20fast=5Ftransfer=5Ffile=20API=20?= =?UTF-8?q?=E5=88=86=E5=8F=91=E6=96=87=E4=BB=B6=EF=BC=8C=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E6=BA=90=E6=96=87=E4=BB=B6=E4=B8=AD=E7=9A=84=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E5=8C=85=E5=90=AB=E7=A9=BA=E6=A0=BC=EF=BC=8C=E4=BC=9A?= =?UTF-8?q?=E6=8A=A5=E9=94=99=20#812?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../job/common/util/FilePathValidateUtil.java | 32 +++---------------- .../common/util/FilePathValidateUtilTest.java | 18 +++-------- 2 files changed, 9 insertions(+), 41 deletions(-) diff --git a/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java b/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java index bd50e35e12..0e908e07bc 100644 --- a/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java +++ b/src/backend/commons/common-utils/src/main/java/com/tencent/bk/job/common/util/FilePathValidateUtil.java @@ -1,10 +1,6 @@ package com.tencent.bk.job.common.util; import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -12,21 +8,14 @@ */ public class FilePathValidateUtil { // 传统DOS正则表达式 - private static final String CONVENTIONAL_DOS_PATH_REGEX = "(^[A-Za-z]:\\\\[^\\\\].*)|(^[A-Za-z]:[\\\\])"; - // DOS设备路径正则表达式 - private static final String DOS_DEVICE_PATH_REGEX = "^\\\\\\\\.\\\\.+|\\\\\\\\\\?\\\\.+"; - // UNC路径正则表达式 - private static final String UNC_PATH_REGEX = "^\\\\\\\\[^\\\\]+\\\\[^\\\\]+\\\\.*"; + private static final String CONVENTIONAL_DOS_PATH_REGEX = "(^[A-Za-z]:\\\\([^\\\\])(([^\\\\/:*?\"<>|])*\\\\?)*)|" + + "(^[A-Za-z]:[\\\\])"; // Linux路径正则表达式 - private static final String LINUX_PATH_REGEX = "(^/([^/].*/{0,1})+)|(/)"; + private static final String LINUX_PATH_REGEX = "^/(((../)*|(./)*)|(\\.?[^.].*/{0,1}))+"; // 传统DOS Pattern private static final Pattern CONVENTIONAL_DOS_PATH_PATTERN = Pattern.compile(CONVENTIONAL_DOS_PATH_REGEX); - // DOS设备Pattern - private static final Pattern DOS_DEVICE_PATH_PATTERN = Pattern.compile(DOS_DEVICE_PATH_REGEX); - // UNC路径Pattern - private static final Pattern UNC_PATH_PATTERN = Pattern.compile(UNC_PATH_REGEX); - // UNC路径Pattern + // Linux路径Pattern private static final Pattern LINUX_PATH_PATTERN = Pattern.compile(LINUX_PATH_REGEX); /** @@ -64,11 +53,6 @@ private static boolean isLinuxAbsolutePath(String path) { * 1)卷号或驱动器号,后跟卷分隔符(:)。 * 2)目录名称。目录分隔符用来分隔嵌套目录层次结构中的子目录。 * 3)文件名。目录分隔符用来分隔文件路径和文件名。 - * 2 DOS设备路径: - * 设备路径说明符(\\.\ 或 \\?\),它将路径标识为DOS设备路径 - * 3 UNC路径 - * 以\\开头的服务器名或主机名,路径必须始终是完全限定的 - * 组成:\\服务器名\共享名\可选目录名\可选文件名 * @param path * @return boolean */ @@ -77,14 +61,6 @@ private static boolean validateWindowsFileSystemAbsolutePath(String path) { if (CONVENTIONAL_DOS_PATH_PATTERN.matcher(path).matches()) { return true; } - // DOS设备 - if (DOS_DEVICE_PATH_PATTERN.matcher(path).matches()) { - return true; - } - // UNC - if (UNC_PATH_PATTERN.matcher(path).matches()) { - return true; - } return false; } diff --git a/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java b/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java index b809bf75d5..d8dae63f9e 100644 --- a/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java +++ b/src/backend/commons/common-utils/src/test/java/com/tencent/bk/job/common/util/FilePathValidateUtilTest.java @@ -17,18 +17,7 @@ void testFileSystemAbsolutePath(){ assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\")).isTrue(); assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\logs\\..\\access.log")).isTrue(); assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\.config\\conf")).isTrue(); - - // DOS设备路径 - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\.\\C:\\Test\\Foo.txt")).isTrue(); - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\?\\C:\\Test\\Foo.txt")).isTrue(); - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\Test\\Foo.txt")).isFalse(); - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\?\\C:\\Te st\\嘉Foo.txt")).isTrue(); - - // UNC路径 - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\system07\\C$\\")).isTrue(); - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\Server2\\Share\\Test\\Foo.txt")).isTrue(); - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\Server201\\C$\\Test1\\Fo o.txt")).isTrue(); - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("\\\\system07")).isFalse(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("C:\\user\\abc>a")).isFalse(); // linux路径 assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/data/test_2022-04-12.apk")).isTrue(); @@ -38,7 +27,10 @@ void testFileSystemAbsolutePath(){ assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/.conf/abc")).isTrue(); assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp/test/../test.log")).isTrue(); assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("data/test_2022-04-12.apk")).isFalse(); - assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("///")).isFalse(); + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("///")).isTrue(); // 根目录 + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp////")).isTrue(); // /tmp/ + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("/tmp//test/")).isTrue();// /tmp/test/ + assertThat(FilePathValidateUtil.validateFileSystemAbsolutePath("///")).isTrue(); } }