Skip to content

Commit b17a946

Browse files
artembilanspring-builds
authored andcommitted
GH-9821: SFTP: Use STAT command to follow symlinks
Fixes: #9821 Issue link: #9821 Previously, Spring Integration used JSch library for SFTP protocol, and that one was able to follow symlinks. Currently, the `SftpSession` uses `LSTAT` command which does not follow symlinks * Fix `SftpSession` to call `sftpClient.stat()` instead of `lstat()` to mitigate migration pain from JSch (cherry picked from commit efa8dc5)
1 parent 5da7327 commit b17a946

File tree

3 files changed

+9
-9
lines changed

3 files changed

+9
-9
lines changed

spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -101,7 +101,7 @@ public Stream<SftpClient.DirEntry> doList(String path) throws IOException {
101101
boolean isPattern = remoteFile != null && remoteFile.contains("*");
102102

103103
if (!isPattern && remoteFile != null) {
104-
SftpClient.Attributes attributes = this.sftpClient.lstat(path);
104+
SftpClient.Attributes attributes = this.sftpClient.stat(path);
105105
if (!attributes.isDirectory()) {
106106
return Stream.of(new SftpClient.DirEntry(remoteFile, path, attributes));
107107
}
@@ -201,7 +201,7 @@ public boolean rmdir(String remoteDirectory) throws IOException {
201201
@Override
202202
public boolean exists(String path) {
203203
try {
204-
this.sftpClient.lstat(normalizePath(path));
204+
this.sftpClient.stat(normalizePath(path));
205205
return true;
206206
}
207207
catch (SftpException ex) {

spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpOutboundTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -279,15 +279,15 @@ public void testExists() throws IOException {
279279

280280
willReturn(new SftpClient.Attributes())
281281
.given(sftpClient)
282-
.lstat("/exist");
282+
.stat("/exist");
283283

284284
willThrow(new SftpException(SftpConstants.SSH_FX_NO_SUCH_FILE, "notExist"))
285285
.given(sftpClient)
286-
.lstat("/notExist");
286+
.stat("/notExist");
287287

288288
willThrow(new SshException(SshConstants.SSH_OPEN_CONNECT_FAILED, "Connection lost."))
289289
.given(sftpClient)
290-
.lstat(and(not(eq("/exist")), not(eq("/notExist"))));
290+
.stat(and(not(eq("/exist")), not(eq("/notExist"))));
291291

292292
SftpSession sftpSession = new SftpSession(sftpClient);
293293

spring-integration-sftp/src/test/java/org/springframework/integration/sftp/session/SftpRemoteFileTemplateTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2024 the original author or authors.
2+
* Copyright 2014-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -86,7 +86,7 @@ public void testINT3412AppendStatRmdir() {
8686
assertThat(template.exists("foo/foobar.txt")).isTrue();
8787
template.executeWithClient((ClientCallbackWithoutResult<SftpClient>) client -> {
8888
try {
89-
SftpClient.Attributes file = client.lstat("foo/foobar.txt");
89+
SftpClient.Attributes file = client.stat("foo/foobar.txt");
9090
assertThat(file.getSize()).isEqualTo(6);
9191
}
9292
catch (IOException e) {

0 commit comments

Comments
 (0)