Index: modules/textutil/pkgIndex.tcl ================================================================== --- modules/textutil/pkgIndex.tcl +++ modules/textutil/pkgIndex.tcl @@ -2,11 +2,11 @@ # FRINK: nocheck return } package ifneeded textutil 0.8 [list source [file join $dir textutil.tcl]] package ifneeded textutil::adjust 0.7.3 [list source [file join $dir adjust.tcl]] -package ifneeded textutil::split 0.7 [list source [file join $dir split.tcl]] +package ifneeded textutil::split 0.8 [list source [file join $dir split.tcl]] package ifneeded textutil::trim 0.7 [list source [file join $dir trim.tcl]] package ifneeded textutil::tabify 0.7 [list source [file join $dir tabify.tcl]] package ifneeded textutil::repeat 0.7 [list source [file join $dir repeat.tcl]] package ifneeded textutil::string 0.8 [list source [file join $dir string.tcl]] package ifneeded textutil::expander 1.3.1 [list source [file join $dir expander.tcl]] Index: modules/textutil/split.tcl ================================================================== --- modules/textutil/split.tcl +++ modules/textutil/split.tcl @@ -60,10 +60,15 @@ return {} } if {[string length $regexp] == 0} { return [::split $str ""] } + if {[regexp $regexp {}]} { + return -code error \ + "splitting on regexp \"$regexp\" would cause infinite loop" + } + set list {} set start 0 while {[regexp -start $start -indices -- $regexp $str match submatch]} { foreach {subStart subEnd} $submatch break foreach {matchStart matchEnd} $match break @@ -87,10 +92,14 @@ return {} } if {[string length $regexp] == 0} { return [::split $str {}] } + if {[regexp $regexp {}]} { + return -code error \ + "splitting on regexp \"$regexp\" would cause infinite loop" + } set list {} while {[regexp -indices -- $regexp $str match submatch]} { lappend list [string range $str 0 [expr {[lindex $match 0] -1}]] if {[lindex $submatch 0] >= 0} { @@ -162,6 +171,6 @@ } # ### ### ### ######### ######### ######### ## Ready -package provide textutil::split 0.7 +package provide textutil::split 0.8 Index: modules/textutil/split.test ================================================================== --- modules/textutil/split.test +++ modules/textutil/split.test @@ -23,15 +23,15 @@ test splitn-0.1 {split empty string} { ::textutil::split::splitn "" } [list] -test splitn-0.2 {split empty string with explicit lenght 1} { +test splitn-0.2 {split empty string with explicit length 1} { ::textutil::split::splitn "" 1 } [list] -test splitn-0.3 {split empty string with explicit lenght 2} { +test splitn-0.3 {split empty string with explicit length 2} { ::textutil::split::splitn "" 2 } [list] test splitn-1.1 {split simple string} { ::textutil::split::splitn "abc" @@ -43,11 +43,11 @@ test splitn-1.3 {split simple string with explicit length 2} { ::textutil::split::splitn "abc" 2 } [list ab c] -test splitn-2.1 {split with nonpositive lenght ->error!} { +test splitn-2.1 {split with nonpositive length ->error!} { catch {::textutil::split::splitn "abc" 0} msg set msg } {len must be > 0} ################################################### @@ -154,5 +154,12 @@ } {} test splitx-5.0 {splitting using an empty regexp} { ::textutil::split::splitx "fooo bar bas" "" } {f o o o { } b a r { } b a s} + + +test splitx-6.0 {split with regexp matching "" causes infinite loop eating RAM} { + list [catch { + ::textutil::split::splitx "Hello, Word" "|" + } msg] $msg +} {1 {splitting on regexp "|" would cause infinite loop}} Index: modules/textutil/textutil_split.man ================================================================== --- modules/textutil/textutil_split.man +++ modules/textutil/textutil_split.man @@ -1,6 +1,7 @@ -[manpage_begin textutil::split n 0.7] +[vset VERSION 0.8] +[manpage_begin textutil::split n [vset VERSION]] [see_also regexp(n)] [see_also split(n)] [see_also string(n)] [keywords {regular expression}] [keywords split] @@ -7,11 +8,11 @@ [keywords string] [moddesc {Text and string utilities, macro processing}] [titledesc {Procedures to split texts}] [category {Text processing}] [require Tcl 8.2] -[require textutil::split [opt 0.7]] +[require textutil::split [opt [vset VERSION]]] [description] The package [package textutil::split] provides commands that split strings by size and arbitrary regular expressions.