Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > gnu.bash.bug > #15843

Re: Preventing Bash Variable Confusion

From Robert Elz <kre@munnari.OZ.AU>
Newsgroups gnu.bash.bug
Subject Re: Preventing Bash Variable Confusion
Date 2020-01-30 01:03 +0700
Message-ID <mailman.51.1580321121.2384.bug-bash@gnu.org> (permalink)
References <20200129142305.GX1350@eeg.ccf.org> <20200128210225.GC12574@localhost4.local> <20806.1580277461@jinx.noi.kre.to> <19032.1580321011@jinx.noi.kre.to>

Show all headers | View raw


    Date:        Wed, 29 Jan 2020 09:23:05 -0500
    From:        Greg Wooledge <wooledg@eeg.ccf.org>
    Message-ID:  <20200129142305.GX1350@eeg.ccf.org>

  | As far as functions go, bash allows you to define local variables within
  | a function.  This avoids namespace collisions as long as you're within
  | that function.

It actually doesn't, or not generally - it allows the function to avoid
namespace collisions with random globals (or other locals) that might exist
up the call stack, but doesn't prevent functions that are called from
trampling all over this function's local vars.

Some variants of ksh apparently make local vars work more like local
vars in C (or other similar languages) and inaccessible outside the
function, but that doesn't really work well for shell, it is useful
to be able to make things like PATH, IFS, ... local in a function,
change their values, and then call other functions which then use
(and can alter) the modified values.

  | Obviously, sh doesn't have this feature,

The POSIX spec doesn't have local vars, but all the shells that are
used very much do, though the details of exactly how they work differ.
If we could get everyone to agree on how they should work, they'd be
in POSIX by now as well.

  | Since the Subject: of this thread includes the word "Bash", it seems
  | likely that the OP is not concerned with portable-sh issues at the
  | moment.

Of course, which is why I suggested using local vars.   One must however
remain aware of the limitations.  Of course if the function in question
calls no other functions, then there is no problem, but knowing that is
true for any function that does any more than variable manipulations
(X=${Y%...} type things, including arithmetic, and which doesn't do everything
in a subshell) is very difficult, and then unless the function writes
"command" (or in bash, perhaps "builtin") before everything that is a
command, then it remains vulnerable.

Consider the proposed trap handling function, copied from another message

	sigint_handler() {
    		trap - INT
    		kill -INT $$
	}

(which has no vars, and manipulates none, so looks dafe enough) but
then consider

	trap() {
		My_Var=123
		command trap "$@"
	}
	kill() {
		PATH=/bin:/usr/bin
		command kill "$@"
	}

and to make this a little more illustrative, consider that instead
of the above, we have:

	sigint_handler() {
		local My_Var=$$
		trap - INT
		kill -s INT "${My_Var}"
	}

None of this is very likely in practice, but things like it do
occasionally happen.

It could be fixed by

	sigint_handler() {
		command local My_Var=$$
		command trap - INT
		command kill -s INT "${My_Var}"
	}

but when you find someone who actually writes their code like that,
please let me know.

kre


Back to gnu.bash.bug | Previous | Next | Find similar


Thread

Re: Preventing Bash Variable Confusion Robert Elz <kre@munnari.OZ.AU> - 2020-01-30 01:03 +0700

csiph-web