commit bash-20180309 snapshot

This commit is contained in:
Chet Ramey
2018-03-12 08:10:29 -04:00
parent 2e66dc02d6
commit bf5b8103d4
22 changed files with 350 additions and 17 deletions
+22
View File
@@ -15047,3 +15047,25 @@ subst.c
we are checking whether value is null, so we can have different
error messages for ${x:?} and ${x?}. Report and fix from
don fong <dfong@dfong.com>
3/5
---
lib/readline/bind.c
- _rl_read_file: instead of calling stat/open on the passed filename,
use open/fstat to avoid one possible filename translation and close
a small (benign) race condition. Report and fix from Roy Ivy
<roy.ivy.iii@gmail.com>
3/11
----
variables.c
- makunbound: if new variable localvar_unset is non-zero, mark local
vars in previous scopes as invisible and unset so they will show
up as unset until that previous scope returns (similar to how local
variables in the current local scope are handled). localvar_unset
is currently set to 0 with no way for a script to change its value.
Eventually there will be an option to modify it. From a bug-bash
discussion started by Nikolai Kondrashov <spbnick@gmail.com> back
on 2/11/2018
+3
View File
@@ -864,6 +864,7 @@ tests/array21.sub f
tests/array22.sub f
tests/array23.sub f
tests/array24.sub f
tests/array25.sub f
tests/array-at-star f
tests/array2.right f
tests/assoc.tests f
@@ -1125,6 +1126,7 @@ tests/nameref15.sub f
tests/nameref16.sub f
tests/nameref17.sub f
tests/nameref18.sub f
tests/nameref19.sub f
tests/nameref.right f
tests/new-exp.tests f
tests/new-exp1.sub f
@@ -1348,6 +1350,7 @@ tests/varenv6.sub f
tests/varenv7.sub f
tests/varenv8.sub f
tests/varenv9.sub f
tests/varenv10.sub f
tests/version f
tests/version.mini f
tests/vredir.tests f
+15 -3
View File
@@ -148,17 +148,20 @@ SYSTEM_FLAGS = -DPROGRAM='"$(Program)"' -DCONF_HOSTTYPE='"$(Machine)"' -DCONF_OS
BASE_CCFLAGS = $(SYSTEM_FLAGS) $(LOCAL_DEFS) \
$(DEFS) $(LOCAL_CFLAGS) $(INCLUDES)
CCFLAGS = $(ASAN_CFLAGS) $(BASE_CCFLAGS) ${PROFILE_FLAGS} $(CPPFLAGS) $(CFLAGS)
CCFLAGS = $(ADDON_CFLAGS) $(BASE_CCFLAGS) ${PROFILE_FLAGS} $(CPPFLAGS) $(CFLAGS)
CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
BASE_LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
LDFLAGS = ${ASAN_LDFLAGS} ${BASE_LDFLAGS} ${PROFILE_FLAGS} ${STATIC_LD}
LDFLAGS = ${ADDON_LDFLAGS} ${BASE_LDFLAGS} ${PROFILE_FLAGS} ${STATIC_LD}
LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ $(LOCAL_LDFLAGS) $(CFLAGS_FOR_BUILD)
ASAN_XCFLAGS = -fsanitize=address -fno-omit-frame-pointer
ASAN_XLDFLAGS = -fsanitize=address
GCOV_XCFLAGS = -fprofile-arcs -ftest-coverage
GCOV_XLDFLAGS = -fprofile-arcs -ftest-coverage
INCLUDES = -I. @RL_INCLUDE@ -I$(srcdir) -I$(BASHINCDIR) -I$(LIBSRC) $(INTL_INC)
# Maybe add: -Wextra
@@ -602,7 +605,12 @@ lint:
${MAKE} ${MFLAGS} CFLAGS='${GCC_LINT_FLAGS}' .made
asan:
${MAKE} ${MFLAGS} ASAN_CFLAGS='${ASAN_XCFLAGS}' ASAN_LDFLAGS='${ASAN_XLDFLAGS}' .made
${MAKE} ${MFLAGS} ADDON_CFLAGS='${ASAN_XCFLAGS}' ADDON_LDFLAGS='${ASAN_XLDFLAGS}' .made
# cheating
gcov:
${MAKE} ${MFLAGS} ADDON_CFLAGS='${GCOV_XCFLAGS}' ADDON_LDFLAGS='${GCOV_XLDFLAGS}' .made
# have to make this separate because making tests depend on $(PROGRAM)
asan-tests: asan $(TESTS_SUPPORT)
@@ -611,6 +619,10 @@ asan-tests: asan $(TESTS_SUPPORT)
@( cd $(srcdir)/tests && \
PATH=$(BUILD_DIR)/tests:$$PATH THIS_SH=$(THIS_SH) $(SHELL) ${TESTSCRIPT} )
profiling-tests: ${PROGRAM}
@test "X$$PROFILE_FLAGS" == "X" && { echo "profiling-tests: must be built with profiling enabled" >&2; exit 1; }
@${MAKE} ${MFLAGS} tests TESTSCRIPT=run-gprof
version.h: $(SOURCES) config.h Makefile patchlevel.h
$(SHELL) $(SUPPORT_SRC)mkversion.sh -b -S ${topdir} -s $(RELSTATUS) -d $(Version) -o newversion.h \
&& mv newversion.h version.h
+1 -1
View File
@@ -94,7 +94,7 @@ INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$
BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \
${INCLUDES} $(LOCAL_CFLAGS)
CCFLAGS = ${ASAN_CFLAGS} $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
CCFLAGS = ${ADDON_CFLAGS} $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
+19 -2
View File
@@ -573,8 +573,9 @@ restart_new_var_name:
}
/* However, if we're turning off the nameref attribute on an existing
nameref variable, we first follow the nameref chain to the end,
modify the value of the variable this nameref variable references,
*CHANGING ITS VALUE AS A SIDE EFFECT* then turn off the nameref
modify the value of the variable this nameref variable references
if there is an assignment statement argument,
*CHANGING ITS VALUE AS A SIDE EFFECT*, then turn off the nameref
flag *LEAVING THE NAMEREF VARIABLE'S VALUE UNCHANGED* */
else if (var == 0 && (flags_off & att_nameref))
{
@@ -592,6 +593,16 @@ restart_new_var_name:
any_failed++;
NEXT_VARIABLE ();
}
/* If all we're doing is turning off the nameref attribute, don't
bother with VAR at all, whether it exists or not. Just turn it
off and go on. */
if (refvar && flags_on == 0 && offset == 0 && (flags_off & ~att_nameref) == 0)
{
VUNSETATTR (refvar, att_nameref);
NEXT_VARIABLE ();
}
if (refvar)
/* XXX - use declare_find_variable here? */
var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
@@ -671,6 +682,12 @@ restart_new_var_name:
value = name + namelen;
}
free (oldname);
/* OK, let's turn off the nameref attribute.
Now everything else applies to VAR. */
if (flags_off & att_nameref)
VUNSETATTR (refvar, att_nameref);
goto restart_new_var_name;
/* NOTREACHED */
}
+4
View File
@@ -92,6 +92,7 @@ extern int glob_asciirange;
extern int lastpipe_opt;
extern int inherit_errexit;
extern int localvar_inherit;
extern int localvar_unset;
#if defined (EXTENDED_GLOB)
extern int extended_glob;
@@ -214,6 +215,9 @@ static struct {
{ "lithist", &literal_history, (shopt_set_func_t *)NULL },
#endif
{ "localvar_inherit", &localvar_inherit, (shopt_set_func_t *)NULL },
#if 0
{ "localvar_unset", &localvar_unset, (shopt_set_func_t *)NULL },
#endif
{ "login_shell", &shopt_login_shell, set_login_shell },
{ "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
#if defined (READLINE)
+1 -1
View File
@@ -53,7 +53,7 @@ BASHINCDIR = ${topdir}/include
INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib
CCFLAGS = $(PROFILE_FLAGS) $(DEFS) $(LOCAL_DEFS) ${INCLUDES} $(CPPFLAGS) \
$(LOCAL_CFLAGS) $(CFLAGS) ${ASAN_CFLAGS}
$(LOCAL_CFLAGS) $(CFLAGS) ${ADDON_CFLAGS}
# Here is a rule for making .o files from .c files that doesn't force
# the type of the machine (like -sun3) into the flags.
+1 -1
View File
@@ -65,7 +65,7 @@ LOCAL_DEFS = @LOCAL_DEFS@
INCLUDES = -I. -I$(BUILD_DIR) -I$(topdir) -I$(topdir)/lib
CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(APP_CFLAGS) $(CPPFLAGS) ${INCLUDES} \
$(LOCAL_CFLAGS) $(CFLAGS) ${ASAN_CFLAGS}
$(LOCAL_CFLAGS) $(CFLAGS) ${ADDON_CFLAGS}
.c.o:
${RM} $@
+7 -2
View File
@@ -839,8 +839,13 @@ _rl_read_file (char *filename, size_t *sizep)
char *buffer;
int i, file;
if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0)
return ((char *)NULL);
file = -1;
if (((file = open (filename, O_RDONLY, 0666)) < 0) || (fstat (file, &finfo) < 0))
{
if (file >= 0)
close (file);
return ((char *)NULL);
}
file_size = (size_t)finfo.st_size;
+1 -1
View File
@@ -67,7 +67,7 @@ LOCAL_DEFS = @LOCAL_DEFS@
INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(BASHINCDIR) -I$(srcdir) $(INTL_INC)
CCFLAGS = ${ASAN_CFLAGS} ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) \
CCFLAGS = ${ADDON_CFLAGS} ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) \
$(LOCAL_CFLAGS) $(CFLAGS) $(CPPFLAGS)
GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
BUILD_DIR=/usr/local/build/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+44
View File
@@ -577,3 +577,47 @@ jkl
abc
def ghi
jkl
1. indexed:
reference:
./array25.sub: line 10: ${a[ ]}: bad substitution
./array25.sub: line 11: ' ': syntax error: operand expected (error token is "' '")
./array25.sub: line 12: ${a[ ]}: bad substitution
4. 0
5. 0
6. 0
assignment:
1.declare -a a=([0]="10" [1]="1")
2.declare -a a=([0]="11" [1]="1")
3.declare -a a=([0]="12" [1]="1")
4.declare -a a=([0]="13" [1]="1")
arithmetic:
1.declare -a a=([0]="0" [1]="1")
2.declare -a a=([0]="0" [1]="1")
3.declare -a a=([0]="0" [1]="1")
4.declare -a a=([0]="0" [1]="1")
5.declare -a a=([0]="0" [1]="1")
6.declare -a a=([0]="11" [1]="1")
7.declare -a a=([0]="0" [1]="1")
8.declare -a a=([0]="13" [1]="1")
2. associative:
reference:
./array25.sub: line 47: ${a[ ]}: bad substitution
2.
./array25.sub: line 49: ${a[ ]}: bad substitution
4.
5.
6.
assignment:
1.declare -A a=([" "]="10" [0]="0" [1]="1" )
2.declare -A a=([" "]="11" [0]="0" [1]="1" )
3.declare -A a=([" "]="12" [0]="0" [1]="1" )
4.declare -A a=([" "]="13" [0]="0" [1]="1" )
arithmetic:
1.declare -A a=([" "]="13" [0]="0" [1]="1" )
2.declare -A a=([" "]="13" [0]="0" [1]="1" )
3.declare -A a=([" "]="13" [0]="0" [1]="1" )
4.declare -A a=([" "]="13" [0]="0" [1]="1" )
5.declare -A a=([" "]="13" [0]="0" [1]="1" )
6.declare -A a=([" "]="13" [0]="0" [1]="1" ["\" \""]="11" )
7.declare -A a=([" "]="13" [0]="0" [1]="1" ["\" \""]="11" )
8.declare -A a=([" "]="13" [0]="0" [1]="1" ["\" \""]="13" )
+1
View File
@@ -400,3 +400,4 @@ ${THIS_SH} ./array21.sub
${THIS_SH} ./array22.sub
${THIS_SH} ./array23.sub
${THIS_SH} ./array24.sub
${THIS_SH} ./array25.sub
+70
View File
@@ -0,0 +1,70 @@
# tests with blank subscripts, indexed and associative
echo 1. indexed:
a[0]=0 a[1]=1
v=" "
echo reference:
echo 1. ${a[ ]}
echo 2. ${a[' ']}
echo 3. "${a[ ]}"
echo 4. ${a[$v]}
echo 5. ${a["$v"]}
echo 6. "${a[$v]}"
echo assignment:
echo -n 1. ; a[ ]=10 ; typeset -p a ; a[0]=0
echo -n 2. ; a[" "]=11 ; typeset -p a ; a[0]=0
echo -n 3. ; a[$v]=12 ; typeset -p a ; a[0]=0
echo -n 4. ; a["$v"]=13 ; typeset -p a ; a[0]=0
echo arithmetic:
echo -n 1. ; (( a[ ]=10 )); typeset -p a ; a[0]=0
echo -n 2. ; (( a[" "]=11 )); typeset -p a ; a[0]=0
echo -n 3. ; (( a[$v]=12 )); typeset -p a ; a[0]=0
echo -n 4. ; (( a["$v"]=13 )); typeset -p a ; a[0]=0
echo -n 5. ; let "a[ ]=10" ; typeset -p a ; a[0]=0
echo -n 6. ; let "a[\" \"]=11" ; typeset -p a ; a[0]=0
echo -n 7. ; let "a[$v]=12" ; typeset -p a ; a[0]=0
echo -n 8. ; let "a[\"$v\"]=13" ; typeset -p a ; a[0]=0
unset -v a v
echo 2. associative:
shopt -s assoc_expand_once
typeset -A a
a[0]=0 a[1]=1
v=" "
echo reference:
echo 1. ${a[ ]}
echo 2. ${a[' ']}
echo 3. "${a[ ]}"
echo 4. ${a[$v]}
echo 5. ${a["$v"]}
echo 6. "${a[$v]}"
echo assignment:
echo -n 1. ; a[ ]=10 ; typeset -p a ; a[0]=0
echo -n 2. ; a[" "]=11 ; typeset -p a ; a[0]=0
echo -n 3. ; a[$v]=12 ; typeset -p a ; a[0]=0
echo -n 4. ; a["$v"]=13 ; typeset -p a ; a[0]=0
echo arithmetic:
echo -n 1. ; (( a[ ]=10 )); typeset -p a ; a[0]=0
echo -n 2. ; (( a[" "]=11 )); typeset -p a ; a[0]=0
echo -n 3. ; (( a[$v]=12 )); typeset -p a ; a[0]=0
echo -n 4. ; (( a["$v"]=13 )); typeset -p a ; a[0]=0
echo -n 5. ; let "a[ ]=10" ; typeset -p a ; a[0]=0
echo -n 6. ; let "a[\" \"]=11" ; typeset -p a ; a[0]=0
echo -n 7. ; let "a[$v]=12" ; typeset -p a ; a[0]=0
echo -n 8. ; let "a[\"$v\"]=13" ; typeset -p a ; a[0]=0
+16 -4
View File
@@ -127,10 +127,22 @@ after 2: 1
after 3: 1
array after 1: 1
array after 2: 1
./errors6.sub: line 18: ${-3}: bad substitution
./errors6.sub: line 19: -3: invalid variable name
./errors6.sub: uvar: parameter not set
./errors6.sub: uvar: parameter null or not set
./errors6.sub: uvar: parameter null or not set
./errors6.sub: line 25: ${-3:-${-3}}: bad substitution
./errors6.sub: line 26: ${-3}: bad substitution
./errors6.sub: line 27: -3: invalid variable name
after indir: 1
./errors6.sub: line 18: ${-3}: bad substitution
./errors6.sub: line 19: -3: invalid variable name
./errors6.sub: line 30: -3: invalid variable name
./errors6.sub: uvar: parameter not set
./errors6.sub: uvar: parameter null or not set
./errors6.sub: uvar: parameter null or not set
./errors6.sub: line 25: ${-3:-${-3}}: bad substitution
./errors6.sub: line 26: ${-3}: bad substitution
./errors6.sub: line 27: -3: invalid variable name
after indir: 1
./errors6.sub: line 30: -3: invalid variable name
./errors.tests: line 278: `!!': not a valid identifier
+11
View File
@@ -15,6 +15,17 @@ echo array after 1: $?' 2>/dev/null
${THIS_SH} -c 'typeset -A v ; v["0"]=one ; echo ${v[ ]}
echo array after 2: $?' 2>/dev/null
${THIS_SH} -c 'echo ${uvar?}' ./errors6.sub
${THIS_SH} -c 'echo ${uvar:?}' ./errors6.sub
export uvar=
${THIS_SH} -c 'echo ${uvar?}' ./errors6.sub
${THIS_SH} -c 'echo ${uvar:?}' ./errors6.sub
unset uvar
echo "${-3:-${-3}}"
echo ${-3}
x=-3; echo ${!x}
echo after indir: $?
function ivar() { echo -n "${!1:-${1}}"; }
ivar -3
+16
View File
@@ -417,3 +417,19 @@ declare -a var=([123]="")
declare -n ref="var[123]"
./nameref18.sub: line 54: declare: var[123]: not found
declare -a var=([123]="X")
declare -n foo="bar"
declare -- foo="bar"
./nameref19.sub: line 9: declare: bar: not found
declare -n foo="bar"
declare -- foo="bar"
declare -i bar="11"
declare -inx foo6
declare -ix foo6
declare -n foo="bar"
declare -- bar="Hello World!"
declare -- foo="bar"
declare -- bar="Hello World!"
declare -n foo="bar"
declare -- bar
declare -- foo="bar"
declare -- bar
+51
View File
@@ -0,0 +1,51 @@
# can we unset the nameref attribute on variables with values that reference
# unset variables?
unset bar
declare -n foo="bar"
declare -p foo
declare +n foo
declare -p foo bar
declare -n foo
declare -p foo
# let's try removing the nameref attribute -- other attributes and assignments
# apply to the nameref target
declare +n -i foo=7+4
declare -p foo bar
unset foo bar
# but if the nameref variable doesn't have a value, the attributes apply to
# the nameref variable itself. thanks ksh93
declare -n foo6
declare -xi foo6
declare -p foo6
# and when we remove the nameref attribute, the other attributes remain
declare +n foo6
declare -p foo6
unset foo6
# make sure these cases continue to work
# nameref referencing an existing, set variable
declare -n foo=bar
bar='Hello World!'
declare -p foo bar
declare +n foo
declare -p foo bar
unset foo bar
# nameref referencing an existing, unset variable
declare -n foo=bar
declare bar
declare -p foo bar
declare +n foo
declare -p foo bar
+9
View File
@@ -119,6 +119,15 @@ declare -ar i4=([0]="a" [1]="b" [2]="c")
declare -ar j4=([0]="1" [1]="2" [2]="3")
./varenv9.sub: line 66: unset: i4: cannot unset: readonly variable
./varenv9.sub: line 66: unset: j4: cannot unset: readonly variable
main: unset
inner: res unset
outer: res: X Y
main: after first call: X
inner: X
outer: res: X Y
main: after second call: X
func: null or unset
after func: x = outside
a=z
a=b
a=z
+3
View File
@@ -225,5 +225,8 @@ ${THIS_SH} ./varenv8.sub
# if executed in shell functions, like they modify local scalar variables
${THIS_SH} ./varenv9.sub
# more tests of unset and local variables with dynamic scoping
${THIS_SH} ./varenv10.sub
# make sure variable scoping is done right
tt() { typeset a=b;echo a=$a; };a=z;echo a=$a;tt;echo a=$a
+47
View File
@@ -0,0 +1,47 @@
#!/bin/bash
#
# various tests of unset when applied to variables at different local scopes
# function unsetting variable at previous local scope, uncovering global
inner()
{
unset res
echo ${FUNCNAME}: ${res-res unset}
if [[ $1 == "set" ]]; then
res[0]="X"
res[1]="Y"
fi
}
outer()
{
local res=
inner "$1"
echo ${FUNCNAME}: "res: ${res[@]}"
}
echo main: ${res-unset}
outer set
echo main: after first call: ${res-unset}
outer dontset
echo main: after second call: ${res-unset}
unset -f outer inner
unset res
# local scope, unset variable at the same scope as local declaration
func()
{
typeset x=4
unset x
echo ${FUNCNAME}: ${x:-null or unset}
}
x=outside
func
echo after func: x = $x
unset -f func
unset x
+7 -1
View File
@@ -124,6 +124,11 @@ int variable_context = 0;
with the same name at a previous scope. */
int localvar_inherit = 0;
/* If non-zero, calling `unset' on local variables in previous scopes marks
them as invisible so lookups find them unset. This is the same behavior
as local variables in the current local scope. */
int localvar_unset = 0;
/* The set of shell assignments which are made only in the environment
for a single command. */
HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
@@ -3706,7 +3711,8 @@ makunbound (name, vc)
must be done so that if the variable is subsequently assigned a new
value inside the function, the `local' attribute is still present.
We also need to add it back into the correct hash table. */
if (old_var && local_p (old_var) && variable_context == old_var->context)
if (old_var && local_p (old_var) &&
(old_var->context == variable_context || (localvar_unset && old_var->context < variable_context)))
{
if (nofree_p (old_var))
var_setvalue (old_var, (char *)NULL);