diff options
author | dgp <dgp@users.sourceforge.net> | 2015-09-23 16:00:57 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2015-09-23 16:00:57 (GMT) |
commit | 4fb1c76abea23369b4d961e2b20f900dd0294e82 (patch) | |
tree | 894a3a003d265bf40aa247339ed94b0d0c7a8050 /generic/tclIO.c | |
parent | 55cb367ecb24a49e0fe76b104f6fe709672b066b (diff) | |
download | tcl-4fb1c76abea23369b4d961e2b20f900dd0294e82.zip tcl-4fb1c76abea23369b4d961e2b20f900dd0294e82.tar.gz tcl-4fb1c76abea23369b4d961e2b20f900dd0294e82.tar.bz2 |
Protect CopyState buffer from conflicting uses when CopyData() is called
recursively. Also, have ReflectWatch() always give driver a chance to act.
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r-- | generic/tclIO.c | 7 |
1 files changed, 7 insertions, 0 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 |