[PATCH] less: fix botched attempt to use last column

Denys Vlasenko vda.linux at googlemail.com
Sun Aug 16 16:58:35 UTC 2015


Applied, thanks!

On Tue, Aug 4, 2015 at 6:10 PM, Ron Yorston <rmy at pobox.com> wrote:
> Commit 1ecb996 attempted to make read_lines() use the last column of
> the terminal (as re_wrap() did).  There were two problems with this:
>
> - The size of the buffer allocated for lines wasn't increased to allow
>   for the extra character.
>
> - The test for width overflow was moved after the point where the
>   next character was added to the buffer.  This caused a buffer overflow
>   in certain circumstances.
>
>   For example, if the line beyond the end of the display was wider than
>   the display read_lines() would initially read the partial line into a
>   buffer.  When the user moved down read_lines() would be called again
>   to ensure the rest of the line was read.  This would place the next
>   character in the partial line before checking for overflow.
>
>   This can be fixed by moving the test for overflow back to where it was
>   before commit 1ecb996 and changing the comparison to `>` rather than
>   `>=`.
>
> There are two other places where buffers are created without allowing
> for width+1 characters.
>
> Signed-off-by: Ron Yorston <rmy at pobox.com>
> ---
>  miscutils/less.c | 28 ++++++++++++++--------------
>  1 file changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/miscutils/less.c b/miscutils/less.c
> index 7a441bf..ccdb15f 100644
> --- a/miscutils/less.c
> +++ b/miscutils/less.c
> @@ -456,7 +456,7 @@ static void read_lines(void)
>         if (option_mask32 & FLAG_N)
>                 w -= 8;
>
> -       p = current_line = ((char*)xmalloc(w + 4)) + 4;
> +       p = current_line = ((char*)xmalloc(w + 5)) + 4;
>         if (!last_terminated) {
>                 const char *cp = flines[max_fline];
>                 p = stpcpy(p, cp);
> @@ -509,6 +509,16 @@ static void read_lines(void)
>                                 *--p = '\0';
>                                 continue;
>                         }
> +                       {
> +                               size_t new_last_line_pos = last_line_pos + 1;
> +                               if (c == '\t') {
> +                                       new_last_line_pos += 7;
> +                                       new_last_line_pos &= (~7);
> +                               }
> +                               if ((int)new_last_line_pos > w)
> +                                       break;
> +                               last_line_pos = new_last_line_pos;
> +                       }
>                         /* ok, we will eat this char */
>                         readpos++;
>                         if (c == '\n') {
> @@ -520,16 +530,6 @@ static void read_lines(void)
>                         if (c == '\0') c = '\n';
>                         *p++ = c;
>                         *p = '\0';
> -                       {
> -                               size_t new_last_line_pos = last_line_pos + 1;
> -                               if (c == '\t') {
> -                                       new_last_line_pos += 7;
> -                                       new_last_line_pos &= (~7);
> -                               }
> -                               if ((int)new_last_line_pos >= w)
> -                                       break;
> -                               last_line_pos = new_last_line_pos;
> -                       }
>                 } /* end of "read chars until we have a line" loop */
>  #if 0
>  //BUG: also triggers on this:
> @@ -573,7 +573,7 @@ static void read_lines(void)
>                         break;
>                 }
>                 max_fline++;
> -               current_line = ((char*)xmalloc(w + 4)) + 4;
> +               current_line = ((char*)xmalloc(w + 5)) + 4;
>                 p = current_line;
>                 last_line_pos = 0;
>         } /* end of "read lines until we reach cur_fline" loop */
> @@ -755,7 +755,7 @@ static void print_found(const char *line)
>         char *growline;
>         regmatch_t match_structs;
>
> -       char buf[width];
> +       char buf[width+1];
>         const char *str = line;
>         char *p = buf;
>         size_t n;
> @@ -814,7 +814,7 @@ void print_found(const char *line);
>
>  static void print_ascii(const char *str)
>  {
> -       char buf[width];
> +       char buf[width+1];
>         char *p;
>         size_t n;
>
> --
> 2.4.3
>
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox


More information about the busybox mailing list