www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1643] New: SocketStream.readLine not processing \r\n properly

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1643

           Summary: SocketStream.readLine not processing \r\n properly
           Product: D
           Version: 1.020
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: daniel.keep+d.puremagic.com gmail.com


A new user on the #d IRC channel demonstrated a program that works if the data
being read is from a local file, but fails if it is read from a SocketStream.

The data is a message in the following format (listed as a string literal):

"STARTFILES\r\n"
"logs/gamestat.txt\r\n"
"\x00\x00\x00\xa8"
"In-Game Statistics\n"
...

The program uses a stream.readLine loop to look for the filename.  The
SocketStream correctly reads the first line in its entirety.  However, the
SocketStream reads the second line as "logs/gamestat.txt\r" leaving the
following "\n" in the stream.  This means that the four-byte big-endian number
is read incorrectly as "\x10\x00\x00\x00".  This problem DOES NOT occur if the
contents of this message are dumped to disk and read back via a BufferedFile.

If it is relevant, I have noticed that the first line is sent in one chunk from
the server, whilst the next several lines are all sent together.  That is, the
data arrives at the client as:

"STARTFILES\r\n",
"logs/gamestat.txt\r\n\x00\x00\x00\xa8In-Game Statistics\n..."

I believe the problem may lie in std.stream.Stream where readLine treats
seekable streams differently to non-seekable streams.  It could be that prevCr
is not being maintained correctly.

I will attach the source for the program and a sample message dump presently. 
The source is minimal, although a bit messy as it contains the code to dump the
message and read it from disk commented out.


-- 
Nov 06 2007
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1643






-------
Created an attachment (id=202)
 --> (http://d.puremagic.com/issues/attachment.cgi?id=202&action=view)
The program in question.

The program has been tested with DMD 1.020 under Windows XP 32-bit, compiled
with "dmd ws2_32.lib -run gamestat.d"


-- 
Nov 06 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1643






-------
Created an attachment (id=203)
 --> (http://d.puremagic.com/issues/attachment.cgi?id=203&action=view)
Sample message dump

A binary dump of the message from the server.


-- 
Nov 06 2007
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1643


Vladimir Panteleev <thecybershadow gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |thecybershadow gmail.com
         Resolution|                            |WONTFIX



20:34:15 PDT ---
The problem comes from mixing usage of text-reading methods (readLine / getch /
etc.) with those reading binary data (read(T)). readLine is conservative when
it comes to consuming newlines; when it thinks there may be more characters
completing the newline after what it's read so far, it sets a flag so future
calls to readLine/getch ignore the first line feed on the stream.

I found it curious that whether or not the stream is seekable controls whether
readLine uses getc/ungetc or the "maybe-linefeed-after-this" boolean flag -
even though in ungetc doesn't actually use any streaming methods, and instead
maintains a separate "unget" buffer. Of course, that also causes problems when
mixing binary and text functions. If the first lines in the test data attached
to this bug report were terminated by UNIX line endings, using a File stream
would have yielded unexpected results as well.

Of course, the bigger problem here is the overall design of std.stream. A much
better design decision would have been to implement the text-reading methods in
a new class on top of a binary-only Stream class. The new class could then
override the binary reading methods and make them aware of the unget buffer
etc.

Since I believe it's generally been decided that std.stream (and
std.socketstream correspondingly) is on its path to deprecation in favor of
std.stdio.File and ranges (see e.g. Issue 4025), I think it's safe to mark this
one as WONTFIX.

Also, I just noticed this bug report is from 4 years ago. What am I doing it's
6 AM I should be in bed.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 23 2011