bug-bash
[Top][All Lists]
Advanced

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

Re: invoke tilde expansion on quoted string


From: Greg Wooledge
Subject: Re: invoke tilde expansion on quoted string
Date: Thu, 4 Apr 2013 09:34:03 -0400
User-agent: Mutt/1.4.2.3i

On Thu, Apr 04, 2013 at 09:17:00PM +0800, Chris Down wrote:
> Perhaps my reply here[1] can help out. Only looked briefly, but it seems it
> could at least eliminate the calls to eval (although it doesn't support some
> more rare tilde expansions).
> 
> Chris
> 
> 1: http://lists.gnu.org/archive/html/help-bash/2013-02/msg00030.html

That code reads /etc/passwd directly.  That will fail on systems where
user accounts are provided by NIS, NIS+, LDAP, or any other thing that's
not /etc/passwd.

Here's the code that I wrote on another mailing list, from which parts
of the discussion have already started being echoed here:

case $1 in
  \~ )
    printf '%s\n' "$HOME" ;;
  \~/* )
    printf '%s\n' "$HOME/${1#??}" ;;
  \~* )
    user=${1%%/*}
    path=${1#*/}
    # Sanitize user before feeding it to eval.
    # You must adjust this code based on what characters are legal in your
    # system's usernames.  If your system allows shell metacharacters in
    # usernames, you are screwed.  Just give up now (switch to perl).
    user=${user#\~}
    user2=${user//[^[:alnum:]._-]/}
    if [[ $user != "$user2" ]]; then
      echo "Error: invalid characters in username" >&2
      exit 1
    fi
    eval "home=~$user2"
    case $1 in
      */* ) printf '%s\n' "$home/$path" ;;
      *   ) printf '%s\n' "$home" ;;
    esac ;;
  * )
    printf '%s\n' "$1" ;;
esac

As I said on the other list, this code must be adjusted based on your
local system's definition of what constitutes a valid username.  Not
all valid usernames can be accomodated by this approach -- particularly,
user accounts with dollar signs in them are NOT going to be manageable
without a second pass to escape those.

If you need more flexibility than this provides, consider switching to
some other language that has support for calling getpwnam() directly.

(There was also some ambiguity in the stated goals in the request that
appeared on the other mailing list.  The code presented here was written
under the interpretation that the input should be tilde-expanded in the
same way that bash performs tilde expansions, and that it was safe to
ignore tilde expansions in inputs of the form "hostname:~username/pathname"
and "variable=~username/pathname".)



reply via email to

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