aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-05-31 15:56:10 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-05-31 15:56:10 +0000
commit5a0772ad0b877d851856a7954de650d1db92eb5d (patch)
treecba198adefc5030fee5c04009a2591b05e0e6b59
parentdeb78c496edb448ad8c879ad4185e4e7373c7ab9 (diff)
downloadbusybox-w32-5a0772ad0b877d851856a7954de650d1db92eb5d.tar.gz
busybox-w32-5a0772ad0b877d851856a7954de650d1db92eb5d.tar.bz2
busybox-w32-5a0772ad0b877d851856a7954de650d1db92eb5d.zip
less: fix very obscure memory corruption bug
git-svn-id: svn://busybox.net/trunk/busybox@18714 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--miscutils/less.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/miscutils/less.c b/miscutils/less.c
index d6b71b9f2..58c1ec217 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -204,7 +204,27 @@ static void fill_match_lines(unsigned pos);
204#define fill_match_lines(pos) ((void)0) 204#define fill_match_lines(pos) ((void)0)
205#endif 205#endif
206 206
207 207/* Devilishly complex routine.
208 *
209 * Has to deal with EOF and EPIPE on input,
210 * with line wrapping, with last line not ending in '\n'
211 * (possibly not ending YET!), with backspace and tabs.
212 *
213 * Variables used:
214 * flines[] - array of lines already read. Linewrap may cause
215 * one source file line to occupy several flines[n].
216 * flines[max_fline] - last line, possibly incomplete.
217 * terminated - 1 if flines[max_fline] is 'terminated'
218 * (if there was '\n' [which isn't stored itself, we just remember
219 * that it was seen])
220 * max_lineno - last line's number, this one doesn't increment
221 * on line wrap, only on "real" new lines.
222 * readbuf[0..readeof-1] - small preliminary buffer.
223 * readbuf[readpos] - next character to add to current line.
224 * linepos - screen line position of next char to be read
225 * (takes into account tabs and backspaces)
226 * eof_error - < 0 error, == 0 EOF, > 0 not EOF/error
227 */
208static void read_lines(void) 228static void read_lines(void)
209{ 229{
210#define readbuf bb_common_bufsiz1 230#define readbuf bb_common_bufsiz1
@@ -225,6 +245,7 @@ static void read_lines(void)
225 cp += 8; 245 cp += 8;
226 strcpy(current_line, cp); 246 strcpy(current_line, cp);
227 p += strlen(current_line); 247 p += strlen(current_line);
248 /* linepos is still valid from previous read_lines() */
228 } else { 249 } else {
229 linepos = 0; 250 linepos = 0;
230 } 251 }
@@ -275,17 +296,27 @@ static void read_lines(void)
275 if (c == '\x8' && linepos && p[-1] != '\t') { 296 if (c == '\x8' && linepos && p[-1] != '\t') {
276 readpos++; /* eat it */ 297 readpos++; /* eat it */
277 linepos--; 298 linepos--;
299 /* was buggy (p could end up <= current_line)... */
278 *--p = '\0'; 300 *--p = '\0';
279 continue; 301 continue;
280 } 302 }
281 if (c == '\t') 303 {
282 linepos += (linepos^7) & 7; 304 size_t new_linepos = linepos + 1;
283 linepos++; 305 if (c == '\t') {
284 if (linepos >= w) 306 new_linepos += 7;
285 break; 307 new_linepos &= (~7);
308 }
309 if (new_linepos >= w)
310 break;
311 linepos = new_linepos;
312 }
286 /* ok, we will eat this char */ 313 /* ok, we will eat this char */
287 readpos++; 314 readpos++;
288 if (c == '\n') { terminated = 1; break; } 315 if (c == '\n') {
316 terminated = 1;
317 linepos = 0;
318 break;
319 }
289 /* NUL is substituted by '\n'! */ 320 /* NUL is substituted by '\n'! */
290 if (c == '\0') c = '\n'; 321 if (c == '\0') c = '\n';
291 *p++ = c; 322 *p++ = c;