From 4fb1c76abea23369b4d961e2b20f900dd0294e82 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 23 Sep 2015 16:00:57 +0000 Subject: Protect CopyState buffer from conflicting uses when CopyData() is called recursively. Also, have ReflectWatch() always give driver a chance to act. --- generic/tclIO.c | 7 +++++++ generic/tclIORChan.c | 8 -------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 27eee5a..09b2537 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -114,6 +114,7 @@ typedef struct CopyState { Tcl_Interp *interp; /* Interp that started the copy. */ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ int refCount; /* Claim count on the struct */ + int bufInUse; /* Flag to govern access to buffer */ int bufSize; /* Size of appended buffer. */ char buffer[1]; /* Copy buffer, this must be the last * field. */ @@ -8661,6 +8662,7 @@ TclCopyChannel( } csPtr->cmdPtr = cmdPtr; csPtr->refCount = 1; + csPtr->bufInUse = 0; inStatePtr->csPtrR = csPtr; PreserveCopyState(csPtr); @@ -8717,6 +8719,9 @@ CopyData( /* Encoding control */ int underflow; /* Input underflow */ + if (csPtr->bufInUse) { + return TCL_OK; + } PreserveCopyState(csPtr); inChan = (Tcl_Channel) csPtr->readPtr; @@ -8780,6 +8785,7 @@ CopyData( sizeb = csPtr->toRead; } + csPtr->bufInUse = 1; if (inBinary || sameEncoding) { size = DoRead(inStatePtr->topChanPtr, csPtr->buffer, sizeb); } else { @@ -8851,6 +8857,7 @@ CopyData( } else { sizeb = WriteChars(outStatePtr->topChanPtr, buffer, sizeb); } + csPtr->bufInUse = 0; /* * [Bug 2895565]. At this point 'size' still contains the number of diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index bbb5b88..2e5fa45 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -1508,14 +1508,6 @@ ReflectWatch( mask &= rcPtr->mode; - if (mask == rcPtr->interest) { - /* - * Same old, same old, why should we do something? - */ - - return; - } - rcPtr->interest = mask; /* -- cgit v0.12