From patchwork Tue Aug 9 21:39:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harald van Dijk X-Patchwork-Id: 9272215 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.web.codeaurora.org (Postfix) with ESMTP id E3868601C2 for ; Tue, 9 Aug 2016 21:39:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CFE2128384 for ; Tue, 9 Aug 2016 21:39:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C3341283E5; Tue, 9 Aug 2016 21:39:25 +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=-6.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_TVD_MIME_EPI 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 C53F128384 for ; Tue, 9 Aug 2016 21:39:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932378AbcHIVjY (ORCPT ); Tue, 9 Aug 2016 17:39:24 -0400 Received: from mailfilter1-k0683s008.csv-networks.nl ([92.48.231.157]:38734 "EHLO mailfilter1-k0683s008.csv-networks.nl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932338AbcHIVjY (ORCPT ); Tue, 9 Aug 2016 17:39:24 -0400 Received: from [84.244.151.217] (helo=hosting12.csv-networks.nl) by mailfilter1-k0683s008.csv-networks.nl with esmtps (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1bXEnX-00088Y-7R; Tue, 09 Aug 2016 21:42:55 +0000 Received: from home.gigawatt.nl ([83.163.3.213] helo=[192.168.178.26]) by hosting12.csv-networks.nl with esmtpa (Exim 4.85) (envelope-from ) id 1bXEk3-0002S2-AN; Tue, 09 Aug 2016 23:39:19 +0200 Subject: Re: Parameter expansion, patterns and fnmatch To: Olof Johansson , dash@vger.kernel.org References: <20160809092832.GB23983@brutus.ethup.se> From: Harald van Dijk Message-ID: <0ce0bca2-3bdd-a1f5-169e-0291a49cd6c7@gigawatt.nl> Date: Tue, 9 Aug 2016 23:39:13 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: <20160809092832.GB23983@brutus.ethup.se> Sender: dash-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dash@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On 09/08/16 11:28, Olof Johansson wrote: > Hello, > > I'm seeing some discrepancies between dash built with --enable-fnmatch > and dash built without that got me curious. Maybe you could help shed > some light? > > foo='[abc]' > echo ${foo#[} > echo ${foo#\[} > > With dash built with --enable-fnmatch: > > abc] > abc] > > With dash built without --enable-fnmatch: > > [abc] > abc] Nice find. > I was able to reproduce this behavior on latest git master > (17a5f24e0). The dash manual states: > >> The end of the character class is indicated by a ]; if the ] is >> missing then the [ matches a [ rather than introducing a character >> class. > > Which to me suggests that the non-fnmatch case is not the expected > behavior. Is this interpretation correct? Yes, this looks like a bug in dash. With the default --disable-fnmatch code, when dash encounters [ in a pattern, it immediately treats the following characters as part of the set. If it then encounters the end of the pattern without having seen a matching ], it attempts to reset the state and continue as if [ was treated as a literal character right from the start. The attempt to reset the state doesn't look right, and has been like this since at least the initial Git commit in 2005. This also affects case [a in [?) echo ok ;; *) echo bad ;; esac which should print ok. Attached is a patch that attempts to reset the state correctly. It passes your test and mine, but I have not yet tested it extensively. > Thanks, > Cheers, Harald van Dijk --- a/src/expand.c +++ b/src/expand.c @@ -1594,7 +1594,8 @@ pmatch(const char *pattern, const char *string) do { if (!c) { p = startp; - c = *p; + q--; + c = '['; goto dft; } if (c == '[') {