less: fix very obscure memory corruption bug
This commit is contained in:
parent
a1d24a0b6e
commit
22a9a3c6f8
@ -204,7 +204,27 @@ static void fill_match_lines(unsigned pos);
|
||||
#define fill_match_lines(pos) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
/* Devilishly complex routine.
|
||||
*
|
||||
* Has to deal with EOF and EPIPE on input,
|
||||
* with line wrapping, with last line not ending in '\n'
|
||||
* (possibly not ending YET!), with backspace and tabs.
|
||||
*
|
||||
* Variables used:
|
||||
* flines[] - array of lines already read. Linewrap may cause
|
||||
* one source file line to occupy several flines[n].
|
||||
* flines[max_fline] - last line, possibly incomplete.
|
||||
* terminated - 1 if flines[max_fline] is 'terminated'
|
||||
* (if there was '\n' [which isn't stored itself, we just remember
|
||||
* that it was seen])
|
||||
* max_lineno - last line's number, this one doesn't increment
|
||||
* on line wrap, only on "real" new lines.
|
||||
* readbuf[0..readeof-1] - small preliminary buffer.
|
||||
* readbuf[readpos] - next character to add to current line.
|
||||
* linepos - screen line position of next char to be read
|
||||
* (takes into account tabs and backspaces)
|
||||
* eof_error - < 0 error, == 0 EOF, > 0 not EOF/error
|
||||
*/
|
||||
static void read_lines(void)
|
||||
{
|
||||
#define readbuf bb_common_bufsiz1
|
||||
@ -225,6 +245,7 @@ static void read_lines(void)
|
||||
cp += 8;
|
||||
strcpy(current_line, cp);
|
||||
p += strlen(current_line);
|
||||
/* linepos is still valid from previous read_lines() */
|
||||
} else {
|
||||
linepos = 0;
|
||||
}
|
||||
@ -275,17 +296,27 @@ static void read_lines(void)
|
||||
if (c == '\x8' && linepos && p[-1] != '\t') {
|
||||
readpos++; /* eat it */
|
||||
linepos--;
|
||||
/* was buggy (p could end up <= current_line)... */
|
||||
*--p = '\0';
|
||||
continue;
|
||||
}
|
||||
if (c == '\t')
|
||||
linepos += (linepos^7) & 7;
|
||||
linepos++;
|
||||
if (linepos >= w)
|
||||
break;
|
||||
{
|
||||
size_t new_linepos = linepos + 1;
|
||||
if (c == '\t') {
|
||||
new_linepos += 7;
|
||||
new_linepos &= (~7);
|
||||
}
|
||||
if (new_linepos >= w)
|
||||
break;
|
||||
linepos = new_linepos;
|
||||
}
|
||||
/* ok, we will eat this char */
|
||||
readpos++;
|
||||
if (c == '\n') { terminated = 1; break; }
|
||||
if (c == '\n') {
|
||||
terminated = 1;
|
||||
linepos = 0;
|
||||
break;
|
||||
}
|
||||
/* NUL is substituted by '\n'! */
|
||||
if (c == '\0') c = '\n';
|
||||
*p++ = c;
|
||||
|
Loading…
Reference in New Issue
Block a user