From 164838c7dd26aa084d00dfa178b870dcda41968f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 4 Jan 2011 14:30:04 +0100 Subject: [PATCH] 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. --- docs/libssh2_sftp_readdir_ex.3 | 10 +++++++--- src/sftp.c | 20 +++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/docs/libssh2_sftp_readdir_ex.3 b/docs/libssh2_sftp_readdir_ex.3 index 9209c76d..f3fb1f7a 100644 --- a/docs/libssh2_sftp_readdir_ex.3 +++ b/docs/libssh2_sftp_readdir_ex.3 @@ -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) diff --git a/src/sftp.c b/src/sftp.c index ad59b87c..e1c4f9a1 100644 --- a/src/sftp.c +++ b/src/sftp.c @@ -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);