Skip to content

Commit 920ced7

Browse files
CaideyipiJackieTien97
authored andcommitted
Pipe: Banned the illegal names in pipe and pipe plugins (#17145)
* fix * fix * fix * sp-linux
1 parent 3fdfe2e commit 920ced7

4 files changed

Lines changed: 105 additions & 6 deletions

File tree

integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/basic/IoTDBPipeSyntaxIT.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.iotdb.pipe.it.dual.treemodel.auto.AbstractPipeDualTreeModelAutoIT;
3131
import org.apache.iotdb.rpc.TSStatusCode;
3232

33+
import org.apache.tsfile.external.commons.lang3.SystemUtils;
3334
import org.junit.Assert;
3435
import org.junit.Before;
3536
import org.junit.Test;
@@ -39,6 +40,7 @@
3940
import java.sql.Connection;
4041
import java.sql.SQLException;
4142
import java.sql.Statement;
43+
import java.util.ArrayList;
4244
import java.util.Arrays;
4345
import java.util.HashMap;
4446
import java.util.List;
@@ -329,6 +331,68 @@ public void testInvalidParameter() throws Exception {
329331
}
330332
}
331333

334+
@Test
335+
public void testDirectoryErrors() throws SQLException {
336+
try (final Connection connection = senderEnv.getConnection();
337+
final Statement statement = connection.createStatement()) {
338+
List<String> wrongDirs = Arrays.asList(".", "..", "./hackYou", ".\\hackYouTwice");
339+
if (SystemUtils.IS_OS_WINDOWS) {
340+
wrongDirs = new ArrayList<>(wrongDirs);
341+
wrongDirs.add("BombWindows/:*?");
342+
wrongDirs.add("AUX");
343+
}
344+
for (final String name : wrongDirs) {
345+
testDirectoryError(name, statement);
346+
}
347+
}
348+
}
349+
350+
private void testDirectoryError(final String wrongDir, final Statement statement) {
351+
final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
352+
353+
final String receiverIp = receiverDataNode.getIp();
354+
final int receiverPort = receiverDataNode.getPort();
355+
356+
try {
357+
statement.execute(
358+
String.format(
359+
"create pipe `"
360+
+ wrongDir
361+
+ "` with source ()"
362+
+ " with processor ()"
363+
+ " with sink ("
364+
+ "'sink'='invalid-param',"
365+
+ "'sink.ip'='%s',"
366+
+ "'sink.port'='%s',"
367+
+ "'sink.batch.enable'='false')",
368+
receiverIp,
369+
receiverPort));
370+
fail();
371+
} catch (final Exception ignore) {
372+
// Expected
373+
}
374+
375+
try {
376+
statement.execute(
377+
String.format(
378+
"create pipePlugin `"
379+
+ wrongDir
380+
+ "` as 'org.apache.iotdb.db.pipe.example.TestProcessor' USING URI '%s'",
381+
new File(
382+
System.getProperty("user.dir")
383+
+ File.separator
384+
+ "target"
385+
+ File.separator
386+
+ "test-classes"
387+
+ File.separator)
388+
.toURI()
389+
+ "PipePlugin.jar"));
390+
fail();
391+
} catch (final SQLException e) {
392+
Assert.assertTrue(e.getMessage().contains("1600: Failed to create pipe plugin"));
393+
}
394+
}
395+
332396
@Test
333397
public void testBrackets() throws Exception {
334398
final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/legacy/IoTDBLegacyPipeReceiverAgent.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.iotdb.commons.conf.CommonDescriptor;
2525
import org.apache.iotdb.commons.exception.IllegalPathException;
2626
import org.apache.iotdb.commons.path.PartialPath;
27+
import org.apache.iotdb.commons.utils.FileUtils;
2728
import org.apache.iotdb.db.auth.AuthorityChecker;
2829
import org.apache.iotdb.db.conf.IoTDBDescriptor;
2930
import org.apache.iotdb.db.pipe.sink.payload.legacy.PipeData;
@@ -52,6 +53,7 @@
5253
import java.nio.ByteBuffer;
5354
import java.time.ZoneId;
5455
import java.util.Map;
56+
import java.util.Objects;
5557
import java.util.concurrent.ConcurrentHashMap;
5658
import java.util.concurrent.atomic.AtomicLong;
5759

@@ -124,7 +126,8 @@ public TSStatus handshake(
124126
}
125127

126128
private boolean validatePipeName(final TSyncIdentityInfo info) {
127-
return info.isSetPipeName() && !info.getPipeName().contains(File.separator);
129+
return info.isSetPipeName()
130+
&& Objects.isNull(FileUtils.getIllegalError4Directory(info.getPipeName()));
128131
}
129132

130133
private void createConnection(final SyncIdentityInfo identityInfo) {

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
import org.apache.iotdb.commons.udf.service.UDFClassLoader;
8181
import org.apache.iotdb.commons.udf.service.UDFExecutableManager;
8282
import org.apache.iotdb.commons.utils.CommonDateTimeUtils;
83+
import org.apache.iotdb.commons.utils.FileUtils;
8384
import org.apache.iotdb.commons.utils.PathUtils;
8485
import org.apache.iotdb.commons.utils.SerializeUtils;
8586
import org.apache.iotdb.commons.utils.TimePartitionUtils;
@@ -939,6 +940,15 @@ public SettableFuture<ConfigTaskResult> createPipePlugin(
939940
final String className = createPipePluginStatement.getClassName();
940941
final String uriString = createPipePluginStatement.getUriString();
941942

943+
final String pathError = FileUtils.getIllegalError4Directory(pluginName);
944+
if (Objects.nonNull(pathError)) {
945+
future.setException(
946+
new IoTDBException(
947+
String.format("Failed to create pipe plugin %s. " + pathError, pluginName),
948+
TSStatusCode.CREATE_PIPE_PLUGIN_ERROR.getStatusCode()));
949+
return future;
950+
}
951+
942952
if (uriString == null || uriString.isEmpty()) {
943953
future.setException(
944954
new IoTDBException(
@@ -1979,6 +1989,7 @@ public SettableFuture<ConfigTaskResult> createPipe(
19791989
final SettableFuture<ConfigTaskResult> future = SettableFuture.create();
19801990

19811991
// Verify that Pipe is disabled if TSFile encryption is enabled
1992+
final String pipeName = createPipeStatement.getPipeName();
19821993
if (!Objects.equals(TSFileDescriptor.getInstance().getConfig().getEncryptType(), "UNENCRYPTED")
19831994
&& !Objects.equals(
19841995
TSFileDescriptor.getInstance().getConfig().getEncryptType(),
@@ -1987,18 +1998,27 @@ public SettableFuture<ConfigTaskResult> createPipe(
19871998
new IoTDBException(
19881999
String.format(
19892000
"Failed to create Pipe %s because TSFile is configured with encryption, which prohibits the use of Pipe",
1990-
createPipeStatement.getPipeName()),
2001+
pipeName),
19912002
TSStatusCode.PIPE_ERROR.getStatusCode()));
19922003
return future;
19932004
}
19942005

19952006
// Validate pipe name
1996-
if (createPipeStatement.getPipeName().startsWith(PipeStaticMeta.SYSTEM_PIPE_PREFIX)) {
2007+
if (pipeName.startsWith(PipeStaticMeta.SYSTEM_PIPE_PREFIX)) {
19972008
future.setException(
19982009
new IoTDBException(
19992010
String.format(
20002011
"Failed to create pipe %s, pipe name starting with \"%s\" are not allowed to be created.",
2001-
createPipeStatement.getPipeName(), PipeStaticMeta.SYSTEM_PIPE_PREFIX),
2012+
pipeName, PipeStaticMeta.SYSTEM_PIPE_PREFIX),
2013+
TSStatusCode.PIPE_ERROR.getStatusCode()));
2014+
return future;
2015+
}
2016+
2017+
final String pathError = FileUtils.getIllegalError4Directory(pipeName);
2018+
if (Objects.nonNull(pathError)) {
2019+
future.setException(
2020+
new IoTDBException(
2021+
String.format("Failed to create pipe %s, " + pathError, pipeName),
20022022
TSStatusCode.PIPE_ERROR.getStatusCode()));
20032023
return future;
20042024
}
@@ -2007,7 +2027,7 @@ public SettableFuture<ConfigTaskResult> createPipe(
20072027
try {
20082028
PipeDataNodeAgent.plugin()
20092029
.validate(
2010-
createPipeStatement.getPipeName(),
2030+
pipeName,
20112031
createPipeStatement.getExtractorAttributes(),
20122032
createPipeStatement.getProcessorAttributes(),
20132033
createPipeStatement.getConnectorAttributes());
@@ -2021,7 +2041,7 @@ public SettableFuture<ConfigTaskResult> createPipe(
20212041
CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
20222042
final TCreatePipeReq req =
20232043
new TCreatePipeReq()
2024-
.setPipeName(createPipeStatement.getPipeName())
2044+
.setPipeName(pipeName)
20252045
.setIfNotExistsCondition(createPipeStatement.hasIfNotExistsCondition())
20262046
.setExtractorAttributes(createPipeStatement.getExtractorAttributes())
20272047
.setProcessorAttributes(createPipeStatement.getProcessorAttributes())

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/FileUtils.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public class FileUtils {
5757
"Renamed file {} to {} because it already exists in the target directory: {}";
5858
private static final String COPY_FILE_MESSAGE =
5959
"Copy file {} to {} because it already exists in the target directory: {}";
60+
private static final String ILLEGAL_PATH_MESSAGE =
61+
"The path cannot be '.', '..', './' or '.\\'. ";
6062

6163
private FileUtils() {}
6264

@@ -567,4 +569,14 @@ private static String copyFileRenameWithMD5(final File sourceFile, final File ta
567569
return targetFileName;
568570
}
569571
}
572+
573+
public static String getIllegalError4Directory(final String path) {
574+
if (path.equals(".") || path.equals("..") || path.contains("./") || path.contains(".\\")) {
575+
return ILLEGAL_PATH_MESSAGE;
576+
}
577+
if (!WindowsOSUtils.isLegalPathSegment4Windows(path)) {
578+
return WindowsOSUtils.OS_SEGMENT_ERROR;
579+
}
580+
return null;
581+
}
570582
}

0 commit comments

Comments
 (0)