This is an automated email from the ASF dual-hosted git repository. twolf pushed a commit to branch dev_3.0 in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
commit 576ae31f8cdbcd0c52b990b9c7f534d71b37d356 Merge: f7fd08995 f98873919 Author: Thomas Wolf <[email protected]> AuthorDate: Sat Oct 18 21:52:08 2025 +0200 Merge branch 'master' into 3.0.0 pom.xml | 4 +- .../sftp/server/AbstractSftpSubsystemHelper.java | 2 +- .../org/apache/sshd/sftp/server/SftpSubsystem.java | 2 +- .../apache/sshd/sftp/client/SftpVersionsTest.java | 85 ++++++++++++++++++++++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --cc sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpVersionsTest.java index e4c2ef65a,f43f6b502..2d883afd7 --- a/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpVersionsTest.java +++ b/sshd-sftp/src/test/java/org/apache/sshd/sftp/client/SftpVersionsTest.java @@@ -70,7 -71,7 +71,8 @@@ import org.apache.sshd.sftp.server.Sftp import org.apache.sshd.sftp.server.SftpSubsystemEnvironment; import org.apache.sshd.sftp.server.SftpSubsystemFactory; import org.apache.sshd.util.test.CommonTestSupportUtils; + import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.MethodOrderer.MethodName; import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.params.ParameterizedTest; @@@ -542,6 -571,96 +544,89 @@@ public class SftpVersionsTest extends A } } + @MethodSource("parameters") + @ParameterizedTest(name = "version={0}") - public void sftpRemoveFileWithSymlinkInPath(int version) throws Exception { ++ void sftpRemoveFileWithSymlinkInPath(int version) throws Exception { + Assumptions.assumeFalse(OsUtils.isWin32(), "Symlinks not reliably supported on Windows"); + - initSftpVersionsTest(version); + Path targetPath = detectTargetFolder(); + Path lclSftp = CommonTestSupportUtils.resolve( + targetPath, + SftpConstants.SFTP_SUBSYSTEM_NAME, + getClass().getSimpleName()); + Path lclParent = assertHierarchyTargetFolderExists(lclSftp); + String testFileName = "test-file.txt"; + - Path actualDir = lclParent.resolve("actual-dir-" + getTestedVersion()); ++ Path actualDir = lclParent.resolve("actual-dir-" + version); + CommonTestSupportUtils.deleteRecursive(actualDir); + Files.createDirectories(actualDir); + - Path symlinkDir = lclParent.resolve("symlink-dir-" + getTestedVersion()); ++ Path symlinkDir = lclParent.resolve("symlink-dir-" + version); + Files.deleteIfExists(symlinkDir); + Files.createSymbolicLink(symlinkDir, actualDir); + + Path fileViaSymlink = symlinkDir.resolve(testFileName); + Files.write(fileViaSymlink, "test content".getBytes(StandardCharsets.UTF_8)); + + assertTrue(Files.exists(fileViaSymlink), "File should exist via symlink path"); + assertTrue(Files.exists(actualDir.resolve(testFileName)), "File should exist in actual directory"); + + Path parentPath = targetPath.getParent(); + String remotePath = CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, fileViaSymlink); + + try (ClientSession session = createAuthenticatedClientSession(); - SftpClient sftp = createSftpClient(session, getTestedVersion())) { ++ SftpClient sftp = createSftpClient(session, version)) { + sftp.remove(remotePath); + + assertFalse(Files.exists(fileViaSymlink), "File should be deleted via symlink path"); + assertFalse(Files.exists(actualDir.resolve(testFileName)), "File should be deleted from actual directory"); + } finally { + Files.deleteIfExists(symlinkDir); + CommonTestSupportUtils.deleteRecursive(actualDir); + } + } + + @MethodSource("parameters") + @ParameterizedTest(name = "version={0}") - public void sftpFStatWithSymlinkInPath(int version) throws Exception { ++ void sftpFStatWithSymlinkInPath(int version) throws Exception { + Assumptions.assumeFalse(OsUtils.isWin32(), "Symlinks not reliably supported on Windows"); + - initSftpVersionsTest(version); + Path targetPath = detectTargetFolder(); + Path lclSftp = CommonTestSupportUtils.resolve(targetPath, + SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName()); + Path lclParent = assertHierarchyTargetFolderExists(lclSftp); + - Path actualDir = lclParent.resolve("actual-fstat-" + getTestedVersion()); ++ Path actualDir = lclParent.resolve("actual-fstat-" + version); + CommonTestSupportUtils.deleteRecursive(actualDir); + Files.createDirectories(actualDir); + - Path symlinkDir = lclParent.resolve("symlink-fstat-" + getTestedVersion()); ++ Path symlinkDir = lclParent.resolve("symlink-fstat-" + version); + Files.deleteIfExists(symlinkDir); + Files.createSymbolicLink(symlinkDir, actualDir); + + Path testFile = symlinkDir.resolve("test.txt"); + String content = getCurrentTestName(); + Files.write(testFile, content.getBytes(StandardCharsets.UTF_8)); + + Path parentPath = targetPath.getParent(); + String remotePath = CommonTestSupportUtils.resolveRelativeRemotePath(parentPath, testFile); + + try (ClientSession session = createAuthenticatedClientSession(); - SftpClient sftp = createSftpClient(session, getTestedVersion())) { ++ SftpClient sftp = createSftpClient(session, version)) { + try (SftpClient.CloseableHandle handle = sftp.open(remotePath, SftpClient.OpenMode.Read)) { + Attributes attrs = sftp.stat(handle); + + assertNotNull(attrs, "Attributes should be retrieved"); + assertEquals(content.length(), attrs.getSize(), "File size mismatch"); + assertTrue(attrs.isRegularFile(), "Should be a regular file"); + } + } finally { + Files.deleteIfExists(testFile); + Files.deleteIfExists(symlinkDir); + CommonTestSupportUtils.deleteRecursive(actualDir); + } + } + - @Override - public String toString() { - return getClass().getSimpleName() + "[" + getTestedVersion() + "]"; - } - public static void assertExtensionsMapEquals(String message, Map<String, String> expected, Map<String, byte[]> actual) { assertMapEquals(message, expected, SftpHelper.toStringExtensions(actual)); }
