From patchwork Wed Sep 12 06:27:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 10596841 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8060814F9 for ; Wed, 12 Sep 2018 06:27:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6DADB2984C for ; Wed, 12 Sep 2018 06:27:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 60AFB2985B; Wed, 12 Sep 2018 06:27:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7F1AF2984C for ; Wed, 12 Sep 2018 06:27:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726418AbeILLaU (ORCPT ); Wed, 12 Sep 2018 07:30:20 -0400 Received: from orcrist.hmeau.com ([104.223.48.154]:52634 "EHLO deadmen.hmeau.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726027AbeILLaU (ORCPT ); Wed, 12 Sep 2018 07:30:20 -0400 Received: from gondobar.mordor.me.apana.org.au ([192.168.128.4] helo=gondobar) by deadmen.hmeau.com with esmtps (Exim 4.89 #2 (Debian)) id 1fzycQ-00028Q-TC; Wed, 12 Sep 2018 14:27:19 +0800 Received: from herbert by gondobar with local (Exim 4.89) (envelope-from ) id 1fzycO-0002Fr-2n; Wed, 12 Sep 2018 14:27:16 +0800 Date: Wed, 12 Sep 2018 14:27:16 +0800 From: Herbert Xu To: Martijn Dekker Cc: DASH shell mailing list Subject: [PATCH v2] expand: Fix multiple issues with EXP_DISCARD in evalvar Message-ID: <20180912062716.boa32pwabi6fpaal@gondor.apana.org.au> References: <20180905132359.s57mpwhsm3opsrvg@gondor.apana.org.au> <20180906050715.vb3tlbagyiryc3pd@gondor.apana.org.au> <38011ac0-04b7-2dd7-b1a8-11377f7c9ade@inlv.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <38011ac0-04b7-2dd7-b1a8-11377f7c9ade@inlv.org> User-Agent: NeoMutt/20170113 (1.7.2) Sender: dash-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dash@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Fri, Sep 07, 2018 at 06:55:29AM +0200, Martijn Dekker wrote: > > But now I'm encountering another, similar bug, that was a bit harder to > track down: > > $ src/dash -c 'foo=bar; echo ${foo=BUG}; echo $foo' > barBUG > bar > $ src/dash -c 'foo=bar; echo ${foo:=BUG}; echo $foo' > barBUG > bar > > Expected output: 'bar' twice in both cases. The ${foo=BUG} and ${foo:=BUG} > expansions fail to discard the word 'BUG' if foo is set. Thanks for the update. In this case we didn't call the parsing function subevalvar at all when we should have called it with EXP_DISCARD. As patchwork was having issues I've rolled all three patches into one. Cheers, ---8<--- The commit 3cd538634f71538370f5af239f342aec48b7470b broke parameter expansion in multiple ways because the EXP_DISCARD flag wasn't set or tested for various cases: $ src/dash -c 'var=; echo ${var:+nonempty}' nonempty $ src/dash -u -c 'unset foo bar; echo ${foo+${bar}}' dash: 1: bar: parameter not set $ src/dash -c 'foo=bar; echo ${foo=BUG}; echo $foo' barBUG bar $ This patch fixes them by introducing a new discard variable that tracks whether the extra word should be discarded or not when it is parsed. Reported-by: Martijn Dekker Fixes: 3cd538634f71 ("expand: Do not reprocess data when...") Signed-off-by: Herbert Xu Reported-by: Martijn Dekker Signed-off-by: Herbert Xu diff --git a/src/expand.c b/src/expand.c index 14daa63..856b7a9 100644 --- a/src/expand.c +++ b/src/expand.c @@ -698,6 +698,7 @@ evalvar(char *p, int flag) int patloc; int startloc; ssize_t varlen; + int discard; int quoted; varflags = *p++; @@ -713,41 +714,41 @@ again: if (varflags & VSNUL) varlen--; + discard = varlen < 0 ? EXP_DISCARD : 0; + switch (subtype) { case VSPLUS: - varlen = -1 - varlen; + discard ^= EXP_DISCARD; /* fall through */ case 0: case VSMINUS: - p = argstr(p, flag | EXP_TILDE | EXP_WORD); - if (varlen < 0) - return p; + p = argstr(p, flag | EXP_TILDE | EXP_WORD | + (discard ^ EXP_DISCARD)); goto record; case VSASSIGN: case VSQUESTION: - if (varlen >= 0) - goto record; - p = subevalvar(p, var, 0, startloc, varflags, - flag & ~QUOTES_ESC); + (flag & ~QUOTES_ESC) | + (discard ^ EXP_DISCARD)); - if (flag & EXP_DISCARD) - return p; + if ((flag | ~discard) & EXP_DISCARD) + goto record; varflags &= ~VSNUL; + subtype = VSNORMAL; goto again; } - if (varlen < 0 && uflag) + if ((discard & ~flag) && uflag) varunset(p, var, 0, 0); if (subtype == VSLENGTH) { if (flag & EXP_DISCARD) return p; cvtnum(varlen > 0 ? varlen : 0, flag); - goto record; + goto really_record; } if (subtype == VSNORMAL) @@ -765,7 +766,7 @@ again: } #endif - flag |= varlen < 0 ? EXP_DISCARD : 0; + flag |= discard; if (!(flag & EXP_DISCARD)) { /* * Terminate the string and start recording the pattern @@ -778,9 +779,10 @@ again: p = subevalvar(p, NULL, patloc, startloc, varflags, flag); record: - if (flag & EXP_DISCARD) + if ((flag | discard) & EXP_DISCARD) return p; +really_record: if (quoted) { quoted = *var == '@' && shellparam.nparam; if (!quoted)