1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

-o posix: don't import/export variable attributes thru environment

When exporting variables, ksh exports their attributes (such as
'integer' or 'readonly') in a magic environment variable called
"A__z" (string defined in e_envmarker[] in data/msg.c). Child
shells recognise that variable and restore the attributes.

This little-known feature is risky; the environment cannot
necessarily be trusted and that A__z variable is easy to manipulate
before or between ksh invocations, so you can cause a script's
variables to be of the wrong type, or readonly. Backwards
compatibility requires keeping it, at least for now. But it should
be disabled in the posix mode, as it violates POSIX.

To do this, we have to solve a catch-22 in init.c. We must parse
options to know whether to turn on posix mode; it may be specified
as '-o posix' on the command line. The option parsing loop depends
on an initialised environment[*], while environment initialisation
(i.e., importing attributes) should depend on the posix option.

The catch-22 can be solved because initialising just the values
before option parsing is enough to avoid regressions. Importing the
attributes can be delayed until after option parsing. That involves
basically splitting env_init() into two parts while keeping a local
static state variable between them.

src/cmd/ksh93/sh/init.c:
- env_init():
  * Split the function in two stages based on a new
    'import_attributes' parameter. Import values in the first
    stage; import attributes from A__z in the second (if ever).
    Make the 'next' variable static as it keeps a state needed for
    the attributes import stage.
  * Single point of truth, greppability: don't hardcode "A__z" in
    separate character comparisons, but use e_envmarker[].
  * Fix an indentation error.
- sh_init(): When initialising the environment (env_init), don't
  import the attributes from A__z yet; parse options first, then
  import attributes only if posix option is not set.

src/cmd/ksh93/sh/name.c:
- sh_envgen(): Don't export variable attributes to A__z if the
  posix option is set.

src/cmd/ksh93/tests/attributes.sh:
- Check that variable attributes aren't imported or exported
  if the POSIX option is set.

src/cmd/ksh93/sh.1:
- Update.

This was the last item on the TODO list for -o posix for now.
Closes: #20

[*] If environment initialisation is delayed until after option
    parsing, bin/shtests shows various regressions, including:
    restricted mode breaks; the locale is not initialised properly
    so that multibyte variable names break; $SHLVL breaks.
This commit is contained in:
Martijn Dekker 2020-09-05 10:33:50 +02:00
parent 20fcf22973
commit 00d439605f
5 changed files with 51 additions and 19 deletions

View file

@ -980,8 +980,9 @@ The attributes supported by the shell are described
later with the
.B typeset\^
special built-in command.
Exported variables pass values and attributes to
the environment.
Exported variables pass their attributes to the environment so that a newly
invoked ksh that is a child or exec'ed process of the current shell will
automatically import them, unless the \fBposix\fR shell option is on.
.PP
The shell supports both indexed and associative arrays.
An element of an array variable is referenced by a
@ -7040,6 +7041,7 @@ to fail or zero if no command has failed.
.B posix
Enable full POSIX standard compliance mode. This option
is on by default if ksh is invoked as \fBsh\fR. It
disables passing exported variables' attributes (such as integer or readonly) to a new ksh process through the environment,
causes file descriptors > 2 to be left open when invoking another program,
makes the \fB<>\fR redirection operator default to standard input,
disables a hack that makes \fBtest -t\fR (\fB[ -t ]\fR) equivalent to \fBtest -t 1\fR (\fB[ -t 1 ]\fR),