bug-bash
[Top][All Lists]
Advanced

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

Bug in completion code for //


From: Eric Blake
Subject: Bug in completion code for //
Date: Thu, 26 May 2005 07:09:37 -0600
User-agent: Mozilla Thunderbird 1.0.2 (Windows/20050317)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: cygwin
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash.exe' -DCONF_HOSTTYPE='i686'
- -DCONF_OSTYPE='cygwin' -DCONF_MACHTYPE='i686-pc-cygwin' -DCONF_VENDOR='pc'
- -DLOCALEDIR='/usr/local/share/locale' -DPACKAGE='bash' -DSHELL
- -DHAVE_CONFIG_H -DRECYCLES_PIDS  -I.  -I. -I./include -I./lib   -g -O2
uname output: CYGWIN_NT-5.1 LOUNGE 1.5.16(0.128/4/2) 2005-04-25 20:26 i686
unknown unknown Cygwin
Machine Type: i686-pc-cygwin

Bash Version: 3.0
Patch Level: 16
Release Status: release

Description:
The completion code is not strictly tolerant of the distinctions between
/, //, /name, and //name.  POSIX requires //name to receive implementation
defined treatment, so it is essential that when the user types the double
slash that exactly a double slash is preserved to all further filename
manipulations.  This is particularly important on the upcoming cygwin
1.5.17, where / and // are different directories, where the contents of //
is a listing of all servers on the network, and where a failed
stat("//name") blocks the process for several seconds while trying to
resolve if name is a live host on the network (you don't want
tab-completion to block for that long).

Repeat-By:
$ /[TAB]
$ //[TAB]
$ ///[TAB]

Fix:
Attached.  Part of this patch also needs to be applied to readline 5.0.
Basically, command_word_completion_hook must not turn / into //, and must
not turn // into ///.  And print_filename must recover when stripping the
final slash turns / into '', // into /, and /// into //, before calling
tilde_expand.

- --
Life is short - so eat dessert first!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFClcqR84KuGfSFAYARAohCAKDU4Az/1Nwua8O8OgLSIuHMUUUkbACfazGS
hQwuJl53SaooEIx8VLCh+iE=
=uxPt
-----END PGP SIGNATURE-----
*** bash-3.0.orig/bashline.c    Mon May 23 06:26:42 2005
--- bash-3.0/bashline.c Tue May 24 21:36:14 2005
*************** bash_directory_completion_hook (dirname)
*** 2296,2304 ****
        if (temp1[len1 - 1] == '/')
        {
          len2 = strlen (temp2);
!         temp2 = (char *)xrealloc (temp2, len2 + 2);
!         temp2[len2] = '/';
!         temp2[len2 + 1] = '\0';
        }
        free (local_dirname);
        *dirname = temp2;
--- 2296,2307 ----
        if (temp1[len1 - 1] == '/')
        {
          len2 = strlen (temp2);
!         if (len2 > 2)
!           {
!             temp2 = (char *)xrealloc (temp2, len2 + 2);
!             temp2[len2] = '/';
!             temp2[len2 + 1] = '\0';
!           }
        }
        free (local_dirname);
        *dirname = temp2;
*** bash-3.0.orig/lib/readline/complete.c       Mon May 23 06:27:03 2005
--- bash-3.0/lib/readline/complete.c    Wed May 25 05:19:40 2005
*************** print_filename (to_print, full_pathname)
*** 707,714 ****
             full_pathname being the empty string, we are trying to complete
             files in the root directory.  If we pass a null string to the
             bash directory completion hook, for example, it will expand it
!            to the current directory.  We just want the `/'. */
!         s = tilde_expand (full_pathname && *full_pathname ? full_pathname : 
"/");
          if (rl_directory_completion_hook)
            (*rl_directory_completion_hook) (&s);
  
--- 707,720 ----
             full_pathname being the empty string, we are trying to complete
             files in the root directory.  If we pass a null string to the
             bash directory completion hook, for example, it will expand it
!            to the current directory.  We just want the `/'.  Be careful
!            that the user's "//" is distinct from "/", but more leading
!            slashes can be collapsed.  */
!         s = tilde_expand (! full_pathname || *full_pathname == '\0' ? "/"
!                           : full_pathname[0] != '/' ? full_pathname
!                           : full_pathname[1] == '\0' ? "//"
!                           : full_pathname[1] == '/' && ! full_pathname[2]
!                           ? "/" : full_pathname);
          if (rl_directory_completion_hook)
            (*rl_directory_completion_hook) (&s);
  
*************** print_filename (to_print, full_pathname)
*** 716,722 ****
          tlen = strlen (to_print);
          new_full_pathname = (char *)xmalloc (slen + tlen + 2);
          strcpy (new_full_pathname, s);
!         new_full_pathname[slen] = '/';
          strcpy (new_full_pathname + slen + 1, to_print);
  
  #if defined (VISIBLE_STATS)
--- 722,731 ----
          tlen = strlen (to_print);
          new_full_pathname = (char *)xmalloc (slen + tlen + 2);
          strcpy (new_full_pathname, s);
!         if (s[slen - 1] == '/')
!           slen--;
!         else
!           new_full_pathname[slen] = '/';
          strcpy (new_full_pathname + slen + 1, to_print);
  
  #if defined (VISIBLE_STATS)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]