From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7088 invoked by alias); 5 Sep 2017 18:21:25 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 22865 Received: (qmail 25883 invoked by uid 1010); 5 Sep 2017 18:21:25 -0000 X-Qmail-Scanner-Diagnostics: from kahlil.inlv.org by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(37.59.109.123):SA:0(-1.9/5.0):. Processed in 1.25748 secs); 05 Sep 2017 18:21:25 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD autolearn=ham autolearn_force=no version=3.4.1 X-Envelope-From: martijn@inlv.org X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Subject: Re: Interpret Parameter Value at Time of Function Definition To: zsh-users@zsh.org References: From: Martijn Dekker Message-ID: <4ccab1d5-7944-dc27-9ccf-be377ff8b038@inlv.org> Date: Tue, 5 Sep 2017 20:21:18 +0200 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Thunderbird/52.1.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-GB Content-Transfer-Encoding: 7bit Op 05-09-17 om 15:47 schreef Vin Shelton: [...] > $ aaa=bbb > $ function t { > print aaa = \"$aaa\" > } > $ t > aaa = "bbb" > $ aaa=ccc t > aaa = "ccc" > > I would like to interpret $aaa at read time, so that: > > aaa=ccc t > > would print: > > aaa = "bbb" > > How do I do that? AFAIK, the only way to do this without side effects is by using 'eval': aaa=bbb eval "function t { print \"aaa = $aaa\" }" typeset -f t The value of "$aaa" is now hard-coded in the function definition, as you can see by the output of 'typeset -f t'. Note that you have to be very careful to backslash-escape everything except $aaa correctly so that only $aaa is interpreted at read time, otherwise you're going to get hard-to-trace bugs. Also, this should ONLY be done this way if $aaa is guaranteed to contain trusted data only. If the value of $aaa can be given by other users from the outside, you've got a code injection vulnerability, as any shell grammar in $aaa will be interpreted and executed by 'eval'. For instance, setting aaa='"; echo injection"' would print "injection". You can avoid the vulnerability by shell-quoting the value of $aaa before using it, which in zsh is easy to do using the (q) parameter expansion flag: # ... $aaa contains some untrusted data ... eval "function t { print -r \"aaa =\" ${(q)aaa} }" typeset -f t The expansion ${(q)aaa} is appropriately quoted as a string using shell grammar so it will never be interpreted as code. This is advanced stuff, so be careful. - Martijn