NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/44183: Shell file name completion aborts shell process or prints wrong data.



>Number:         44183
>Category:       lib
>Synopsis:       Shell file name completion aborts shell process or prints 
>wrong data.
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Dec 01 23:15:00 +0000 2010
>Originator:     Sergio Acereda
>Release:        -current
>Organization:
>Environment:
NetBSD new-host-4 5.99.40 NetBSD 5.99.40 (DM) #0: Sun Nov 21 21:37:10 CET 2010  
root@.:/usr/obj/sys/arch/amd64/compile/DM amd64
>Description:
Shell file name completion aborts shell process or prints wrong data.
>How-To-Repeat:
- Login with /bin/sh
- Try TAB file completion with some directories (/usr/bin, /var/tmp...).
- The shell will crash or print null/wrong entries.

>Fix:
Index: lib/libedit/filecomplete.c
===================================================================
RCS file: /cvsroot/src/lib/libedit/filecomplete.c,v
retrieving revision 1.20
diff -u -r1.20 filecomplete.c
--- lib/libedit/filecomplete.c  15 Nov 2010 21:24:31 -0000      1.20
+++ lib/libedit/filecomplete.c  1 Dec 2010 22:56:21 -0000
@@ -59,7 +59,7 @@
#include "histedit.h"
#include "filecomplete.h"

-static Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
+static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
    '$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' };


@@ -341,10 +341,10 @@
 * 'matches' is list of strings, 'len' is number of strings in 'matches',
 * 'max' is maximum length of string in 'matches'.
 */
-void
-fn_display_match_list (EditLine *el, char **matches, size_t len, size_t max)
+static void
+_fn_display_match_list (EditLine *el, char **matches, size_t len, size_t max)
{
-       size_t i, idx, limit, count;
+       size_t i, limit;
        int screenwidth = el->el_term.t_size.h;

        /*
@@ -355,25 +355,21 @@
        if (limit == 0)
                limit = 1;

-       /* how many lines of output */
-       count = len / limit;
-       if (count * limit < len)
-               count++;
-
        /* Sort the items if they are not already sorted. */
-       qsort(&matches[1], (size_t)(len - 1), sizeof(char *),
-           _fn_qsort_string_compare);
+       qsort(matches, len, sizeof(char *), _fn_qsort_string_compare);

-       idx = 1;
-       for(; count > 0; count--) {
-               int more = limit > 0 && matches[0];
-               for(i = 0; more; i++, idx++) {
-                       more = i < limit && matches[idx + 1];
-                       (void)fprintf(el->el_outfile, "%-*s%s", (int)max,
-                           matches[idx], more ? " " : "");
-               }
-               (void)fprintf(el->el_outfile, "\n");
-       }
+       for (i = 0; i < len; i++)
+               fprintf(el->el_outfile, "%-*s%s", 
+                       (int)max,
+                       matches[i], 
+                       i == (len-1) || (i % limit) == limit-1? "\n" : " ");
+}
+
+void
+fn_display_match_list (EditLine *el, char **matches, size_t len, size_t max)
+{
+       /* Don't process the first argument */
+       _fn_display_match_list(el, matches + 1, len - 1, max);
}

/*
@@ -492,7 +488,7 @@
                                if (match_len > maxlen)
                                        maxlen = match_len;
                        }
-                       matches_num = i - 1;
+                       matches_num = i;
                                
                        /* newline to get on next line from command line */
                        (void)fprintf(el->el_outfile, "\n");
@@ -504,7 +500,7 @@
                        if (matches_num > query_items) {
                                (void)fprintf(el->el_outfile,
                                    "Display all %zu possibilities? (y or n) ",
-                                   matches_num);
+                                   matches_num-1);
                                (void)fflush(el->el_outfile);
                                if (getc(stdin) != 'y')
                                        match_display = 0;



Home | Main Index | Thread Index | Old Index