[PATCH RFA] libgloss read.c ... totally broken!
J. Johnston
jjohnstn@redhat.com
Thu Jul 18 13:28:00 GMT 2002
cgd@broadcom.com wrote:
>
> So, I was truly shocked to discover... libgloss/read.c is totally
> broken. it seems to have been _always_ been broken in the public CVS,
> at least w.r.t. common sense and the read() semantics expected by the
> newlib stdio implementation.
>
> I'm kinda surprised that nobody's noticed this problem before, I guess
> most people use libgloss w/ targets that don't use read.c, or just
> don't use input at all!
>
> Two big problems, which this patch fixes:
>
> (1) can write outside the buffer provided by the caller!
>
> the caller-provided buffer goes from buf[0] .. buf[nbytes-1].
>
> consider the 'for' loop when i == (nbytes-1), and the read
> character is \n or \r:
>
> buf[nbytes-1] = the read character;
> buf[nbytes-1+1] = \0;
>
> the latter is past the end of the user-supplied buffer! (Also,
> it's pointless to NUL-terminate the buffer. 8-)
>
> (2) on empty input line, read returns 0!
>
> if first character returned by 'inbyte' is \n or \r. the break
> inside the loop is hit, but 'i' is never incremented. 0 is
> returned.
>
> the stdio code (refill.c, ca. line 103) assumes that read
> returning 0 means EOF, because, well, that's what normal UNIX
> blocking read returning 0 means. The Wrong Thing results.
>
> The solution is:
>
> * don't NUL-terminate the buffer,
>
> * when you get CR or NL, make sure it's reflected in the return value
> (by incrementing 'i' before the break).
>
> So, more generally about libgloss read(), is there _any_ point in
> having it do this feeble attempt at line buffering? Why not just
> return one character at a time? (for apps which read lines from
> stdio, it'll work just fine...)
>
> Then, once the existing buffering is squished: that would be a 'raw'
> read function, it might also be nice to have a 'cooked' read function
> that let people backspace, etc. while entering the line. (The UNIX
> way to select between them is, of course, ioctl, but I'd be quite
> happy to do it for libgloss w/ a special function call that the user
> program could make if they wanted the cooked behaviour...)
>
> (yes, that's right, somehow i've found people who want to use
> newlib+libgloss with simple, interactive programs on real raw
> hardware... 8-)
>
Good catch Chris. It is quite possible that something out there originally
depended on the old behavior, but I couldn't tell you what that would be.
The file was originally checked-in in 1995. A number of the newer platforms
are supported by simulators and use a read syscall interface which is
handled by the simulator.
Patch checked in.
-- Jeff J.
> chris
> ===================================================================
> 2002-07-17 Chris Demetriou <cgd@broadcom.com>
>
> * read.c (read): Don't assign past end of buffer, fix return value.
>
> Index: read.c
> ===================================================================
> RCS file: /cvs/src/src/libgloss/read.c,v
> retrieving revision 1.1
> diff -u -p -r1.1 read.c
> --- read.c 17 Mar 2000 22:48:49 -0000 1.1
> +++ read.c 18 Jul 2002 05:58:27 -0000
> @@ -31,7 +31,7 @@ _DEFUN (read, (fd, buf, nbytes),
> for (i = 0; i < nbytes; i++) {
> *(buf + i) = inbyte();
> if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {
> - (*(buf + i + 1)) = 0;
> + i++;
> break;
> }
> }
More information about the Newlib
mailing list