From 7ce627fce02eae8c7db36b4090fa0ce1bf69bf44 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 4 Jan 2011 16:05:11 +0000 Subject: [PATCH] fish: fails to tilde expand '~' when $HOME env is unset (RHBZ#617440). This also adds a regression test. --- fish/tilde.c | 37 +++++++++++++++----- regressions/Makefile.am | 1 + regressions/test-guestfish-tilde.sh | 70 +++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 8 deletions(-) create mode 100755 regressions/test-guestfish-tilde.sh diff --git a/fish/tilde.c b/fish/tilde.c index 806297c..ee87ce1 100644 --- a/fish/tilde.c +++ b/fish/tilde.c @@ -28,8 +28,9 @@ #include "fish.h" -static char *expand_home (const char *); +static char *expand_home (char *orig, const char *append); static const char *find_home_for_username (const char *, size_t); +static const char *find_home_for_current_user (void); /* This is called from the script loop if we find a candidate for * ~username (tilde-expansion). @@ -39,13 +40,11 @@ try_tilde_expansion (char *str) { assert (str[0] == '~'); - /* Expand current user's home directory. By simple experimentation - * I found out that bash always uses $HOME. - */ + /* Expand "~" to current user's home directory. */ if (str[1] == '\0') /* ~ */ - return expand_home (NULL); + return expand_home (str, NULL); else if (str[1] == '/') /* ~/... */ - return expand_home (&str[1]); + return expand_home (str, &str[1]); /* Try expanding the part up to the following '\0' or '/' as a * username from the password file. @@ -76,14 +75,21 @@ try_tilde_expansion (char *str) /* Return $HOME + append string. */ static char * -expand_home (const char *append) +expand_home (char *orig, const char *append) { const char *home; int len; char *str; home = getenv ("HOME"); - if (!home) home = "~"; + if (!home) { + /* $HOME not set, bash can look up the current user in the + * password file and find their home that way. (RHBZ#617440). + */ + home = find_home_for_current_user (); + if (!home) + return orig; + } len = strlen (home) + (append ? strlen (append) : 0) + 1; str = malloc (len); @@ -116,3 +122,18 @@ find_home_for_username (const char *username, size_t ulen) return NULL; } + +static const char * +find_home_for_current_user (void) +{ + struct passwd *pw; + uid_t euid = geteuid (); + + setpwent (); + while ((pw = getpwent ()) != NULL) { + if (pw->pw_uid == euid) + return pw->pw_dir; + } + + return NULL; +} diff --git a/regressions/Makefile.am b/regressions/Makefile.am index 15f6d7b..c1dedcd 100644 --- a/regressions/Makefile.am +++ b/regressions/Makefile.am @@ -38,6 +38,7 @@ TESTS = \ test-find0.sh \ test-guestfish-a.sh \ test-guestfish-d.sh \ + test-guestfish-tilde.sh \ test-launch-race.pl \ test-luks.sh \ test-lvm-filtering.sh \ diff --git a/regressions/test-guestfish-tilde.sh b/regressions/test-guestfish-tilde.sh new file mode 100755 index 0000000..8ba5904 --- /dev/null +++ b/regressions/test-guestfish-tilde.sh @@ -0,0 +1,70 @@ +#!/bin/bash - +# libguestfs +# Copyright (C) 2011 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# Test guestfish tilde expansion. +# RHBZ#617440 guestfish: fails to tilde expand '~' when the $HOME env is unset +# RHBZ#511372 guestfish doesn't understand '~' in filenames +# and multiple other fixes to tilde handling. + +set -e + +# Don't rely on $HOME being set when this script is called. +HOME=$(pwd) +export HOME + +if [ `echo 'echo ~' | ../fish/guestfish` != "$HOME" ]; then + echo "$0: failed: did not expand ~ correctly" + exit 1 +fi + +if [ `echo 'echo ~/foo' | ../fish/guestfish` != "$HOME/foo" ]; then + echo "$0: failed: did not expand ~/foo correctly" + exit 1 +fi + +# We can be reasonably sure that the root user will always exist and +# should have a home directory. +root="$(echo ~root)" + +if [ `echo 'echo ~root' | ../fish/guestfish` != "$root" ]; then + echo "$0: failed: did not expand ~root correctly" + exit 1 +fi + +if [ `echo 'echo ~root/foo' | ../fish/guestfish` != "$root/foo" ]; then + echo "$0: failed: did not expand ~root/foo correctly" + exit 1 +fi + +# RHBZ#617440 +unset HOME +home="$(echo ~)" + +if [ `echo 'echo ~' | ../fish/guestfish` != "$home" ]; then + echo "$0: failed: did not expand ~ correctly when \$HOME unset" + exit 1 +fi + +if [ `echo 'echo ~/foo' | ../fish/guestfish` != "$home/foo" ]; then + echo "$0: failed: did not expand ~/foo correctly when \$HOME unset" + exit 1 +fi + +# Setting $HOME to pwd above causes guestfish to create a history +# file. Remove it. +rm -f .guestfish \ No newline at end of file -- 1.8.3.1