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