mirror of
https://github.com/curl/curl.git
synced 2026-05-30 16:07:28 +03:00
libssh2/sftp: fix resume corruption by avoiding O_APPEND with rresume
Opening the remote file with O_APPEND while attempting to resume causes all writes to be forced to EOF on servers/implementations where O_APPEND semantics override a prior seek(). As a result, sftp_seek64() is ignored and the resumed data is appended, duplicating/corrupting the file. Fix by: - Using O_WRONLY (without O_APPEND) when resume_from > 0. - Skipping the seek entirely if remote_append mode is requested. Closes #18952
This commit is contained in:
parent
391e3fbeec
commit
dae19dd94a
1 changed files with 16 additions and 10 deletions
|
|
@ -1027,15 +1027,21 @@ sftp_upload_init(struct Curl_easy *data,
|
|||
}
|
||||
}
|
||||
|
||||
if(data->set.remote_append)
|
||||
/* Try to open for append, but create if nonexisting */
|
||||
flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
|
||||
else if(data->state.resume_from > 0)
|
||||
/* If we have restart position then open for append */
|
||||
flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
|
||||
else
|
||||
if(data->set.remote_append) {
|
||||
/* True append mode: create if nonexisting */
|
||||
flags = LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_APPEND;
|
||||
}
|
||||
else if(data->state.resume_from > 0) {
|
||||
/*
|
||||
* Resume MUST NOT use APPEND; some servers force writes to EOF when
|
||||
* APPEND is set, ignoring a prior seek().
|
||||
*/
|
||||
flags = LIBSSH2_FXF_WRITE;
|
||||
}
|
||||
else {
|
||||
/* Clear file before writing (normal behavior) */
|
||||
flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
|
||||
flags = LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC;
|
||||
}
|
||||
|
||||
sshc->sftp_handle =
|
||||
libssh2_sftp_open_ex(sshc->sftp_session, sshp->path,
|
||||
|
|
@ -1093,8 +1099,8 @@ sftp_upload_init(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
/* If we have a restart point then we need to seek to the correct
|
||||
position. */
|
||||
if(data->state.resume_from > 0) {
|
||||
Skip if in explicit remote append mode. */
|
||||
if(data->state.resume_from > 0 && !data->set.remote_append) {
|
||||
int seekerr = CURL_SEEKFUNC_OK;
|
||||
/* Let's read off the proper amount of bytes from the input. */
|
||||
if(data->set.seek_func) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue