Tcl Library Source Code

View Ticket
Login
Ticket UUID: c9d8a52fe61a56d28655809f570eb203c52a7e57
Title: socket i/o hangs wint translation crlf on 4095 byte line
Type: Bug Version: tk 8.6.9 / 8.7a6
Submitter: anonymous Created on: 2022-05-31 01:37:50
Subsystem: websocket Assigned To:
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2022-08-05 08:37:42
Resolution: Fixed Closed By: max
    Closed on: 2022-08-04 15:33:16
Description:
with a socket and -translation crlf, if you try to write a buffered puts 
(or gets - not sure which), it will hang if the size is 4095, 8191, ... 
and any multiple of 4096 - 1.

I see this on windows, didn't test linux, problem gone if change crlf to lf

client test script:


######################
set m 8191

set so [socket 127.0.0.1 10042]

chan configure $so -buffering line -encoding utf-8 -blocking 1 -translation crlf
set output [string repeat x   $m]
puts $so  $output                             
set len [gets $so result]
puts "len:$len"
close $so

########### server script run first ########

proc on_accept {so client_ip client_port} {
	set ::so $so
}
set listener [socket -server on_accept -myaddr 127.0.0.1 10042] 
console show
puts "hello"
vwait ::so
puts "after connect"
chan configure $so -buffering line -encoding utf-8 -blocking 1 -translation crlf
set n [gets $so line]

puts "after gets n=$n"
puts $so $line 
puts "after puts of line"
vwait forever
User Comments: max added on 2022-08-05 08:37:42:
I was also considering that, but then went with pasting the full URL to this ticket to my commit messages. But feel free to create a Tcl ticket, if you think that's better in the long run.

oehhar added on 2022-08-05 07:10:03:

Great catch, my appreciation. We have this bug now for 8 years.

I suppose, it would be helpful for Don to copy this information to a TCL ticket.

Shall I take care ?

Harald


max added on 2022-08-04 15:33:16:
Fixed in
8.6: [https://core.tcl-lang.org/tcl/info/2e8fc36e39984559]
8.7: [https://core.tcl-lang.org/tcl/info/cf8be3fc82dcee22]
9.0: [https://core.tcl-lang.org/tcl/info/658a9d7cb5d6db70]

max added on 2022-08-04 15:03:05:
The bug was introduced by wrong parenthesation in

https://core.tcl-lang.org/tcl/info/d6de6b35d883e546

and not covered by existing tests.

max added on 2022-08-04 07:13:03:

This is a bug in the channel I/O code of the Tcl core that is not limited to sockets. Here is a shorter reproducer that uses a pipe and a shorter buffer size, so that the issue is easier to spot in strace:

lassign [chan pipe] r w
chan configure $r -buffering line -translation crlf -buffersize 8
chan configure $w -buffering line -translation crlf -buffersize 8
puts $w xxxxxxx
gets $r

strace output of the puts and gets part looks like this:

write(4, "xxxxxxx\r", 8)                = 8
read(3, "xxxxxxx\r", 8)                 = 8
read(3, 

So, puts only flushes the first buffer up to the CR, but not the NL that ends up in the next buffer, and then gets does not return because the it wants to see the NL character before it considers the line complete.