[php-src] PR #24477: ext/ftp: abort a pending transfer in ftp_nb_put()
| From: | kubakozub | Date: | Wed, 21 Oct 2026 11:44:59 +0000 |
| Subject: | [php-src] PR #24477: ext/ftp: abort a pending transfer in ftp_nb_put() | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-39656@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/24477
Author: kubakozub
### What
ftp_nb_get() aborts a pending non-blocking transfer before starting a new one.
ftp_nb_put() does not. ftp_getdata() assigns ftp->data
unconditionally, so each
ftp_nb_put() / ftp_nb_fput() issued while a transfer is pending replaces
the pointer to the
previous databuf_t, leaking it with its socket, and reads the pending transfer's
response as
the answer to its own command.
The guard was added to the GET path by c962a96c347 (GH-10562, "Memory leak and invalid state
with consecutive ftp_nb_fget") and never applied to the PUT path. It is absent
there on every
branch from PHP-8.2 to master.
### Measured
Starting one non-blocking download and then five non-blocking uploads, counting the process's
own sockets through /proc/self/fd:
```
before: nb_fput #0..#4 sockets 3,4,5,6,7 (delta +1 +2 +3 +4 +5)
after: nb_fput #0..#4 sockets 1,2,1,2,1 (delta -1 +0 -1 +0 -1)
```
The second line is what the guarded sibling ftp_nb_fget() already does with the same
server
and the same loop.
### Test
ext/ftp/tests/ftp_nb_put_during_nb_transfer.phpt leaves a transfer pending with
ftp_nb_fget() and then uploads. It fails without the change and passes with it. The
full
ext/ftp suite is unaffected: 62 passed, 0 failed, 4 skipped.
🤖 Generated with [Claude Code](https://claude.com/claude-code)