diff options
author | Benjamin Otte <otte@gnome.org> | 2009-02-19 15:54:57 +0000 |
---|---|---|
committer | Benjamin Otte <otte@src.gnome.org> | 2009-02-19 15:54:57 +0000 |
commit | 530167e203f195a64c9420ffe90f1d28528b7000 (patch) | |
tree | ecfe92f871f3bf0c721cfd983c94c6a80e5f7495 | |
parent | 2a3049e6da268b89e7a37f35d683bf947cfaee0d (diff) | |
download | gvfs-530167e203f195a64c9420ffe90f1d28528b7000.tar.gz |
reviewed by: Andreas Henriksson <andreas@fatal.se>
2009-02-19 Benjamin Otte <otte@gnome.org>
reviewed by: Andreas Henriksson <andreas@fatal.se>
Bug 525283 - handle short reads in ftp
* daemon/gvfsbackendftp.c: (ftp_connection_receive):
account for cases where soup_socket_read_until() would not read up to
the boundary on the first read.
svn path=/trunk/; revision=2238
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | daemon/gvfsbackendftp.c | 96 |
2 files changed, 57 insertions, 49 deletions
@@ -1,3 +1,13 @@ +2009-02-19 Benjamin Otte <otte@gnome.org> + + reviewed by: Andreas Henriksson <andreas@fatal.se> + + Bug 525283 - handle short reads in ftp + + * daemon/gvfsbackendftp.c: (ftp_connection_receive): + account for cases where soup_socket_read_until() would not read up to + the boundary on the first read. + 2009-02-18 Alexander Larsson <alexl@redhat.com> Bug 563623 – build dies on platforms lacking poll() implimentation diff --git a/daemon/gvfsbackendftp.c b/daemon/gvfsbackendftp.c index 8df8efe7..bbadf991 100644 --- a/daemon/gvfsbackendftp.c +++ b/daemon/gvfsbackendftp.c @@ -364,58 +364,56 @@ ftp_connection_receive (FtpConnection *conn, conn->read_bytes = 0; while (reply_state != DONE) { - if (conn->read_buffer_size - conn->read_bytes < 128) - { - gsize new_size = conn->read_buffer_size + 1024; - /* FIXME: upper limit for size? */ - gchar *new = g_try_realloc (conn->read_buffer, new_size); - if (new) - { - conn->read_buffer = new; - conn->read_buffer_size = new_size; - } - else - { - g_set_error_literal (&conn->error, G_IO_ERROR, G_IO_ERROR_FAILED, - _("Invalid reply")); - return 0; - } - } last_line = conn->read_buffer + conn->read_bytes; - status = soup_socket_read_until (conn->commands, - last_line, - /* -1 byte for nul-termination */ - conn->read_buffer_size - conn->read_bytes - 1, - "\r\n", - 2, - &n_bytes, - &got_boundary, - conn->job->cancellable, - &conn->error); - - conn->read_bytes += n_bytes; - conn->read_buffer[conn->read_bytes] = 0; - DEBUG ("<-- %s", last_line); - - switch (status) - { - case SOUP_SOCKET_OK: - case SOUP_SOCKET_EOF: - if (got_boundary) - break; - if (n_bytes > 0) - continue; + do { + /* the available size must at least allow for boundary size (2) + * bytes to be available for reading */ + if (conn->read_buffer_size - conn->read_bytes < 128) + { + gsize new_size = conn->read_buffer_size + 1024; + /* FIXME: upper limit for size? */ + gchar *new = g_try_realloc (conn->read_buffer, new_size); + if (new) + { + /* make last line relative to new allocation */ + last_line = new + (last_line - conn->read_buffer); + conn->read_buffer = new; + conn->read_buffer_size = new_size; + } + else + { + g_set_error_literal (&conn->error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Invalid reply")); + return 0; + } + } + status = soup_socket_read_until (conn->commands, + conn->read_buffer + conn->read_bytes, + /* -1 byte for nul-termination */ + conn->read_buffer_size - conn->read_bytes - 1, + "\r\n", + 2, + &n_bytes, + &got_boundary, + conn->job->cancellable, + &conn->error); + + conn->read_bytes += n_bytes; + conn->read_buffer[conn->read_bytes] = 0; + + g_assert (status != SOUP_SOCKET_WOULD_BLOCK); + if (status == SOUP_SOCKET_ERROR) + return 0; + + if (n_bytes == 0) + { g_set_error_literal (&conn->error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Invalid reply")); - /* fall through */ - case SOUP_SOCKET_ERROR: - conn->read_buffer[conn->read_bytes] = 0; - return 0; - case SOUP_SOCKET_WOULD_BLOCK: - default: - g_assert_not_reached (); - break; - } + return 0; + } + } while (!got_boundary); + + DEBUG ("<-- %s", last_line); if (reply_state == FIRST_LINE) { |