diff options
author | dgp <dgp@users.sourceforge.net> | 2015-09-23 16:58:34 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2015-09-23 16:58:34 (GMT) |
commit | fe70ef2e7949c720d01eb97b30effc6294794cac (patch) | |
tree | e7797faca326702677562ea6a76ce219a161dac5 /tests | |
parent | 401ea793a5691a5dc91795371922de138ea7f68c (diff) | |
parent | e52bf0ecd422e64401d71475c5995f18c49c8561 (diff) | |
download | tcl-fe70ef2e7949c720d01eb97b30effc6294794cac.zip tcl-fe70ef2e7949c720d01eb97b30effc6294794cac.tar.gz tcl-fe70ef2e7949c720d01eb97b30effc6294794cac.tar.bz2 |
[32ae34e63a] Prevent segfaults and data corruption when CopyData() is called recursively.
Mark new test io-53.20 as "knownBug". It demos some unknown flaw in MoveBytes().
Diffstat (limited to 'tests')
-rw-r--r-- | tests/io.test | 185 | ||||
-rw-r--r-- | tests/ioCmd.test | 26 |
2 files changed, 198 insertions, 13 deletions
diff --git a/tests/io.test b/tests/io.test index 6b6ad6d..783bc75 100644 --- a/tests/io.test +++ b/tests/io.test @@ -8003,6 +8003,191 @@ test io-53.17 {[7c187a3773] MBWrite: proper inQueueTail handling} -setup { close $c removeFile out } -result {line 100 line} +test io-53.18 {[32ae34e63a] recursive CopyData} -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) [encoding convertto utf-8 \ + [string repeat a 100]] + return {initialize finalize watch read} + } + finalize { + unset index($chan) buffer($chan) + return + } + watch { + if {"read" in [lindex $args 1]} { + chan postevent $chan read + } + return + } + read { + set n [lindex $args 1] + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + return $result + } + } + } + proc more {c outChan bytes args} { + if {[eof $c]} { + set ::done eof + catch {close $c} + return + } + if {[llength $args]} { + set ::done error + } else { + chan copy $c $outChan -command [list [namespace which more] $c $outChan] + } + } + set c [chan create read [namespace which driver]] + chan configure $c -encoding utf-8 + set out [makeFile {} out] + set outChan [open $out w] + # Different encoding to force use of DoReadChars() + chan configure $outChan -encoding iso8859-1 +} -body { + after 100 {set ::done timeout} + chan copy $c $outChan -size 99 -command [list [namespace which more] $c $outChan] + vwait ::done + set ::done +} -cleanup { + close $outChan + removeFile out + rename driver {} + rename more {} + unset ::done +} -result eof + +test io-53.19 {[32ae34e63a] stop ReflectWatch filtering} -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) [encoding convertto utf-8 \ + [string repeat a 100]] + return {initialize finalize watch read} + } + finalize { + unset index($chan) buffer($chan) + return + } + watch { + if {"read" in [lindex $args 1]} { + chan postevent $chan read + } + return + } + read { + set n [lindex $args 1] + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + return $result + } + } + } + proc more {c outChan bytes args} { + if {[eof $c]} { + set ::done eof + catch {close $c} + return + } + if {[llength $args]} { + set ::done error + } else { + chan copy $c $outChan -size 30 -command [list [namespace which more] $c $outChan] + } + } + set c [chan create read [namespace which driver]] + chan configure $c -encoding utf-8 -buffersize 20 + set out [makeFile {} out] + set outChan [open $out w] + # Different encoding to force use of DoReadChars() + chan configure $outChan -encoding iso8859-1 +} -body { + after 100 {set ::done timeout} + chan copy $c $outChan -size 30 -command [list [namespace which more] $c $outChan] + vwait ::done + set ::done +} -cleanup { + catch {close $outChan} + removeFile out + rename driver {} + rename more {} + unset ::done +} -result eof + +test io-53.20 {[e0a7b3e5f8] DoRead calls to UpdateInterest} -constraints knownBug -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) [encoding convertto utf-8 \ + [string repeat a 100]] + return {initialize finalize watch read} + } + finalize { + unset index($chan) buffer($chan) + return + } + watch { + if {"read" in [lindex $args 1]} { + chan postevent $chan read + } + return + } + read { + set n [lindex $args 1] + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + return $result + } + } + } + proc more {c outChan bytes args} { + if {[eof $c]} { + set ::done eof + catch {close $c} + return + } + if {[llength $args]} { + set ::done error + } else { + chan copy $c $outChan -size 10 -command [list [namespace which more] $c $outChan] + } + } + set c [chan create read [namespace which driver]] + chan configure $c -encoding utf-8 -buffersize 20 + set out [makeFile {} out] + set outChan [open $out w] + # Same encoding to force use of DoRead() + chan configure $outChan -encoding utf-8 +} -body { + after 100 {set ::done timeout} + chan copy $c $outChan -size 10 -command [list [namespace which more] $c $outChan] + vwait ::done + set ::done +} -cleanup { + catch {close $outChan} + removeFile out + rename driver {} + rename more {} + unset ::done +} -result eof test io-54.1 {Recursive channel events} {socket fileevent} { # This test checks to see if file events are delivered during recursive diff --git a/tests/ioCmd.test b/tests/ioCmd.test index cd89a02..a0caab2 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -1019,7 +1019,7 @@ test iocmd-23.1 {chan read, regular data return} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} {read rc* 4096} snarfsnarf} +} -result {{read rc* 4096} {read rc* 4096} {watch rc* {}} snarfsnarf} test iocmd-23.2 {chan read, bad data return, to much} -match glob -body { set res {} proc foo {args} { @@ -1031,7 +1031,7 @@ test iocmd-23.2 {chan read, bad data return, to much} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} 1 {read delivered more than requested}} +} -result {{read rc* 4096} {watch rc* {}} 1 {read delivered more than requested}} test iocmd-23.3 {chan read, for non-readable channel} -match glob -body { set res {} proc foo {args} { @@ -1054,7 +1054,7 @@ test iocmd-23.4 {chan read, error return} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} 1 BOOM!} +} -result {{read rc* 4096} {watch rc* {}} 1 BOOM!} test iocmd-23.5 {chan read, break return is error} -match glob -body { set res {} proc foo {args} { @@ -1066,7 +1066,7 @@ test iocmd-23.5 {chan read, break return is error} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} 1 *bad code*} +} -result {{read rc* 4096} {watch rc* {}} 1 *bad code*} test iocmd-23.6 {chan read, continue return is error} -match glob -body { set res {} proc foo {args} { @@ -1078,7 +1078,7 @@ test iocmd-23.6 {chan read, continue return is error} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} 1 *bad code*} +} -result {{read rc* 4096} {watch rc* {}} 1 *bad code*} test iocmd-23.7 {chan read, custom return is error} -match glob -body { set res {} proc foo {args} { @@ -1090,7 +1090,7 @@ test iocmd-23.7 {chan read, custom return is error} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} 1 *bad code*} +} -result {{read rc* 4096} {watch rc* {}} 1 *bad code*} test iocmd-23.8 {chan read, level is squashed} -match glob -body { set res {} proc foo {args} { @@ -1102,7 +1102,7 @@ test iocmd-23.8 {chan read, level is squashed} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} +} -result {{read rc* 4096} {watch rc* {}} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} test iocmd-23.9 {chan read, no data means eof} -match glob -setup { set res {} proc foo {args} { @@ -1118,7 +1118,7 @@ test iocmd-23.9 {chan read, no data means eof} -match glob -setup { close $c rename foo {} unset res -} -result {{read rc* 4096} {} 1} +} -result {{read rc* 4096} {watch rc* {}} {} 1} test iocmd-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glob -setup { set res {} proc foo {args} { @@ -1134,7 +1134,7 @@ test iocmd-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glo close $c rename foo {} unset res -} -result {{read rc* 4096} {} 0} +} -result {{read rc* 4096} {watch rc* {}} {} 0} test iocmd-23.11 {chan read, close pulls the rug out} -match glob -body { set res {} proc foo {args} { @@ -1448,14 +1448,14 @@ test iocmd-25.10 {chan configure, cgetall, level is ignored} -match glob -body { test iocmd-26.1 {chan configure, set standard option} -match glob -body { set res {} proc foo {args} { - oninit configure; onfinal; track; note MUST_NOT_HAPPEN; return + oninit configure; onfinal; track; return } set c [chan create {r w} foo] note [fconfigure $c -translation lf] close $c rename foo {} set res -} -result {{}} +} -result {{watch rc* {}} {}} test iocmd-26.2 {chan configure, set option, error return} -match glob -body { set res {} proc foo {args} { @@ -1993,7 +1993,7 @@ test iocmd-31.6 {chan postevent, posted events do happen} -match glob -body { close $c rename foo {} set res -} -result {{watch rc* read} {} TOCK {} {watch rc* {}}} +} -result {{watch rc* read} {} TOCK {watch rc* read} {} {watch rc* {}}} test iocmd-31.7 {chan postevent, posted events do happen} -match glob -body { set res {} proc foo {args} {oninit; onfinal; track; return} @@ -2006,7 +2006,7 @@ test iocmd-31.7 {chan postevent, posted events do happen} -match glob -body { close $c rename foo {} set res -} -result {{watch rc* write} {} TOCK {} {watch rc* {}}} +} -result {{watch rc* write} {} TOCK {watch rc* write} {} {watch rc* {}}} test iocmd-31.8 {chan postevent after close throws error} -match glob -setup { proc foo {args} {oninit; onfinal; track; return} proc dummy args { return } |