# HG changeset patch # User Tim Ringenbach # Date 1093053745 0 # Node ID 255596f41014a2e17a25731977d6164a13640589 # Parent 62eb9fe24692fdb2e48b0bb21ec4faabc3dd3986 [gaim-migrate @ 10666] This is patch number 1002252 by Joe Shaw. He writes: If you start a file transfer with a yahoo user and then unplug the network, wait a couple minutes, and plug it back in, a minute or so later the gaim UI will completely freeze, eventually consume all your memory and crash. This is because ft.c:transfer_cb() does not correctly handle the case in which both READ and WRITE conditions are coming in, and because the yahoo_xfer_read() and yahoo_xfer_write() functions are incorrectly returning 0 on errors instead of -1. Since transfer_cb() is getting both conditions, it only checks READ first and gets back 0 bytes (because the connection has been hung up). 0 is not explicitly handled, so nothing is done and we get ourselves into an infinite loop. committer: Tailor Script diff -r 62eb9fe24692 -r 255596f41014 src/ft.c --- a/src/ft.c Fri Aug 20 22:05:18 2004 +0000 +++ b/src/ft.c Sat Aug 21 02:02:25 2004 +0000 @@ -666,7 +666,7 @@ GaimXferUiOps *ui_ops; GaimXfer *xfer = (GaimXfer *)data; char *buffer = NULL; - ssize_t r; + ssize_t r = 0; if (condition & GAIM_INPUT_READ) { r = gaim_xfer_read(xfer, &buffer); @@ -677,13 +677,14 @@ return; } } - else { + + if (condition & GAIM_INPUT_WRITE) { size_t s = MIN(gaim_xfer_get_bytes_remaining(xfer), 4096); /* this is so the prpl can keep the connection open if it needs to for some odd reason. */ if (s == 0) { - if(xfer->watcher) { + if (xfer->watcher) { gaim_input_remove(xfer->watcher); xfer->watcher = 0; } diff -r 62eb9fe24692 -r 255596f41014 src/protocols/yahoo/yahoo_filexfer.c --- a/src/protocols/yahoo/yahoo_filexfer.c Fri Aug 20 22:05:18 2004 +0000 +++ b/src/protocols/yahoo/yahoo_filexfer.c Sat Aug 21 02:02:25 2004 +0000 @@ -253,11 +253,11 @@ if (len <= 0) { if ((gaim_xfer_get_size(xfer) > 0) && - (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer))) + (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer))) { gaim_xfer_set_completed(xfer, TRUE); - else - gaim_xfer_cancel_remote(xfer); - return 0; + return 0; + } else + return -1; } @@ -302,10 +302,10 @@ struct yahoo_xfer_data *xd = xfer->data; if (!xd) - return 0; + return -1; if (gaim_xfer_get_type(xfer) != GAIM_XFER_SEND) { - return 0; + return -1; } len = write(xfer->fd, buffer, size); @@ -314,7 +314,7 @@ if (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer)) gaim_xfer_set_completed(xfer, TRUE); if ((errno != EAGAIN) && (errno != EINTR)) - gaim_xfer_cancel_remote(xfer); + return -1; return 0; }