From efa8dc50b7196a5ae14d2e683d2d8ff107019ebd Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Wed, 12 Feb 2025 13:28:41 -0500 Subject: [PATCH] GH-9821: SFTP: Use `STAT` command to follow symlinks Fixes: #9821 Issue link: https://github.com/spring-projects/spring-integration/issues/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 **Auto-cherry-pick to `6.4.x` & `6.3.x`** --- .../integration/sftp/session/SftpSession.java | 6 +++--- .../integration/sftp/outbound/SftpOutboundTests.java | 8 ++++---- .../sftp/session/SftpRemoteFileTemplateTests.java | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java index 94d1af1d4b..860cabea9e 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -101,7 +101,7 @@ public class SftpSession implements Session { boolean isPattern = remoteFile != null && remoteFile.contains("*"); if (!isPattern && remoteFile != null) { - SftpClient.Attributes attributes = this.sftpClient.lstat(path); + SftpClient.Attributes attributes = this.sftpClient.stat(path); if (!attributes.isDirectory()) { return Stream.of(new SftpClient.DirEntry(remoteFile, path, attributes)); } @@ -201,7 +201,7 @@ public class SftpSession implements Session { @Override public boolean exists(String path) { try { - this.sftpClient.lstat(normalizePath(path)); + this.sftpClient.stat(normalizePath(path)); return true; } catch (SftpException ex) { diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpOutboundTests.java b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpOutboundTests.java index 6ebf61fd32..d4813d1791 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpOutboundTests.java +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpOutboundTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -279,15 +279,15 @@ public class SftpOutboundTests { willReturn(new SftpClient.Attributes()) .given(sftpClient) - .lstat("/exist"); + .stat("/exist"); willThrow(new SftpException(SftpConstants.SSH_FX_NO_SUCH_FILE, "notExist")) .given(sftpClient) - .lstat("/notExist"); + .stat("/notExist"); willThrow(new SshException(SshConstants.SSH_OPEN_CONNECT_FAILED, "Connection lost.")) .given(sftpClient) - .lstat(and(not(eq("/exist")), not(eq("/notExist")))); + .stat(and(not(eq("/exist")), not(eq("/notExist")))); SftpSession sftpSession = new SftpSession(sftpClient); diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/session/SftpRemoteFileTemplateTests.java b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/session/SftpRemoteFileTemplateTests.java index 9511f52c55..5ee26f9aa9 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/session/SftpRemoteFileTemplateTests.java +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/session/SftpRemoteFileTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2024 the original author or authors. + * Copyright 2014-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,7 +86,7 @@ public class SftpRemoteFileTemplateTests extends SftpTestSupport { assertThat(template.exists("foo/foobar.txt")).isTrue(); template.executeWithClient((ClientCallbackWithoutResult) client -> { try { - SftpClient.Attributes file = client.lstat("foo/foobar.txt"); + SftpClient.Attributes file = client.stat("foo/foobar.txt"); assertThat(file.getSize()).isEqualTo(6); } catch (IOException e) {