veeso / suppaftp

a super FTP/FTPS client library for Rust with support for both passive and active mode
Apache License 2.0
121 stars 31 forks source link

[BUG] - abort can be called without passing ownership to data_stream #66

Closed clonejo closed 10 months ago

clonejo commented 10 months ago

Description

I had trouble with using ImplAsyncFtpStream::abort() correctly. Apparently it is possible to only pass a mutable reference for data_stream instead of full ownership, so the drop does not work.

Steps to reproduce

let _ = env_logger::builder().is_test(true).try_init();
use suppaftp::{AsyncFtpStream, Mode};
let mut ftp_stream = AsyncFtpStream::connect("127.0.0.1:1234").await?;
ftp_stream.login("anonymous", "anonymous").await?;
ftp_stream.set_mode(Mode::ExtendedPassive);
let mut stream = ftp_stream.retr_as_stream("foo").await?;
// only pass &mut:
ftp_stream.abort(&mut stream).await?;
// this code will never actually be reached:
loop {
    dbg!();
}

Expected behaviour

abort() does not block indefinitely, or rather, it should be impossible to pass a reference here.

Environment

Additional information

Last lines from trace log:

[2024-01-03T00:50:29Z DEBUG suppaftp::async_ftp] Aborting active file transfer
[2024-01-03T00:50:29Z TRACE suppaftp::async_ftp] CC OUT: ABOR
[2024-01-03T00:50:29Z TRACE suppaftp::async_ftp] dropped stream
[2024-01-03T00:50:29Z TRACE polling::epoll] modify: epoll_fd=10, fd=9, ev=Event { key: 0, readable: true, writable: false }
clonejo commented 10 months ago

Similarly, ImplAsyncFtpStream::quit() can be called on a &mut, and the ftp stream will be broken afterwards.