Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: input.c and here documents bugfixes
- X-seq: zsh-workers 400
- From: hzoli@xxxxxxxxxx (Zoltan Hidvegi)
- To: schaefer@xxxxxxxxxx
- Subject: Re: input.c and here documents bugfixes
- Date: Fri, 22 Sep 1995 19:03:32 +0200 (MET DST)
- In-reply-to: <9509220938.ZM4578@xxxxxxxxxxxxxxxx> from "Bart Schaefer" at Sep 22, 95 09:38:15 am
- Sender: hzoli@xxxxxxxxxx
Bart Schaefer wrote:
> } The problem with the original file is that is can exit from the for loop on
> } two conditions. If it exits when the buffer is filled up, the l counter is
> } one more than otherwise.
>
> But that's the right thing to do, unless ingetc() has changed a lot from
> hgetch(). Originally, hgetch() would return a space that wasn't really
> in the input stream whenever lexstop was true; and hgets() [which became
> ingets() recently] would have to trim that space off to return the real
> input. If the buffer is filled up, then the last character returned by
> ingetc() is a real part of the stream, and the counter should be one
> greater so that the '\0' string-terminator will be inserted after the
> last character read.
>
> Your loop is completely equivalent as far as I can tell, except that if
> n <= 1 and lexstop happens to already be true before ingets() is called,
> you'll write a '\0' into buf[-1].
Here is the original:
! for (l = 0; l < n - 1; l++)
! if ((buf[l] = ingetc()) == '\n' || lexstop)
! break;
! buf[l + (lexstop ? 0 : 1)] = 0;
If it exit on the l < n - 1 condition, buf[l-1] is the last character it
wrote, but in all other cases it is buf[l]. The (lexstop ? 0 : 1) hack does
what you said but if l = n - 1 (the buffer filled up) and lexstop is not yes
true (more to come) then buf[n] will be written, which is one byte over the
end of the buffer. This means that it overwrites the next element on the
stack which may be a return address, a frame pointer or anything else. And
here is the fixed version:
! for (l = 0; l < n - 1 && (buf[l++] = ingetc()) != '\n' && !lexstop;);
! if (lexstop)
! l--;
! buf[l] = '\0';
Note that here in all cases, buf[l-1] was the last character written. This
means that in most cases the terminating null must be written to buf[l], but
if lexstop is one, I decrement l to delete the additional space returned by
ingetc().
The exit condition guarantees that l < n on exit from the loop, and l is not
incremented after the exit from the loop, so buf[l] is always in the usable
address range (unless n = 1 but htegs() never called with this value).
Zoltan
Messages sorted by:
Reverse Date,
Date,
Thread,
Author