diff options
author | Jim Meyering <jim@meyering.net> | 2000-10-21 19:16:37 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2000-10-21 19:16:37 +0000 |
commit | 51e2ffc52458de9b96079cf2b9fd2301eae0ec0a (patch) | |
tree | 98ace012c9edb94c3b3ca188b65501b9e695b73b | |
parent | 379688e35da0d34055fc3436aa1f4fd72de05a8c (diff) | |
download | coreutils-51e2ffc52458de9b96079cf2b9fd2301eae0ec0a.tar.xz |
Prevent a counter buffer overrun when numbering lines and when
processing 100 billion lines (or more) of input.
(LINE_COUNTER_BUF_LEN): Define to allow numbering as
many as 10^18 - 1 lines (the old limit was 10^11 - 1, and could
be exceeded without too much trouble). Use this symbol rather
than hard-coding the constant everywhere. Rather than overruning
for input with more lines, mark the line number by putting a
`>' in the leftmost slot.
(next_line_num): Fixed (now academic) possible line buffer overrun.
Patch by Jan Nieuwenhuizen.
-rw-r--r-- | src/cat.c | 36 |
1 files changed, 24 insertions, 12 deletions
@@ -55,19 +55,26 @@ static char *infile; /* Descriptor on which input file is open. */ static int input_desc; -/* Buffer for line numbers. */ -static char line_buf[13] = -{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0', '\t', '\0'}; +/* Buffer for line numbers. + An 11 digit counter may overflow within an hour on a P2/466, + an 18 digit counter needs about 1000y */ +#define LINE_COUNTER_BUF_LEN 20 +static char line_buf[LINE_COUNTER_BUF_LEN] = + { + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0', + '\t', '\0' + }; /* Position in `line_buf' where printing starts. This will not change unless the number of lines is larger than 999999. */ -static char *line_num_print = line_buf + 5; +static char *line_num_print = line_buf + LINE_COUNTER_BUF_LEN - 8; /* Position of the first digit in `line_buf'. */ -static char *line_num_start = line_buf + 10; +static char *line_num_start = line_buf + LINE_COUNTER_BUF_LEN - 3; /* Position of the last digit in `line_buf'. */ -static char *line_num_end = line_buf + 10; +static char *line_num_end = line_buf + LINE_COUNTER_BUF_LEN - 3; /* Preserves the `cat' function's local `newlines' between invocations. */ static int newlines2 = 0; @@ -129,7 +136,10 @@ next_line_num (void) *endp-- = '0'; } while (endp >= line_num_start); - *--line_num_start = '1'; + if (line_num_start > line_buf) + *--line_num_start = '1'; + else + *line_buf = '>'; if (line_num_start < line_num_print) line_num_print--; } @@ -775,8 +785,8 @@ main (int argc, char **argv) { inbuf = (unsigned char *) xmalloc (insize + 1); - /* Why are (OUTSIZE - 1 + INSIZE * 4 + 13) bytes allocated for - the output buffer? + /* Why are (OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN) + bytes allocated for the output buffer? A test whether output needs to be written is done when the input buffer empties or when a newline appears in the input. After @@ -788,10 +798,12 @@ main (int argc, char **argv) If the last character in the preceding block of input was a newline, a line number may be written (according to the given options) as the first thing in the output buffer. (Done after the - new input is read, but before processing of the input begins.) A - line number requires seldom more than 13 positions. */ + new input is read, but before processing of the input begins.) + A line number requires seldom more than LINE_COUNTER_BUF_LEN + positions. */ - outbuf = (unsigned char *) xmalloc (outsize - 1 + insize * 4 + 13); + outbuf = (unsigned char *) xmalloc (outsize - 1 + insize * 4 + + LINE_COUNTER_BUF_LEN); cat (inbuf, insize, outbuf, outsize, quote, output_tabs, numbers, numbers_at_empty_lines, mark_line_ends, |