Opened 11 years ago

Closed 9 years ago

#568 closed defect (fixed)

read-line produces inconsistent results on DOS-style line endings when buffer is cut off at an unfortunate point

Reported by: sjamaan Owned by:
Priority: critical Milestone:
Component: core libraries Version: 4.6.x
Keywords: tcp, read-line Cc:
Estimated difficulty:

Description

This showed up when trying to use chicken-install, I got this:

% /tmp/chicken-snapshot/bin/chicken-install -test coops
retrieving ...
resolving alias `kitten-technologies' to: http://chicken.kitten-technologies.co.uk/henrietta.cgi
connecting to host "chicken.kitten-technologies.co.uk", port 80 ...
requesting "/henrietta.cgi?name=coops&mode=default&tests=yes" ...
reading response ...
HTTP/1.1 200 OK
Date: Sun, 17 Apr 2011 13:07:39 GMT
Server: Apache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/plain
reading chunks SIZE: 1 line: "1"
...

Error: (zero?) bad argument type: #f

Oddly, it worked when I omitted the -test or tried the call-cc server instead!

It turned out that in setup-download.scm in read-chunks the value of size was #f. After adding some debugging code I found out that read-line returned "0\r" instead of the expected "0", and string->number failed on that.

The actual problem is in an interaction between unit TCP's code for reading lines from a TCP port and ##sys#scan-buffer-line, which it calls. The attached code reproduces this issue 100% reliably for me and triggers what's happening in the kernel on Alaric's machine; it happens to buffer the output just in such a way that my machine reads only a few characters exactly in the middle of the \r and \n line ending markers.

This causes ##sys#scan-buffer-line to be invoked like this:

; read buffer, get two characters in it: "0\r"..
(##sys#scan-buffer-line "0\r" 2 0 ...)
; read buffer, get one character in it: "\n"..
(##sys#scan-buffer-line "\n" 1 0 ...)

At the first call, the one-character lookahead for a \n following the \r fails because it's not present in the buffer. At the next call, it forgot that it encountered the \r in the previous buffer and just returns the empty string. The \r is never discarded.

This can theoretically happen with other types of buffered ports too, but so far I think it only happens with TCP ports.

Attachments (3)

server.scm (443 bytes) - added by sjamaan 11 years ago.
server code
client.scm (155 bytes) - added by sjamaan 11 years ago.
Client code
0001-Implement-fix-for-568-by-making-sys-scan-buffer-line.patch (9.8 KB) - added by sjamaan 9 years ago.
Fix

Download all attachments as: .zip

Change History (10)

Changed 11 years ago by sjamaan

Attachment: server.scm added

server code

Changed 11 years ago by sjamaan

Attachment: client.scm added

Client code

comment:1 Changed 11 years ago by sjamaan

The output of the client should be:

I just read: "0"
I just read: "0"

But it is:

I just read: "0"
I just read: "0\r"

comment:2 Changed 11 years ago by felix winkelmann

Milestone: 4.7.04.8.0

comment:3 Changed 11 years ago by felix winkelmann

Milestone: 4.8.04.7.0

comment:4 Changed 11 years ago by felix winkelmann

Milestone: 4.7.04.8.0

A workaround (thanks to sjamaan) has been committed and merged into "prerelease" and "experimental".

comment:5 Changed 10 years ago by felix winkelmann

Owner: felix winkelmann deleted
Status: newassigned

comment:6 Changed 10 years ago by felix winkelmann

Milestone: 4.8.0

comment:7 Changed 9 years ago by sjamaan

Resolution: fixed
Status: assignedclosed

Fixed by 002ea4128f8b04c7e6d63b6b7a2bdbcd957b785b (and that was fixed by fa9ccaa030cf7acaceb15378a4d6c33464f0eb1f)

Note: See TracTickets for help on using tickets.