Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix for issue [ea69b0258a9833cb], crash when using a channel transformation on TCP client socket. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk | main |
Files: | files | file ages | folders |
SHA3-256: |
62058cafe065cb35802794e11643b3fd |
User & Date: | pooryorick 2023-03-13 20:57:59.974 |
References
2023-03-13
| ||
21:02 | • Pending ticket [ea69b0258a]: Crash when using a channel transformation on TCP client socket plus 4 other changes artifact: 851b534171 user: pooryorick | |
Context
2023-03-22
| ||
17:15 | Merge trunk 62058cafe0: Fix for issue [ea69b0258a9833cb], crash when using a channel transformation ... check-in: 13eca467c0 user: pooryorick tags: unchained | |
2023-03-14
| ||
10:33 | Merge 8.7 check-in: 30ba320f81 user: jan.nijtmans tags: trunk, main | |
2023-03-13
| ||
20:57 | Fix for issue [ea69b0258a9833cb], crash when using a channel transformation on TCP client socket. check-in: 62058cafe0 user: pooryorick tags: trunk, main | |
15:59 | Merge 8.7: Bug [183a1adcc0]. Buffer overflow in Tcl_UtfToExternal check-in: 5c6fa768fe user: apnadkarni tags: trunk, main | |
13:36 | Fix for issue [ea69b0258a9833cb], crash when using a channel transformation on TCP client socket. check-in: ac8ea99a1a user: pooryorick tags: core-8-branch-bug-ea69b0258a9833cb6 | |
Changes
Changes to generic/tclIO.c.
︙ | ︙ | |||
8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 | * events too. This compiles on all platforms, and also passes the * testsuite on all of them. */ mask &= ~TCL_EXCEPTION; if (!statePtr->timer) { statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, ChannelTimerProc, chanPtr); } } } if (!statePtr->timer && mask & TCL_WRITABLE && GotFlag(statePtr, CHANNEL_NONBLOCKING)) { statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, ChannelTimerProc,chanPtr); } ChanWatch(chanPtr, mask); } | > > | 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 | * events too. This compiles on all platforms, and also passes the * testsuite on all of them. */ mask &= ~TCL_EXCEPTION; if (!statePtr->timer) { TclChannelPreserve((Tcl_Channel)chanPtr); statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, ChannelTimerProc, chanPtr); } } } if (!statePtr->timer && mask & TCL_WRITABLE && GotFlag(statePtr, CHANNEL_NONBLOCKING)) { TclChannelPreserve((Tcl_Channel)chanPtr); statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, ChannelTimerProc,chanPtr); } ChanWatch(chanPtr, mask); } |
︙ | ︙ | |||
8752 8753 8754 8755 8756 8757 8758 | void *clientData) { Channel *chanPtr = (Channel *)clientData; /* State info for channel */ ChannelState *statePtr = chanPtr->state; | > > | > > > > | > | | | | | | | | | | | | | < | | | | | | | | | | | | | | | > | | > > | | > | > | | 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 | void *clientData) { Channel *chanPtr = (Channel *)clientData; /* State info for channel */ ChannelState *statePtr = chanPtr->state; /* TclChannelPreserve() must be called before the current function was * scheduled, is already in effect. In this function it guards against * deallocation in Tcl_NotifyChannel and also keps the channel preserved * until ChannelTimerProc is later called again. */ if (chanPtr->typePtr == NULL) { TclChannelRelease((Tcl_Channel)chanPtr); } else { Tcl_Preserve(statePtr); statePtr->timer = NULL; if (statePtr->interestMask & TCL_WRITABLE && GotFlag(statePtr, CHANNEL_NONBLOCKING) && !GotFlag(statePtr, BG_FLUSH_SCHEDULED) ) { /* * Restart the timer in case a channel handler reenters the event loop * before UpdateInterest gets called by Tcl_NotifyChannel. */ statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, ChannelTimerProc,chanPtr); Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_WRITABLE); } else { /* The channel may have just been closed from within Tcl_NotifyChannel */ if (!GotFlag(statePtr, CHANNEL_INCLOSE)) { if (!GotFlag(statePtr, CHANNEL_NEED_MORE_DATA) && (statePtr->interestMask & TCL_READABLE) && (statePtr->inQueueHead != NULL) && IsBufferReady(statePtr->inQueueHead)) { /* * Restart the timer in case a channel handler reenters the event loop * before UpdateInterest gets called by Tcl_NotifyChannel. */ statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, ChannelTimerProc,chanPtr); Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE); } else { TclChannelRelease((Tcl_Channel)chanPtr); UpdateInterest(chanPtr); } } else { TclChannelRelease((Tcl_Channel)chanPtr); } } Tcl_Release(statePtr); } } /* *---------------------------------------------------------------------- * * Tcl_CreateChannelHandler -- * |
︙ | ︙ |
Changes to tests/ioTrans.test.
︙ | ︙ | |||
629 630 631 632 633 634 635 636 637 638 639 640 641 642 | if {[string length $result] == 0} { driver finalize $chan } return $result } } } # Channel read transform that is just the identity - pass all through proc idxform {cmd handle args} { switch -- $cmd { initialize { return {initialize finalize read} } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | if {[string length $result] == 0} { driver finalize $chan } return $result } } } namespace eval reflector { proc initialize {_ chan mode} { return {initialize finalize watch read} } proc finalize {_ chan} { namespace delete $_ } proc read {_ chan count} { namespace upvar $_ source source set res [string range $source 0 $count-1] set source [string range $source $count end] return $res } proc watch {_ chan events} { after 0 [list chan postevent $chan read] return read } namespace ensemble create -parameters _ namespace export * } namespace eval inputfilter { proc initialize {chan mode} { return {initialize finalize read} } proc read {chan buffer} { return $buffer } proc finalize chan { namespace delete $chan } namespace ensemble create namespace export * } # Channel read transform that is just the identity - pass all through proc idxform {cmd handle args} { switch -- $cmd { initialize { return {initialize finalize read} } |
︙ | ︙ | |||
2085 2086 2087 2088 2089 2090 2091 | vwait ::res set res } -cleanup { thread::send $tidb tempdone thread::release $tidb } -result {Owner lost} | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 | vwait ::res set res } -cleanup { thread::send $tidb tempdone thread::release $tidb } -result {Owner lost} test iortrans-ea69b0258a9833cb { Crash when using a channel transformation on TCP client socket "line two" does not make it into result. This issue should probably be addressed, but it is outside the scope of this test. } -setup { set res {} set read 0 } -body { namespace eval reflector1 { variable source "line one\nline two" interp alias {} [namespace current]::dispatch {} [ namespace parent]::reflector [namespace current] } set chan [chan create read [namespace which reflector1::dispatch]] chan configure $chan -blocking 0 chan push $chan inputfilter chan event $chan read [list ::apply [list chan { variable res variable read set gets [gets $chan] append res $gets incr read } [namespace current]] $chan] vwait [namespace current]::read chan pop $chan vwait [namespace current]::read return $res } -cleanup { catch {unset read} close $chan } -result {line one} cleanupTests return |