-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix test -v for numeric types & set/unset state for short int
This commit fixes two interrelated problems. 1. The -v unary test/[/[[ operator is documented to test if a variable is set. However, it always returns true for variable names with a numeric attribute, even if the variable has not been given a value. Reproducer: $ ksh -o nounset -c 'typeset -i n; [[ -v n ]] && echo $n' ksh: n: parameter not set That is clearly wrong; 'echo $n' should never be reached and the error should not occur, and does not occur on mksh or bash. 2. Fixing the previous problem revealed serious breakage in short integer type variables that was being masked. After applying that fix and then executing 'typeset -si var=0': - The conditional assignment expansions ${var=123} and ${var:=123} assigned 123 to var, even though it was set to 0. - The expansions ${var+s} and ${var:+n} incorrectly acted as if the variable was unset and empty, respectively. - '[[ -v var ]]' and 'test -v var' incorrectly returned false. The problems were caused by a different storage method for short ints. Their values were stored directly in the 'union Value' member of the Namval_t struct, instead of allocated on the stack and referred to by a pointer, as regular integers and all other types do. This inherently broke nv_isnull() as this leaves no way to distinguish between a zero value and no value at all. (I'm also pretty sure it's undefined behaviour in C to check for a null pointer at the address where a short int is stored.) The fix is to store short ints like other variables and refer to them by pointers. The NV_INT16P combined bit mask already existed for this, but nv_putval() did not yet support it. src/cmd/ksh93/bltins/test.c: test_unop(): - Fix problem 1. For -v, only check nv_isnull() and do not check for the NV_INTEGER attribute (which, by the way, is also used for float variables by combining it with other bits). See also 5aba0c7 where we recently fixed nv_isnull() to work properly for all variable types including short ints. src/cmd/ksh93/sh/name.c: nv_putval(): - Fix problem 2, part 1. Add support for NV_INT16P. The code is simply copied and adapted from the code for regular integers, a few lines further on. The regular NV_SHORT code is kept as this is still used for some special variables like ${.sh.level}. src/cmd/ksh93/bltins/typeset.c: b_typeset(): - Fix problem 2, part 2. Use NV_INT16P instead of NV_SHORT. src/cmd/ksh93/tests/attributes.sh: - Add set/unset/empty/nonempty tests for all numeric types. src/cmd/ksh93/tests/bracket.sh, src/cmd/ksh93/tests/comvar.sh: - Update a couple of existing tests. - Add test for [[ -v var ]] and [[ -n ${var+s} ]] on unset and empty variables with many attributes. src/cmd/ksh93/COMPATIBILITY: - Add a note detailing the change to test -v. src/cmd/ksh93/data/builtins.c, src/cmd/ksh93/sh.1: - Correct 'typeset -C' documentation. Variables declared as compound are *not* initially unset, but initially have the empty compound value. 'typeset' outputs them as: typeset -C foo=() and not: typeset -C foo and nv_isnull() is never true for them. This may or may not technically be a bug. I don't think it's worth changing, but it should at least be documented correctly.
- Loading branch information
Showing
10 changed files
with
79 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters