Ok, I think I got it figured out.

The code in wordfile() blindly assumed that read() would always return
exactly the number of bytes requested. This is NOT garanteed by the
specification. It's perfectly valid for read() to return less, but
never more data than requested.

Windows is doing something very reasonable here. When the requested
read size would split up a CRNL, then it stops reading one byte earlier.
This ensures that the next read() will be able to correctly convert the
CRNL into a single NL.

The consequence for us is that counting back from the end of MAXWLEN will
give us the wrong position in the data. We need to save the value of n
right after the read(), and use that instead of MAXWLEN in the memmove().
Reading in binary mode is unnecessary.

I've checked a working version into CVS.

Cheers
-schorsch


Am 2016-05-13 02:06, schrieb Gregory J. Ward:
I agree the code in wordfile.c is a bit over-complex and confusing.
Hopefully, it will make more sense to you tomorrow.

Meanwhile, you can try running the following code on the attached files:

#include <stdio.h>
#include "platform.h"

int
main(int argc, char *argv[])
{
        char    rdbuf[40];
        int     n;

        while ((n = read(0, rdbuf, sizeof(rdbuf))) > 0) {
                char    *cp = rdbuf;
                printf("Read %d characters:\n\"", n);
                while (n--)
                        fputc(*cp++, stdout);
                fputs("\"\n", stdout);
        }
        return 0;
}

Running "checkread < testfile_unix.txt" gives me the following on Mac OS X:

Read 40 characters:
"123456789
123456789
123456789
123456789
"
Read 20 characters:
"123456789
123456789
"

You should get the same result on Windows using this file.  However,
using the "testfile_dos.txt" as your input, you might get:

Read 37 characters:
"123456789
123456789
123456789
1234567"
Read 23 characters:
"89
123456789
123456789
"

Using "testfile_dos2.txt", I get:

Read 40 characters:
"12345678
12345678
12345678
12345678
"
Read 20 characters:
"12345678
12345678
"
You should get the same, but with different character counts -- 36 in
the first read and 18 in the second as it removes the '\r' characters
from the result in the default _O_TEXT mode.  Now, try adding an extra
character to the beginning of the "testfile_dos2.txt" file, so that
the "\r\n" sequence splits the read calls.  I'm hoping this will
demonstrate the bug, or else I'm still confused about what's going
wrong in Windows.

Cheers,
-Greg




From: Georg Mischler <[email protected]>
Subject: Re: [Radiance-dev] NREL Radiance re-distribution
Date: May 12, 2016 4:17:50 PM PDT

Hmmm... I really seem to be tired.
That null byte is the one we just wrote ourselfes...

But something in the counting is definitively off.
"buf+MAXWLEN-crem" will point to the second character of the next word,
and memmove() probably reads one beyond the buffer.

More tomorrow.

Cheers
-schorsch

Am 2016-05-13 00:53, schrieb Georg Mischler:
The problem is that in wordfile(), crem still gets incremented even after passing the null byte in buf. I must admit that I don't quite understand the counting logic in there yet, the function looks unnecessarily complicated
to me. Maybe I'll see clearer tomorrow when I'm fully awake again...
Cheers
-schorsch
Am 2016-05-13 00:02, schrieb Gregory J. Ward:
Should be reproducible with a sequence of read calls on a file with
one or two printing characters per line, followed by "\r\n" as usual.
If a character gets eaten, then it must be the _O_TEXT processing at
fault, somehow.
-Greg

_______________________________________________
Radiance-dev mailing list
[email protected]
http://www.radiance-online.org/mailman/listinfo/radiance-dev

--
Georg Mischler  --  simulations developer  --  schorsch at schorsch com
+schorsch.com+  --  lighting design tools  --  http://www.schorsch.com/

_______________________________________________
Radiance-dev mailing list
[email protected]
http://www.radiance-online.org/mailman/listinfo/radiance-dev

Reply via email to