This is an automated email from the ASF dual-hosted git repository.

jt2594838 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 50a2e83eb65 fix: validate internal tsfile paths for files only (#18417)
50a2e83eb65 is described below

commit 50a2e83eb6512fa5635664efa125a19f6cab9623
Author: Zhenyu Luo <[email protected]>
AuthorDate: Mon Aug 10 18:24:05 2026 +0800

    fix: validate internal tsfile paths for files only (#18417)
    
    * fix: validate internal tsfile paths for files only
    
    * test: cover loading internal data directories
    
    * test: cover empty and non-empty internal data directories
    
    * fix: reject empty load tsfile paths
    
    * Revert "test: cover loading internal data directories"
    
    This reverts commit c7557a762854ec890c760c07e6979b66f38e3fff.
    
    * Revert "fix: validate internal tsfile paths for files only"
    
    This reverts commit 509b40ed0106f617163be8ac91b62a310ee327b9.
    
    * fix: validate empty load tsfile paths for both models
    
    * fixed
---
 .../en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java   |  2 ++
 .../zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java   |  2 ++
 .../db/queryengine/plan/relational/sql/ast/LoadTsFile.java   |  1 +
 .../queryengine/plan/statement/crud/LoadTsFileStatement.java |  8 ++++++++
 .../plan/analyze/load/LoadTsFileAnalyzerTest.java            | 10 ++++++++++
 .../plan/statement/crud/LoadTsFileStatementTest.java         | 12 ++++++++++++
 6 files changed, 35 insertions(+)

diff --git 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
index ade27d85d09..3feefd72a6f 100644
--- 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
@@ -3681,6 +3681,8 @@ public final class DataNodeQueryMessages {
   public static final String EXCEPTION_UDFNAME_IS_NULL_83E9039B = "udfName is 
null";
   public static final String EXCEPTION_URISTRING_IS_NULL_E7458C6A = "uriString 
is null";
   public static final String EXCEPTION_FILEPATH_IS_NULL_84CE8A66 = "filePath 
is null";
+  public static final String 
EXCEPTION_LOAD_TSFILE_PATH_CANNOT_BE_EMPTY_2B106181 =
+      "The LOAD TSFILE path cannot be empty.";
   public static final String EXCEPTION_DETAILS_IS_NULL_8EDEEA03 = "details is 
null";
   public static final String EXCEPTION_COLUMNCATEGORY_IS_NULL_0075924B = 
"columnCategory is null";
   public static final String EXCEPTION_ARGUMENTNAME_IS_NULL_7F8F665F = 
"argumentName is null";
diff --git 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
index 31278e1e48e..0d4e7cc0071 100644
--- 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
@@ -4424,6 +4424,8 @@ public final class DataNodeQueryMessages {
   public static final String EXCEPTION_UDFNAME_IS_NULL_83E9039B = "udfName 
不能为空";
   public static final String EXCEPTION_URISTRING_IS_NULL_E7458C6A = "uriString 
不能为空";
   public static final String EXCEPTION_FILEPATH_IS_NULL_84CE8A66 = "filePath 
不能为空";
+  public static final String 
EXCEPTION_LOAD_TSFILE_PATH_CANNOT_BE_EMPTY_2B106181 =
+      "LOAD TSFILE 路径不能为空。";
   public static final String EXCEPTION_DETAILS_IS_NULL_8EDEEA03 = "details 
不能为空";
   public static final String EXCEPTION_COLUMNCATEGORY_IS_NULL_0075924B = 
"columnCategory 不能为空";
   public static final String EXCEPTION_ARGUMENTNAME_IS_NULL_7F8F665F = 
"argumentName 不能为空";
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/LoadTsFile.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/LoadTsFile.java
index 8e46f7cd72a..2e9adadb576 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/LoadTsFile.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/LoadTsFile.java
@@ -111,6 +111,7 @@ public class LoadTsFile extends Statement {
     initAttributes();
 
     try {
+      LoadTsFileStatement.validateLoadTsFilePath(filePath);
       this.tsFiles =
           validateInternalDataDir
               ? LoadTsFileStatement.processTsFile(new File(filePath), 
validateSourcePath)
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/LoadTsFileStatement.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/LoadTsFileStatement.java
index 0b0dea76311..ca0a0a3e2bf 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/LoadTsFileStatement.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/LoadTsFileStatement.java
@@ -94,6 +94,7 @@ public class LoadTsFileStatement extends Statement {
   private LoadTsFileStatement(
       String filePath, boolean validateSourcePath, boolean 
validateInternalDataDir)
       throws FileNotFoundException {
+    validateLoadTsFilePath(filePath);
     this.file = new File(filePath).getAbsoluteFile();
     this.databaseLevel = 
IoTDBDescriptor.getInstance().getConfig().getDefaultDatabaseLevel();
     this.verifySchema = true;
@@ -111,6 +112,13 @@ public class LoadTsFileStatement extends Statement {
     this.statementType = StatementType.MULTI_BATCH_INSERT;
   }
 
+  public static void validateLoadTsFilePath(final String filePath) throws 
FileNotFoundException {
+    if (filePath == null || filePath.isEmpty()) {
+      throw new FileNotFoundException(
+          
DataNodeQueryMessages.EXCEPTION_LOAD_TSFILE_PATH_CANNOT_BE_EMPTY_2B106181);
+    }
+  }
+
   public static List<File> processTsFile(final File file) throws 
FileNotFoundException {
     return processTsFile(file, true, true);
   }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzerTest.java
index 68503f3d794..bf248d7a600 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzerTest.java
@@ -120,6 +120,16 @@ public class LoadTsFileAnalyzerTest {
     Assert.assertEquals(2, schemaCache.getVerifiedDeviceCount());
   }
 
+  @Test
+  public void testTableLoadEmptyPathIsRejected() {
+    try {
+      new LoadTsFile(null, "", Collections.emptyMap());
+      Assert.fail("Expected empty LOAD TSFILE path to be rejected.");
+    } catch (final RuntimeException e) {
+      Assert.assertTrue(e.getMessage().contains("The LOAD TSFILE path cannot 
be empty."));
+    }
+  }
+
   @Test
   public void testTableSchemaCacheShouldThrowMismatchWhenVerifyingDataType() 
throws Exception {
     final LoadTsFileTableSchemaCache schemaCache = 
createTableSchemaCache(true);
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/crud/LoadTsFileStatementTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/crud/LoadTsFileStatementTest.java
index fac3227f4b5..98b54ea5303 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/crud/LoadTsFileStatementTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/crud/LoadTsFileStatementTest.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.queryengine.plan.statement.crud;
 
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.queryengine.plan.parser.StatementGenerator;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -29,6 +30,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.time.ZoneId;
 import java.util.Comparator;
 import java.util.List;
 import java.util.stream.Stream;
@@ -144,6 +146,16 @@ public class LoadTsFileStatementTest {
     }
   }
 
+  @Test
+  public void testTreeLoadEmptyPathIsRejected() {
+    try {
+      StatementGenerator.createStatement("LOAD ''", ZoneId.systemDefault());
+      Assert.fail("Expected empty LOAD TSFILE path to be rejected.");
+    } catch (final RuntimeException e) {
+      Assert.assertTrue(e.getMessage().contains("The LOAD TSFILE path cannot 
be empty."));
+    }
+  }
+
   @Test
   public void testLoadPipeReceiverTsFileOutsideDataDirIsAllowed() throws 
Exception {
     final IoTDBConfig config = IoTDBDescriptor.getInstance().getConfig();

Reply via email to