mirror of
https://github.com/libssh2/libssh2.git
synced 2025-11-23 01:22:37 +03:00
sftp_symlink: return error if receive buffer too small
and clean up some variable type mismatches Discussion: http://www.libssh2.org/mail/libssh2-devel-archive-2011-01/0001.shtml
This commit is contained in:
@@ -59,10 +59,13 @@ zero) or negative on failure.
|
|||||||
|
|
||||||
It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
From 1.2.8, LIBSSH2_ERROR_BUFFER_TOO_SMALL is returned if the given 'target'
|
||||||
|
buffer is too small to fit the requested object name.
|
||||||
.SH BUG
|
.SH BUG
|
||||||
Passing in a too small buffer when receiving data only results in libssh2 not
|
Passing in a too small buffer when receiving data only results in libssh2
|
||||||
copying the entire data amount, and it is not possible for the application to
|
1.2.7 or earlier to not copy the entire data amount, and it is not possible
|
||||||
tell when it happens!
|
for the application to tell when it happens!
|
||||||
.SH ERRORS
|
.SH ERRORS
|
||||||
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
|||||||
42
src/sftp.c
42
src/sftp.c
@@ -2798,7 +2798,7 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
|
|||||||
unsigned char *s, *data;
|
unsigned char *s, *data;
|
||||||
static const unsigned char link_responses[2] =
|
static const unsigned char link_responses[2] =
|
||||||
{ SSH_FXP_NAME, SSH_FXP_STATUS };
|
{ SSH_FXP_NAME, SSH_FXP_STATUS };
|
||||||
int rc;
|
int retcode;
|
||||||
|
|
||||||
if ((sftp->version < 3) && (link_type != LIBSSH2_SFTP_REALPATH)) {
|
if ((sftp->version < 3) && (link_type != LIBSSH2_SFTP_REALPATH)) {
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||||
@@ -2845,11 +2845,11 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sftp->symlink_state == libssh2_NB_state_created) {
|
if (sftp->symlink_state == libssh2_NB_state_created) {
|
||||||
rc = _libssh2_channel_write(channel, 0, sftp->symlink_packet,
|
ssize_t rc = _libssh2_channel_write(channel, 0, sftp->symlink_packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||||
return rc;
|
return rc;
|
||||||
} else if (packet_len != rc) {
|
else if (packet_len != rc) {
|
||||||
LIBSSH2_FREE(session, sftp->symlink_packet);
|
LIBSSH2_FREE(session, sftp->symlink_packet);
|
||||||
sftp->symlink_packet = NULL;
|
sftp->symlink_packet = NULL;
|
||||||
sftp->symlink_state = libssh2_NB_state_idle;
|
sftp->symlink_state = libssh2_NB_state_idle;
|
||||||
@@ -2862,13 +2862,12 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
|
|||||||
sftp->symlink_state = libssh2_NB_state_sent;
|
sftp->symlink_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sftp_packet_requirev(sftp, 2, link_responses,
|
retcode = sftp_packet_requirev(sftp, 2, link_responses,
|
||||||
sftp->symlink_request_id, &data,
|
sftp->symlink_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
if (retcode == LIBSSH2_ERROR_EAGAIN)
|
||||||
return rc;
|
return retcode;
|
||||||
}
|
else if (retcode) {
|
||||||
else if (rc) {
|
|
||||||
sftp->symlink_state = libssh2_NB_state_idle;
|
sftp->symlink_state = libssh2_NB_state_idle;
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message");
|
"Timeout waiting for status message");
|
||||||
@@ -2881,9 +2880,9 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
|
|||||||
|
|
||||||
retcode = _libssh2_ntohu32(data + 5);
|
retcode = _libssh2_ntohu32(data + 5);
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
if (retcode == LIBSSH2_FX_OK) {
|
if (retcode == LIBSSH2_FX_OK)
|
||||||
return 0;
|
return LIBSSH2_ERROR_NONE;
|
||||||
} else {
|
else {
|
||||||
sftp->last_errno = retcode;
|
sftp->last_errno = retcode;
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||||
"SFTP Protocol Error");
|
"SFTP Protocol Error");
|
||||||
@@ -2897,15 +2896,18 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
|
|||||||
"no name entries");
|
"no name entries");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this reads a u32 and stores it into a signed 32bit value */
|
||||||
link_len = _libssh2_ntohu32(data + 9);
|
link_len = _libssh2_ntohu32(data + 9);
|
||||||
if (link_len >= target_len) {
|
if (link_len < target_len) {
|
||||||
link_len = target_len - 1;
|
memcpy(target, data + 13, link_len);
|
||||||
|
target[link_len] = 0;
|
||||||
|
retcode = (int)link_len;
|
||||||
}
|
}
|
||||||
memcpy(target, data + 13, link_len);
|
else
|
||||||
target[link_len] = 0;
|
retcode = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
|
|
||||||
return link_len;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* libssh2_sftp_symlink_ex
|
/* libssh2_sftp_symlink_ex
|
||||||
|
|||||||
Reference in New Issue
Block a user