SFTP's handling of "." and ".."

Damien Miller djm at mindrot.org
Fri Jul 4 11:00:47 AEST 2025


On Thu, 3 Jul 2025, Andrew Wood wrote:

>  Hi all,
> 
> Apologies if this has already been discussed before; I googled a bit before
> coming here but couldn't find any mention of this issue. The other day I
> noticed what felt like some strange behavior from SFTP. When doing a
> recursive put command to upload a directory and making the folder a "." or
> "..", it gets copied to the destination with those dots. I'm not good at
> explaining things so perhaps it's easier to give an example.
> If I ran:
> $ cd /path/to/source_dir
> $ sftp dest_host
> sftp> put -r . /destination/path
> 
> Instead of transferring source_dir as a full directory to
> "/destination/path/source_dir", what happens is the "." is simply appended
> to /destination/path resulting in all of the files going to
> "/destination/path/.".

This is expected IMO. You're telling sftp to transfer the current
directory and it's doing that.

> Even worse, if I tried to transfer ".." to
> "/destination/path", all my files would instead go to "/destination"!

This OTOH isn't expected. "put -r .. foo" should IMO have identical
behaviour to "put -r . foo". I think this fixed it:

diff --git a/sftp.c b/sftp.c
index dfbb2d2..a3339f1 100644
--- a/sftp.c
+++ b/sftp.c
@@ -760,6 +760,9 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
 			err = -1;
 			goto out;
 		}
+		/* Special handling for source of '..' */
+		if (strcmp(filename, "..") == 0)
+			filename++; /* point to '.' */
 
 		free(abs_dst);
 		abs_dst = NULL;


More information about the openssh-unix-dev mailing list