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: Eric Blake
Subject: Re: invoke tilde expansion on quoted string
Date: Thu, 04 Apr 2013 07:11:46 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130311 Thunderbird/17.0.4

On 11/14/2011 07:23 AM, Freddy Vulto wrote:
> This is used in the bash-completion package:

Given that the topic of tilde-completion has recently come up (again), I
wanted to point out:

> 
> ---8<-------------------------------------------------------------------
> 
> # Expand variable starting with tilde (~)
> # We want to expand ~foo/... to /home/foo/... to avoid problems when
> # word-to-complete starting with a tilde is fed to commands and ending
> # up quoted instead of expanded.
> # Only the first portion of the variable from the tilde up to the first
> # slash (~../) is expanded.  The remainder of the variable, containing
> # for example a dollar sign variable ($) or asterisk (*) is not
> # expanded.
> # Example usage:
> #
> #    $ v="~"; __expand_tilde_by_ref v; echo "$v"
> #
> # Example output:
> #
> #       v                  output
> #    --------         ----------------
> #    ~                /home/user
> #    ~foo/bar         /home/foo/bar
> #    ~foo/$HOME       /home/foo/$HOME
> #    ~foo/a  b        /home/foo/a  b
> #    ~foo/*           /home/foo/*
> #  
> # @param $1  Name of variable (not the value of the variable) to expand
> __expand_tilde_by_ref() {
>     # Does $1 start with tilde (~)?
>     if [ "${!1:0:1}" = "~" ]; then
>         # Does $1 contain slash (/)?
>         if [ "${!1}" != "${!1//\/}" ]; then
>             # Yes, $1 contains slash;
>             # 1: Remove * including and after first slash (/), i.e. "~a/b"
>             #    becomes "~a".  Double quotes allow eval.
>             # 2: Remove * before the first slash (/), i.e. "~a/b"
>             #    becomes "b".  Single quotes prevent eval.
>             #       +-----1----+ +---2----+
>             eval $1="${!1/%\/*}"/'${!1#*/}'

Danger.  This is broken, because you aren't sanitizing the contents
passed to eval.

>         else 
>             # No, $1 doesn't contain slash
>             eval $1="${!1}"
>         fi
>     fi
> } # __expand_tilde_by_ref()
> 
> ---8<-------------------------------------------------------------------

$ foo='~;$(date)'
$ __expand_tilde_by_ref foo
bash: Thu: command not found...

If you're going to use eval, you MUST SANITIZE THE INPUT.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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