[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-bash] Performing quote removal on data
From: |
Maarten Billemont |
Subject: |
Re: [Help-bash] Performing quote removal on data |
Date: |
Wed, 28 May 2014 16:05:47 -0400 |
On May 28, 2014, at 3:40 PM, Greg Wooledge <address@hidden> wrote:
>>> On May 28, 2014 1:54 AM, "Maarten Billemont" <address@hidden> wrote:
>>>> Suppose you have a variable whose value contains bash-escapes and quotes,
>>>> and you need to perform the operations bash would perform on that string
>>>> to turn it into a literal word.
>>>>
>>>> var=?foo\ bar/?
>
> Ugh, stupid quotes?
Sorry, disabled those, I hope! var='foo\ bar/'
>
>>>> How would you proceed to get the literal ?foo bar/? out of that,
>
> eval
>
>>>> in a safe way (ie. perform just pathname expansion and quote removal,
>>>> maybe even word splitting but that taking into account the quoted
>>>> whitespace)? Specifically, I do NOT want any risk of performing command
>>>> execution or any other expansions on the data (eg. ?foo $(rm -rf ~)/?
>
> Oh. So you want to do an eval on user-supplied code, but you don't want
> to ever run any commands other than variable assignments?
>
> Maybe you could set resource limits in such a way that fork() would
> become impossible? Might be OS-specific. Make sure you either do so
> in a subshell, or that you have a way to restore the limits afterward.
>
> Short of modifying bash to add shopts to disable command substitutions
> at will, or writing a full-blown bash parser in bash, I don't think
> there's any other way to make eval-able code safe to eval.
>
> I actually think "shopt -s nocmdsubs" or similar might be a useful
> feature, but I won't try to implement it. Also, there's still another
> problem: what prevents the malicious user from sticking "shopt -u ..."
> in front of the command substitution? Then you'd need to make the
> "shopt -s nocmdsubs" irreversible, which means you'd still need to do
> it all in a subshell, and communicate the results back to the parent
> somehow. It's quite a mess.
>
> (For that matter, if a "no forking" resource limit is reversible, then
> you have the same problem! Ugh....)
I'd rather not rely on eval at all. The behaviour I want is essentially the
default bash pathname completion:
mkdir "dir 1"
Now:
- "dir" completes to "dir\ 1"
- "dir\ " completes to "dir\ 1"
- "di*" completes to "dir\ 1"
- "$(:)di" does not complete
man bash does not describe exactly what bash's default pathname completion
does, but it looks like we're seeing quote removal, word splitting and then
pathname expansion.
Since the goal is essentially to write a reliable programmable completion
function, and that function needs to populate a COMPREPLY array based on the
word that is being completed, it might be possible to avoid converting the word
to be completed into a literal:
1. If we have a list of possible completions to filter with the word currently
being completed, we can use this instead:
partial=${COMP_WORDS[COMP_CWORD]} # This contains the readline word currently
being completed.
completions=( house ball printer school "school bus" ) # A list of eligible
words for completion.
IFS=$'\n' read -r -d '' COMPREPLY < <(compgen -W "$(printf '%q '
"address@hidden")" "$partial") # holy crap, it really shouldn't have to be this
hard to do it right!
2. If we do NOT have a list of possible completions but rather need the current
word being completed to populate that list, we're in trouble.
2a. One such case is doing pathname completion, but here we can fall back to
compgen -o bashdefault:
IFS=$'\n' read -r -d '' COMPREPLY < <(compgen -o bashdefault "$partial*") #
notice the trailing *
Sadly though, while it completes "dir\ " into "dir 1" just fine, it does NOT
complete "dir' " or "dir' '" into "dir 1". Consistency? Why would you want
that?
Notice also that compgen -o dirnames "$partial" can be used to complete "dir'
'" into "dir 1" nicely, but that in turn does not support pathname expansion
and also only works on dirs. The similarly named -o filenames does not do the
same for filenames (I couldn't actually reproduce any effect of -o filenames).
So on that note, how do I, in programmable completion, perform a simple,
regular, default bash pathname completion without re-implementing quote removal
in bash code?
— Maarten Billemont (lhunath) —
me: http://www.lhunath.com – business: http://www.lyndir.com –
http://masterpasswordapp.com
signature.asc
Description: Message signed with OpenPGP using GPGMail
- [Help-bash] Performing quote removal on data, Maarten Billemont, 2014/05/28
- Message not available
- Re: [Help-bash] Performing quote removal on data, Maarten Billemont, 2014/05/28
- Re: [Help-bash] Performing quote removal on data, Greg Wooledge, 2014/05/28
- Re: [Help-bash] Performing quote removal on data,
Maarten Billemont <=
- Re: [Help-bash] Performing quote removal on data, Greg Wooledge, 2014/05/28
- Re: [Help-bash] Performing quote removal on data, Maarten Billemont, 2014/05/28
- Re: [Help-bash] Performing quote removal on data, Greg Wooledge, 2014/05/28
- Re: [Help-bash] Performing quote removal on data, Maarten Billemont, 2014/05/28
- Re: [Help-bash] Performing quote removal on data, Greg Wooledge, 2014/05/29
- Re: [Help-bash] Performing quote removal on data, Chet Ramey, 2014/05/30
- Re: [Help-bash] Performing quote removal on data, Chet Ramey, 2014/05/30