Path: csiph.com!xmission!news.snarked.org!news.linkpendium.com!news.linkpendium.com!panix!usenet.stanford.edu!not-for-mail From: Great Big Dot Newsgroups: gnu.bash.bug Subject: Removing a function's function attribute makes `declare` not know it's a function (kind of) Date: Wed, 21 Nov 2018 23:02:16 -0500 Lines: 133 Approved: bug-bash@gnu.org Message-ID: NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" X-Trace: usenet.stanford.edu 1542859360 26214 208.118.235.17 (22 Nov 2018 04:02:40 GMT) X-Complaints-To: action@cs.stanford.edu To: bug-bash@gnu.org Envelope-to: bug-bash@gnu.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=WDQAtmwIfy2/RR2oa76oSiKyymmH6cXHYzTtDaFvx/o=; b=ArcwBZqjJSMHkD3d1KiOUi+t48Y5FUsGwM0lnwlmGP3XQqT+jTRYAXcWDRXCb2Zxw1 6O3ANFcjXfmR5RrwG7h7DBLVeS5kR+g3XXLMS4F8BcHMihJDAFRyw81+SzYPGCg8JvJ6 m+Hjm3uFf9kTMVU3fNlBrSerzbImcSApSk3UFDIIJtZwtclVwKQXHCPvvfIqW4jsOmtE QR7zYOY29dVPjgGfQGLLjEyeuXZ8ej0lcg1pb4kztKlneniVp5+d76rPanHkIsuDfEKo 0OBVU/IHIxxnJD+sxQUB3N4n0qdhCiesEwpjUSjK/h60/yEnGYCXLxfQoB3lJdjlvtjh KLYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=WDQAtmwIfy2/RR2oa76oSiKyymmH6cXHYzTtDaFvx/o=; b=b4323ftm/4SX0qcVyzcHZY9Gubgm8seorQUcrVpPwALg0gatd4R7XIbKpe7LdiHKCi wWyUZZ7kcxkNcuFsIw2WO+HWZyPaUtXq+HAuEJ6I1lKQwhnU+bC+vkmaB3usSeBH+5In SggE4KU/EFg9CucmkObdWU3Rc8wYhNsGh8n/bTwhhduaKs4jww77RZElfMzdR/7ZonUw zXiDBEMn20pSbCu3amY7hT1jVx6gaCr9QRcDT9HSiCTyxV8SU9Hlqjs9aU6QUIKSoiQL sz6lvk2PiSQ1LYk3ewSDbOxfCQP3UdtCy7o7ae+uqC1JfKas7albHv1zGWgHmbDMfKFy 6GKA== X-Gm-Message-State: AGRZ1gLbBAfqwilBRXPNtbi3U9LVukTG5Uqf28RWWxrcagYUGvpSDb1a Ct9W14WCnFz2IpsquYYdjwylBPeRGilXrE91UC41R+64 X-Google-Smtp-Source: AJdET5eC1kRa/uUHnrf6kDUStx42pLOJ+EgTq9rxwc3s244K2oIgd4m8K0Ru9viB2Y1eRi+mFPbcDB7Z1J2sCUm/4Rg= X-Received: by 2002:ac2:4215:: with SMTP id y21mr5280516lfh.6.1542859348345; Wed, 21 Nov 2018 20:02:28 -0800 (PST) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::129 X-Content-Filtered-By: Mailman/MimeDel 2.1.21 X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com gnu.bash.bug:14841 Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' -DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fno-plt -DDEFAULT_PATH_VALUE='/usr/local/sbin:/usr/local/bin:/usr/bin' -DSTANDARD_UTILS_PATH='/usr/bin' -DSYS_BASHRC='/etc/bash.bashrc' -DSYS_BASH_LOGOUT='/etc/bash.bash_logout' -DNON_INTERACTIVE_LOGIN_SHELLS -Wno-parentheses -Wno-format-security uname output: Linux ArchBox0 4.19.2-arch1-1-ARCH #1 SMP PREEMPT Tue Nov 13 21:16:19 UTC 2018 x86_64 GNU/Linux Machine Type: x86_64-unknown-linux-gnu Bash Version: 4.4 Patch Level: 23 Release Status: release Description: The manual's section on `declare` (aka `typeset`) states that you can negate any attribute except for "-r" and "-a" by replacing "-" with "+". Aside from the fact that this appears to mistakenly leave out associative arrays ("-A"), this leaves one to wonder what happens if you try to negate the function attribute. At first glance, this seems impossible, since a (non-option) argument to `declare` is assumed to be a variable, and only gets considered a function if you include the "-f" (or "-F") option. But, if you include *both* "-f" and "+f", something unusual happens. First the setup and demonstration of `declare`'s usual behavior: $ func () { echo 'hello world'; } $ declare -p -- func bash: declare: func: not found $ declare -pF -- func declare -f func $ declare -pf -- func func () { echo 'hello world' } If we try to remove func's function attribute by just saying "declare +f -- func", `declare` (as usual) assumes we mean the *variable *"func", and nothing of interest happens. It's equivalent to "declare -- func". But what if we include "-f" to state we're talking about functions and not variables, yet include "+f" to try to turn it off? $ declare -f +f -- func # Expectation: Error message or no-op. $ func # hello world # So nothing changed, right? Wrong. $ declare -p -- func # bash: declare: func: not found # Again as expected. But... $ declare -pF -- func # declare -- func # The "-f" attribute is missing. Weird... $ declare -pf -- func # declare -- func=" " # A tab character? What the heck?? Where did that come from? Make no mistake, the function is still a function. Executing it works the same as before, and attempting to expand it as a parameter fails just as before. In almost all respects, the line `declare -f +f -- func` does nothing. Yet `declare` has been tricked into an inconsistent view of the world! Namely, it appears to believe the following things simultaneously: *1.* There is no variable named "func". *2.* There is a function named "func". *3.* This function does NOT have the "-f" attribute. (???) *4.* This function has a variable definition, not a function definition. (???) *5.* The value of this variable definition is a single tab character. (???????) Again, `declare`'s vision of the world appears to have no basis in reality. In particular, expanding "$func" does not yield a tab. Neither the order nor the case of the "f"-options on the problematic line appear to have any affect. Few more random observations: $ declare -F -- func # func # Same as normal. $ declare -f -- func # func () # } { # } Same as normal again. echo 'hello world' # } Has `declare` regained sanity? (Spoiler: no) } # } # (In the below, irrelevant lines have been removed.) $ declare # func # I'm not sure if this is ever a legitimate output line for a bare `declare`. $ declare -f # Nothing. In particular, different from `declare -f -- func`. $ declare -F # Again nothing, again different from `declare -F -- func`. $ declare -fp # declare -- func=" " # Identical wrong answer as `declare -fp -- func`. $ declare -Fp # declare -- func # Ditto. So, we can add these two to the list of things `declare` believes about `func`. *6.* The function `func` has a function definition. *7.* The function (possibly variable?) named "func" exists, but has no definition. (???) *8.* There is no function named "func". (???) What is going on here? Repeat-By: $ func () { echo 'hello, world'; } # Setup. $ declare -f +f -- func # The problem. $ declare -pf -- func # declare -- func=" " # Now `declare` believes nonsensical things like this. Fix: N/A. This is just an edge case that would never actually be used. If anything, this is the expected behavior: expected () { printf -- 'bash: declare: %s: inconsistent flags or something.' "$1" 1>&2; return 1; } So, just replace any occurrences of the problematic command with calls to the above, and you're all set! ;)