/pidgin/main: 451ed08be0b9: Fix purple_xfer_write() during do_tr...

Jakub Adam <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: 451ed08be0b9003154d1e0dd0e5305d17757efb8
Author:	 Jakub Adam <[email protected]>
Date:	 2016-04-07 15:07 +0200
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/451ed08be0b9

Description:

Fix purple_xfer_write() during do_transfer()

Consider sending a small (say 10 bytes) file in do_transfer().

First, the buffer is filled in purple_xfer_read_file(), which also calls
purple_xfer_set_bytes_sent(); because the file is small, bytes sent now
equals the file size. Later in purple_xfer_write(), the size of
the write buffer is adjusted so that it's not bigger than the remaining
portion of the file being sent - but at that point
purple_xfer_get_bytes_remaining() already returns 0, nothing is written
and the file transfer gets stuck.

As I understant it, the meaning of buffer size adjustment in
purple_xfer_write() is to ensure that external protocol plugin which
handles file transfer input and output on its own can't by accident send
more data than the size of the file. In do_transfer(), though, that
check is redundant and can be skipped.

diffstat:

 libpurple/xfer.c |  41 ++++++++++++++++++++++++++---------------
 1 files changed, 26 insertions(+), 15 deletions(-)

diffs (65 lines):

diff --git a/libpurple/xfer.c b/libpurple/xfer.c
--- a/libpurple/xfer.c
+++ b/libpurple/xfer.c
@@ -1205,27 +1205,38 @@ purple_xfer_read(PurpleXfer *xfer, gucha
 	return r;
 }
 
+static gssize
+do_write(PurpleXfer *xfer, const guchar *buffer, gsize size)
+{
+	PurpleXferPrivate *priv = PURPLE_XFER_GET_PRIVATE(xfer);
+	gssize r;
+
+	g_return_val_if_fail(priv   != NULL, 0);
+	g_return_val_if_fail(buffer != NULL, 0);
+	g_return_val_if_fail(size   != 0,    0);
+
+	if (priv->ops.write != NULL) {
+		r = (priv->ops.write)(buffer, size, xfer);
+	} else {
+		r = write(priv->fd, buffer, size);
+		if (r < 0 && errno == EAGAIN)
+			r = 0;
+	}
+
+	return r;
+}
+
 gssize
 purple_xfer_write(PurpleXfer *xfer, const guchar *buffer, gsize size)
 {
 	PurpleXferPrivate *priv = PURPLE_XFER_GET_PRIVATE(xfer);
-	gssize r, s;
-
-	g_return_val_if_fail(priv   != NULL, 0);
-	g_return_val_if_fail(buffer != NULL, 0);
-	g_return_val_if_fail(size   != 0,    0);
+	gssize s;
+
+	g_return_val_if_fail(priv != NULL, 0);
 
 	s = MIN((gssize)purple_xfer_get_bytes_remaining(xfer), (gssize)size);
 
-	if (priv->ops.write != NULL) {
-		r = (priv->ops.write)(buffer, s, xfer);
-	} else {
-		r = write(priv->fd, buffer, s);
-		if (r < 0 && errno == EAGAIN)
-			r = 0;
-	}
-
-	return r;
+	return do_write(xfer, buffer, s);
 }
 
 gboolean
@@ -1405,7 +1416,7 @@ do_transfer(PurpleXfer *xfer)
 			result = priv->buffer->len;
 		}
 
-		r = purple_xfer_write(xfer, buffer, result);
+		r = do_write(xfer, buffer, result);
 
 		if (r == -1) {
 			purple_xfer_cancel_remote(xfer);

_______________________________________________
Commits mailing list
[email protected]
https://pidgin.im/cgi-bin/mailman/listinfo/commits
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.