Clear the values of pipe before calling handler.

Summary:
Applications are stuck when handler of pipe made nested loop.
In the nested loop, _ecore_pipe_read() tried to read new data based on previous information which is not cleared yet.

Spotted by gyuyoung.kim, sy302.park.

Related webkit bug is https://bugs.webkit.org/show_bug.cgi?id=129294

Reviewers: cedric, seoz, raster

CC: seoz, cedric

Differential Revision: https://phab.enlightenment.org/D790
This commit is contained in:
Ryuan Choi 2014-04-25 10:29:01 +09:00 committed by Carsten Haitzler (Rasterman)
parent 64e947512a
commit 2030067991
1 changed files with 11 additions and 33 deletions

View File

@ -586,12 +586,22 @@ _ecore_pipe_handler_call(Ecore_Pipe *p,
size_t len)
{
void *data = (void*) p->data;
// clear all values of pipe first.
p->passed_data = NULL;
p->already_read = 0;
p->len = 0;
p->message++;
if (!p->delete_me)
{
_ecore_unlock();
p->handler(data, buf, len);
_ecore_lock();
}
// free p->passed_data
free(buf);
}
static Eina_Bool
@ -634,11 +644,6 @@ _ecore_pipe_read(void *data,
{
/* no data on first try through means an error */
_ecore_pipe_handler_call(p, NULL, 0);
if (p->passed_data) free(p->passed_data);
p->passed_data = NULL;
p->already_read = 0;
p->len = 0;
p->message++;
pipe_close(p->fd_read);
p->fd_read = PIPE_FD_INVALID;
p->fd_handler = NULL;
@ -673,11 +678,6 @@ _ecore_pipe_read(void *data,
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
_ecore_pipe_handler_call(p, NULL, 0);
if (p->passed_data) free(p->passed_data);
p->passed_data = NULL;
p->already_read = 0;
p->len = 0;
p->message++;
pipe_close(p->fd_read);
p->fd_read = PIPE_FD_INVALID;
p->fd_handler = NULL;
@ -694,12 +694,6 @@ _ecore_pipe_read(void *data,
if (p->len == 0)
{
_ecore_pipe_handler_call(p, NULL, 0);
/* reset all values to 0 */
if (p->passed_data) free(p->passed_data);
p->passed_data = NULL;
p->already_read = 0;
p->len = 0;
p->message++;
_ecore_pipe_unhandle(p);
return ECORE_CALLBACK_RENEW;
}
@ -713,9 +707,6 @@ _ecore_pipe_read(void *data,
{
_ecore_pipe_handler_call(p, NULL, 0);
/* close the pipe */
p->already_read = 0;
p->len = 0;
p->message++;
pipe_close(p->fd_read);
p->fd_read = PIPE_FD_INVALID;
p->fd_handler = NULL;
@ -732,15 +723,7 @@ _ecore_pipe_read(void *data,
/* catch the non error case first */
/* if we read enough data to finish the message/buffer */
if (ret == (ssize_t)(p->len - p->already_read))
{
_ecore_pipe_handler_call(p, p->passed_data, p->len);
free(p->passed_data);
/* reset all values to 0 */
p->passed_data = NULL;
p->already_read = 0;
p->len = 0;
p->message++;
}
_ecore_pipe_handler_call(p, p->passed_data, p->len);
else if (ret > 0)
{
/* more data left to read */
@ -775,11 +758,6 @@ _ecore_pipe_read(void *data,
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
_ecore_pipe_handler_call(p, NULL, 0);
if (p->passed_data) free(p->passed_data);
p->passed_data = NULL;
p->already_read = 0;
p->len = 0;
p->message++;
pipe_close(p->fd_read);
p->fd_read = PIPE_FD_INVALID;
p->fd_handler = NULL;