summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@gnome.org>2009-02-19 15:54:57 +0000
committerBenjamin Otte <otte@src.gnome.org>2009-02-19 15:54:57 +0000
commit530167e203f195a64c9420ffe90f1d28528b7000 (patch)
treeecfe92f871f3bf0c721cfd983c94c6a80e5f7495
parent2a3049e6da268b89e7a37f35d683bf947cfaee0d (diff)
downloadgvfs-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--ChangeLog10
-rw-r--r--daemon/gvfsbackendftp.c96
2 files changed, 57 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index e05e062b..f68cda38 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)
{