sftp_readdir: return error if buffer is too small

If asked to read data into a buffer and the buffer is too small to hold
the data, this function now returns an error instead of as previously
just copy as much as fits.
This commit is contained in:
Daniel Stenberg 2011-01-04 14:30:04 +01:00
parent f9b1b95059
commit 164838c7dd
2 changed files with 20 additions and 10 deletions

View File

@ -45,9 +45,9 @@ zero), or negative on failure. 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.
.SH BUG
Passing in a too small buffer when receiving data only results in libssh2 not
copying the entire data amount, and it is not possible for the application to
tell when it happens!
Passing in a too small buffer for 'buffer' or 'longentry' when receiving data
only results in libssh2 1.2.7 or earlier to not copy the entire data amount,
and it is not possible for the application to tell when it happens!
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
@ -58,6 +58,10 @@ tell when it happens!
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
received on the socket, or an SFTP operation caused an errorcode to be
returned by the server.
From 1.2.8, LIBSSH2_ERROR_BUFFER_TOO_SMALL is returned if any of the
given 'buffer' or 'longentry' buffers are too small to fit the requested
object name.
.SH SEE ALSO
.BR libssh2_sftp_open_ex(3),
.BR libssh2_sftp_close_handle(3)

View File

@ -1317,7 +1317,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
LIBSSH2_SFTP *sftp = handle->sftp;
LIBSSH2_CHANNEL *channel = sftp->channel;
LIBSSH2_SESSION *session = channel->session;
size_t data_len, filename_len, longentry_len;
size_t data_len;
uint32_t num_names;
/* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
uint32_t packet_len = handle->handle_len + 13;
@ -1335,6 +1335,8 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
LIBSSH2_SFTP_ATTRIBUTES attrs_dummy;
size_t real_longentry_len;
size_t real_filename_len;
size_t filename_len;
size_t longentry_len;
s = (unsigned char *) handle->u.dir.next_name;
real_filename_len = _libssh2_ntohu32(s);
@ -1342,9 +1344,10 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
s += 4;
filename_len = real_filename_len;
if (filename_len >= buffer_maxlen)
/* leave room for the trailing zero */
filename_len = buffer_maxlen - 1;
if (filename_len >= buffer_maxlen) {
filename_len = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto end;
}
memcpy(buffer, s, filename_len);
buffer[filename_len] = '\0'; /* zero terminate */
@ -1356,9 +1359,10 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
if (longentry && (longentry_maxlen>1)) {
longentry_len = real_longentry_len;
if (longentry_len >= longentry_maxlen)
/* leave room for the trailing zero */
longentry_len = longentry_maxlen -1;
if (longentry_len >= longentry_maxlen) {
filename_len = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto end;
}
memcpy(longentry, s, longentry_len);
longentry[longentry_len] = '\0'; /* zero terminate */
@ -1371,6 +1375,8 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
s += sftp_bin2attr(attrs ? attrs : &attrs_dummy, s);
handle->u.dir.next_name = (char *) s;
end:
if ((--handle->u.dir.names_left) == 0)
LIBSSH2_FREE(session, handle->u.dir.names_packet);