git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [RFC] shell: local x=$1 may need to quote the RHS

From
KKKonstantin Khomoutov <kostix@bswap.ru>
Date
Jan 25, 2022, 09:24 UTC
Message-ID
<20220125092419.cgtfw32nk2niazfk@carbon>
In-Reply-To
<xmqqsftc3nd6.fsf@gitster.g>
On Mon, Jan 24, 2022 at 12:11:33PM -0800, Junio C Hamano wrote:
Show 24 quoted lines
> Even though this message ends with a patch that could be applied to
> your tree, it is not for application at all.  It is to demonstrate a
> potential problem in the code in our tree. 
> 
> While I was playing with the "Linux development environment (beta)"
> on one of my Chromebooks, I say its default /bin/sh (which is Dash
> 0.5.10) mishandled this construct:
> 
> 	func () {
> 		local x=$1
> 		clobber x and nothing else and feel safe
> 		message="I expect this to be visible by the caller"
> 	}
> 
> 	func "a message"
> 	use "$message"
> 
> It assigned 'a' to $x in the function, DECLARED the varilable
> $message as local to the function, hence the caller after func
> returned did not see what I intended to see in $message.
> 
> The breakage is subtle; unless you have a character in $1 that would
> not make a valid variable name, you won't get any error message yet
> the program would behave in an unexpected way.

Sorry, I might have not followed the entire thread, but assignment in `local` is a bashism, and dash can only handle the declaration part with `local`, not assignment; hence the safe code should read

  local x
  x="$1"
To cite the dash manual page:
| Variables may be declared to be local to a function by using a local
| command.  This should appear as the first statement of a function, and the
| syntax is
| 
|    local [variable | -] ...
| 
| Local is implemented as a builtin command.
| 
| When a variable is made local, it inherits the initial value and exported
| and readonly flags from the variable with the same name in the surrounding
| scope, if there is one.  Otherwise, the vari‐ able is initially unset.  The
| shell uses dynamic scoping, so that if you make the variable x lo‐ cal to
| function f, which then calls function g, references to the variable x made
| inside g will refer to the variable x declared inside f, not to the global
| variable named x.
| 
| The only special parameter that can be made local is “-”.  Making “-” local
| any shell options that are changed via the set command inside the function
| to be restored to their original values
| when the function returns.
Previous: Junio C HamanoNext: Junio C Hamano
Message 2 of 9 in “[RFC] shell: local x=$1 may need to quote the RHS”
  1. Junio C HamanoJan 24, 2022
  2. Konstantin KhomoutovJan 25, 2022
  3. Junio C HamanoJan 25, 2022
  4. Taylor BlauJan 25, 2022
  5. Junio C HamanoJan 26, 2022
  6. Konstantin KhomoutovJan 26, 2022
  7. SZEDER GáborJan 26, 2022
  8. Taylor BlauJan 26, 2022
  9. Junio C HamanoJan 27, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.