revert change that suppressed array subscript expansion when called by the let builtin; fix default file descriptor for <> redirection when printing command

This commit is contained in:
Chet Ramey
2025-02-24 11:36:49 -05:00
parent c3ca11424d
commit e608233770
25 changed files with 1576 additions and 1640 deletions
+33
View File
@@ -10985,3 +10985,36 @@ braces.c
- brace_expand: call valid_seqterm if brace_gobbler finds a BRACE_SEQ
expansion
Inspired by report from Robert Elz <kre@munnari.oz.au>
2/13
----
doc/bash.1,doc/bashref.texi
- clarified the handling of double quotes in EXPRESSION in
(( EXPRESSION )) and $(( EXPRESSION )) to say that only unescaped
double quotes are removed
expr.c
- expr_bind_variable,expr_streval: revert change from 1/10 that
suppresses additional expansion when called by the `let' builtin,
tag for possible inclusion in a future release when I can look
at parallel changes to ((...)) and $((...)) (and probably
declare 'a[" "]=12' or similar)
2/14
----
lib/sh/zmapfd.c,externs.h
- zmapfd: now returns ssize_t in case of large files when size_t is
larger than int
builtins/evalfile.c,builtins/help.def
- zmapfd: changed callers
print_cmd.c
- print_redirection: the default file descriptor for <> is 0
Report and fix from Emanuele Torre <torreemanuele6@gmail.com>
2/18
----
configure.ac
- check for d_type member of struct dirent for future use
+2
View File
@@ -533,6 +533,7 @@ m4/timespec.m4 f
m4/bison.m4 f
m4/c-bool.m4 f
m4/codeset.m4 f
m4/d-type.m4 f
m4/extern-inline.m4 f
m4/fcntl-o.m4 f
m4/flexmember.m4 f
@@ -967,6 +968,7 @@ tests/arith6.sub f
tests/arith7.sub f
tests/arith8.sub f
tests/arith9.sub f
tests/arith10.sub f
tests/array.tests f
tests/array.right f
tests/array1.sub f
+16 -3
View File
@@ -245,7 +245,8 @@ show_longdoc (int i)
static void
show_desc (char *name, int i)
{
register int j, r;
int j;
ssize_t r;
char * const *doc, *line;
int fd, usefile;
@@ -258,8 +259,13 @@ show_desc (char *name, int i)
if (fd < 0)
return;
r = zmapfd (fd, &line, doc[0]);
if (r < 0)
{
builtin_error ("%s: %s: %s", doc[0], _("read error"), strerror (errno));
free (line);
line = (char *)NULL;
}
close (fd);
/* XXX - handle errors if zmapfd returns < 0 */
}
else
line = doc ? doc[0] : (char *)NULL;
@@ -281,6 +287,7 @@ static void
show_manpage (char *name, int i)
{
register int j;
ssize_t r;
char * const *doc;
char *line;
int fd, usefile;
@@ -293,7 +300,13 @@ show_manpage (char *name, int i)
fd = open_helpfile (doc[0]);
if (fd < 0)
return;
zmapfd (fd, &line, doc[0]);
r = zmapfd (fd, &line, doc[0]);
if (r < 0)
{
builtin_error ("%s: %s: %s", doc[0], _("read error"), strerror (errno));
free (line);
line = (char *)NULL;
}
close (fd);
}
else
+11
View File
@@ -298,6 +298,11 @@ history_builtin (WORD_LIST *list)
result = read_history (filename);
history_lines_in_file = history_lines_read_from_file;
/* history_lines_in_file = where_history () + history_base - 1; */
#if 0
/* Report read errors from the history library. */
if (result > 0)
builtin_error ("%s: %s: %s", filename, _("read error"), strerror (errno));
#endif
}
else if (flags & NFLAG) /* Read `new' history from file. */
{
@@ -312,6 +317,12 @@ history_builtin (WORD_LIST *list)
history_lines_in_file = history_lines_read_from_file;
/* history_lines_in_file = where_history () + history_base - 1; */
#if 0
/* Report read errors from the history library. */
if (result > 0)
builtin_error ("%s: %s: %s", filename, _("read error"), strerror (errno));
#endif
/* If we're rewriting the history file at shell exit rather than just
appending the lines from this session to it, the question is whether
we reset history_lines_this_session to 0, losing any history entries
+2
View File
@@ -434,6 +434,8 @@
#undef HAVE_STRUCT_DIRENT_D_NAMLEN
#undef HAVE_STRUCT_DIRENT_D_TYPE
#undef TIOCSTAT_IN_SYS_IOCTL
#undef FIONREAD_IN_SYS_IOCTL
Vendored
+58 -10
View File
@@ -1,5 +1,5 @@
#! /bin/sh
# From configure.ac for Bash 5.3, version 5.074.
# From configure.ac for Bash 5.3, version 5.075.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.72 for bash 5.3-beta.
#
@@ -6922,6 +6922,12 @@ fi
# d-type.m4
# serial 12
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
printf %s "checking for an ANSI C-conforming const... " >&6; }
@@ -9222,8 +9228,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
LIBS=$save_LIBS
test $gl_pthread_api = yes && break
done
echo "$as_me:9225: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9226: LIBPTHREAD=$LIBPTHREAD" >&5
echo "$as_me:9231: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9232: LIBPTHREAD=$LIBPTHREAD" >&5
gl_pthread_in_glibc=no
# On Linux with glibc >= 2.34, libc contains the fully functional
@@ -9249,7 +9255,7 @@ rm -rf conftest*
;;
esac
echo "$as_me:9252: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
echo "$as_me:9258: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
# Test for libpthread by looking for pthread_kill. (Not pthread_self,
# since it is defined as a macro on OSF/1.)
@@ -9427,7 +9433,7 @@ fi
fi
fi
echo "$as_me:9430: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
echo "$as_me:9436: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5
printf %s "checking whether POSIX threads API is available... " >&6; }
@@ -9674,8 +9680,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
LIBS=$save_LIBS
test $gl_pthread_api = yes && break
done
echo "$as_me:9677: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9678: LIBPTHREAD=$LIBPTHREAD" >&5
echo "$as_me:9683: gl_pthread_api=$gl_pthread_api" >&5
echo "$as_me:9684: LIBPTHREAD=$LIBPTHREAD" >&5
gl_pthread_in_glibc=no
# On Linux with glibc >= 2.34, libc contains the fully functional
@@ -9701,7 +9707,7 @@ rm -rf conftest*
;;
esac
echo "$as_me:9704: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
echo "$as_me:9710: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
# Test for libpthread by looking for pthread_kill. (Not pthread_self,
# since it is defined as a macro on OSF/1.)
@@ -9879,7 +9885,7 @@ fi
fi
fi
echo "$as_me:9882: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
echo "$as_me:9888: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5
printf %s "checking whether POSIX threads API is available... " >&6; }
@@ -16939,7 +16945,7 @@ INTL_DEP= INTL_INC= LIBINTL_H=
if test "x$USE_INCLUDED_LIBINTL" = "xyes"; then
INTL_DEP='${INTL_LIBDIR}/libintl.a'
INTL_INC='-I${INTL_LIBSRC} -I${INTL_BUILDDIR}'
LIBINTL_H='${INTL_LIBDIR}/libintl.h'
LIBINTL_H='${INTL_BUILDDIR}/libintl.h'
printf "%s\n" "#define HAVE_LOCALE_CHARSET 1" >>confdefs.h
@@ -20005,6 +20011,48 @@ printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_NAMLEN 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for d_type member in directory struct" >&5
printf %s "checking for d_type member in directory struct... " >&6; }
if test ${gl_cv_struct_dirent_d_type+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
#include <dirent.h>
int
main (void)
{
struct dirent dp; dp.d_type = 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
gl_cv_struct_dirent_d_type=yes
else case e in #(
e) gl_cv_struct_dirent_d_type=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_struct_dirent_d_type" >&5
printf "%s\n" "$gl_cv_struct_dirent_d_type" >&6; }
if test $gl_cv_struct_dirent_d_type = yes; then
printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_TYPE 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct winsize in sys/ioctl.h and termios.h" >&5
printf %s "checking for struct winsize in sys/ioctl.h and termios.h... " >&6; }
if test ${bash_cv_struct_winsize_header+y}
+3 -1
View File
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_REVISION([for Bash 5.3, version 5.074])dnl
AC_REVISION([for Bash 5.3, version 5.075])dnl
define(bashvers, 5.3)
define(relstatus, beta)
@@ -778,6 +778,7 @@ m4_include([m4/glibc21.m4])
m4_include([m4/host-cpu-c-abi.m4])
m4_include([m4/c-bool.m4])
m4_include([m4/d-type.m4])
dnl C compiler characteristics
AC_C_CONST
@@ -1079,6 +1080,7 @@ BASH_STRUCT_TERMIO_LDISC
BASH_STRUCT_DIRENT_D_INO
BASH_STRUCT_DIRENT_D_FILENO
BASH_STRUCT_DIRENT_D_NAMLEN
gl_CHECK_TYPE_STRUCT_DIRENT_D_TYPE
BASH_STRUCT_WINSIZE
BASH_STRUCT_TIMEVAL
AC_CHECK_MEMBERS([struct stat.st_blocks])
+46
View File
@@ -1,3 +1,49 @@
# Make sure the first target in the makefile is the right one
configure: configure.ac aclocal.m4 config.h.in
autoconf
configure: \
m4/bison.m4 \
m4/c-bool.m4 \
m4/codeset.m4 \
m4/d-type.m4 \
m4/extern-inline.m4 \
m4/fcntl-o.m4 \
m4/flexmember.m4 \
m4/gettext.m4 \
m4/glibc2.m4 \
m4/glibc21.m4 \
m4/host-cpu-c-abi.m4 \
m4/iconv.m4 \
m4/intdiv0.m4 \
m4/intl-thread-locale.m4 \
m4/intl.m4 \
m4/intlmacosx.m4 \
m4/intmax.m4 \
m4/inttypes-pri.m4 \
m4/inttypes.m4 \
m4/inttypes_h.m4 \
m4/lcmessage.m4 \
m4/lib-ld.m4 \
m4/lib-link.m4 \
m4/lib-prefix.m4 \
m4/locale_h.m4 \
m4/lock.m4 \
m4/nls.m4 \
m4/po.m4 \
m4/printf-posix.m4 \
m4/progtest.m4 \
m4/pthread_rwlock_rdlock.m4 \
m4/size_max.m4 \
m4/stat-time.m4 \
m4/stdint_h.m4 \
m4/strtoimax.m4 \
m4/threadlib.m4 \
m4/timespec.m4 \
m4/uintmax_t.m4 \
m4/ulonglong.m4 \
m4/unlocked-io.m4 \
m4/visibility.m4 \
m4/wchar_t.m4 \
m4/wint_t.m4 \
m4/xsize.m4
+13 -5
View File
@@ -771,7 +771,8 @@ otherwise the return status is 1.
The \fIexpression\fP
undergoes the same expansions
as if it were within double quotes,
but double quote characters in \fIexpression\fP are not treated
but unescaped double quote characters
in \fIexpression\fP are not treated
specially and are removed.
.TP
\fB[[\fP \fIexpression\fP \fB]]\fP
@@ -3410,7 +3411,7 @@ each generated term will contain the same number of digits,
zero-padding where necessary.
When letters are supplied, the expression expands to each character
lexicographically between \fIx\fP and \fIy\fP, inclusive,
using the default C locale.
using the C locale.
Note that both \fIx\fP and \fIy\fP must be of the same type
(integer or letter).
When the increment is supplied, it is used as the difference between
@@ -3689,9 +3690,15 @@ starting at the character specified by \fIoffset\fP.
If \fIparameter\fP is \fB@\fP or \fB*\fP, an indexed array subscripted by
\fB@\fP or \fB*\fP, or an associative array name, the results differ as
described below.
If \fIlength\fP is omitted, expands to the substring of the value of
If \fB:\fP\fIlength\fP is omitted (the first form above), this
expands to the substring of the value of
\fIparameter\fP starting at the character specified by \fIoffset\fP
and extending to the end of the value.
If \fIoffset\fP is omitted,
it is treated as 0.
If \fIlength\fP is omitted,
but the colon after \fIoffset\fP is present,
it is treated as 0.
\fIlength\fP and \fIoffset\fP are arithmetic expressions (see
.SM
.B
@@ -4164,8 +4171,9 @@ The
.I expression
undergoes the same expansions
as if it were within double quotes,
but double quote characters in \fIexpression\fP are not treated specially
and are removed.
but unescaped double quote characters
in \fIexpression\fP are not treated
specially and are removed.
All tokens in the expression undergo parameter and variable expansion,
command substitution, and quote removal.
The result is treated as the arithmetic expression to be evaluated.
+14 -6
View File
@@ -1161,8 +1161,9 @@ The arithmetic @var{expression} is evaluated according to the rules
described below (@pxref{Shell Arithmetic}).
The @var{expression} undergoes the same expansions
as if it were within double quotes,
but double quote characters in @var{expression} are not treated specially
and are removed.
but unescaped double quote characters
in @var{expression} are not treated
specially and are removed.
If the value of the expression is non-zero, the return status is 0;
otherwise the return status is 1.
@@ -2076,7 +2077,7 @@ each generated term will contain the same number of digits,
zero-padding where necessary.
When letters are supplied, the expression expands to each character
lexicographically between @var{x} and @var{y}, inclusive,
using the default C locale.
using the C locale.
Note that both @var{x} and @var{y} must be of the same type
(integer or letter).
When the increment is supplied, it is used as the difference between
@@ -2398,9 +2399,15 @@ starting at the character specified by @var{offset}.
If @var{parameter} is @samp{@@} or @samp{*}, an indexed array subscripted by
@samp{@@} or @samp{*}, or an associative array name, the results differ as
described below.
If @var{length} is omitted, it expands to the substring of the value of
If :@var{length} is omitted (the first form above), this
expands to the substring of the value of
@var{parameter} starting at the character specified by @var{offset}
and extending to the end of the value.
If @var{offset} is omitted,
it is treated as 0.
If @var{length} is omitted,
but the colon after @var{offset} is present,
it is treated as 0.
@var{length} and @var{offset} are arithmetic expressions
(@pxref{Shell Arithmetic}).
@@ -2922,8 +2929,9 @@ $(( @var{expression} ))
The @var{expression} undergoes the same expansions
as if it were within double quotes,
but double quote characters in @var{expression} are not treated specially
and are removed.
but unescaped double quote characters
in @var{expression} are not treated
specially and are removed.
All tokens in the expression undergo parameter and variable expansion,
command substitution, and quote removal.
The result is treated as the arithmetic expression to be evaluated.
+2
View File
@@ -1,5 +1,7 @@
/* fltexpr.c -- floating-point arithmetic expression evaluation. */
/* A thinly-edited version of expr.c/builtins/let.def */
/* Copyright (C) 2025 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
+4
View File
@@ -338,8 +338,10 @@ expr_bind_variable (const char *lhs, const char *rhs)
#if defined (ARRAY_VARS)
aflags = (array_expand_once && already_expanded) ? ASS_NOEXPAND : 0; /* XXX */
#if 0 /* TAG:bash-5.4 https://lists.gnu.org/archive/html/bug-bash/2024-12/msg00193.html */
if (this_shell_builtin == let_builtin && shell_compatibility_level > 51)
aflags |= ASS_NOEXPAND; /* we didn't quote subscripts */
#endif
aflags |= ASS_ALLOWALLSUB; /* allow assoc[@]=value */
#else
aflags = 0;
@@ -1167,8 +1169,10 @@ expr_streval (char *tok, int e, struct lvalue *lvalue)
#if defined (ARRAY_VARS)
tflag = (array_expand_once && already_expanded) ? AV_NOEXPAND : 0; /* for a start */
#if 0 /* TAG:bash-5.4 https://lists.gnu.org/archive/html/bug-bash/2024-12/msg00193.html */
if (this_shell_builtin == let_builtin && shell_compatibility_level > 51)
tflag |= AV_NOEXPAND; /* we didn't quote subscripts */
#endif
#endif
/* [[[[[ */
+1 -1
View File
@@ -550,7 +550,7 @@ extern int zcatfd (int, int, const char *);
extern ssize_t zgetline (int, char **, size_t *, int, int);
/* declarations for functions defined in lib/sh/zmapfd.c */
extern int zmapfd (int, char **, const char *);
extern ssize_t zmapfd (int, char **, const char *);
/* declarations for functions defined in lib/sh/zread.c */
extern ssize_t zread (int, char *, size_t);
+16 -13
View File
@@ -298,21 +298,24 @@ read_history_range (const char *filename, int from, int to)
#endif
goto error_and_exit;
}
file_size = (size_t)finfo.st_size;
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
else
{
errno = overflow_errno;
goto error_and_exit;
}
/* regular file */
file_size = (size_t)finfo.st_size;
if (file_size == 0)
{
xfree (input);
close (file);
return 0; /* don't waste time if we don't have to */
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
errno = overflow_errno;
goto error_and_exit;
}
if (file_size == 0)
{
xfree (input);
close (file);
return 0; /* don't waste time if we don't have to */
}
}
#ifdef HISTORY_USE_MMAP
+3 -8
View File
@@ -44,16 +44,14 @@ extern ssize_t zread (int, char *, size_t);
/* Dump contents of file descriptor FD to *OSTR. FN is the filename for
error messages (not used right now). */
int
ssize_t
zmapfd (int fd, char **ostr, const char *fn)
{
ssize_t nr;
int rval;
char lbuf[ZBUFSIZ];
char *result;
size_t rsize, rind;
rval = 0;
result = (char *)xmalloc (rsize = ZBUFSIZ);
rind = 0;
@@ -61,10 +59,7 @@ zmapfd (int fd, char **ostr, const char *fn)
{
nr = zread (fd, lbuf, sizeof (lbuf));
if (nr == 0)
{
rval = rind;
break;
}
break;
else if (nr < 0)
{
free (result);
@@ -86,5 +81,5 @@ zmapfd (int fd, char **ostr, const char *fn)
else
free (result);
return rval;
return (ssize_t)rind;
}
+32
View File
@@ -0,0 +1,32 @@
# d-type.m4
# serial 12
dnl Copyright (C) 1997, 1999-2004, 2006, 2009-2025 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl This file is offered as-is, without any warranty.
dnl From Jim Meyering.
dnl
dnl Check whether struct dirent has a member named d_type.
AC_DEFUN([gl_CHECK_TYPE_STRUCT_DIRENT_D_TYPE],
[AC_CACHE_CHECK([for d_type member in directory struct],
[gl_cv_struct_dirent_d_type],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <dirent.h>
]],
[[struct dirent dp; dp.d_type = 0;]])],
[gl_cv_struct_dirent_d_type=yes],
[gl_cv_struct_dirent_d_type=no])
]
)
if test $gl_cv_struct_dirent_d_type = yes; then
AC_DEFINE([HAVE_STRUCT_DIRENT_D_TYPE], [1],
[Define if there is a member named d_type in the struct describing
directory headers.])
fi
]
)
BIN
View File
Binary file not shown.
+1111 -1586
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1199,7 +1199,7 @@ print_redirection (REDIRECT *redirect)
case r_input_output:
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}", redir_word->word);
else if (redirector != 1)
else if (redirector != 0)
cprintf ("%d", redirector);
cprintf ("<> %s", redirectee->word);
break;
+79 -5
View File
@@ -281,15 +281,89 @@ after 4 0
+ set +x
./arith9.sub: line 37: 4+: arithmetic syntax error: operand expected (error token is "+")
x = 4+ y =
== arraysub ==
=== assoc_expand_once unset ===
declare -a a=([0]="10")
declare -a a=([0]="11")
declare -a a=([0]="12")
declare -a a=([0]="13")
declare -a a=([0]="14")
./arith10.sub: line 33: " ": arithmetic syntax error: operand expected (error token is "" "")
declare -a a=([0]="16")
declare -a a=([0]="17")
declare -a a=([0]="18")
./arith10.sub: line 38: "": arithmetic syntax error: operand expected (error token is """")
declare -a a=([0]="20")
declare -a a=([0]="21")
declare -a a=([0]="22")
declare -a a=([0]="23")
./arith10.sub: line 44: ((: `a[]': not a valid identifier
declare -a a=([0]="0")
./arith10.sub: line 45: `a[]': not a valid identifier
declare -a a=([0]="0")
declare -a a=([0]="26")
=== assoc_expand_once set ===
declare -a a=([0]="10")
declare -a a=([0]="11")
declare -a a=([0]="12")
declare -a a=([0]="13")
declare -a a=([0]="14")
./arith10.sub: line 33: " ": arithmetic syntax error: operand expected (error token is "" "")
declare -a a=([0]="16")
declare -a a=([0]="17")
./arith10.sub: line 36: " ": arithmetic syntax error: operand expected (error token is "" "")
./arith10.sub: line 38: "": arithmetic syntax error: operand expected (error token is """")
declare -a a=([0]="20")
declare -a a=([0]="21")
./arith10.sub: line 41: "": arithmetic syntax error: operand expected (error token is """")
declare -a a=([0]="23")
./arith10.sub: line 44: ((: `a[]': not a valid identifier
declare -a a=([0]="0")
./arith10.sub: line 45: `a[]': not a valid identifier
declare -a a=([0]="0")
./arith10.sub: line 46: "": arithmetic syntax error: operand expected (error token is """")
== substring ==
12
12
345
== cond ==
1
1
0
== arithsub ==
0
1 0
0
2 0
./arith10.sub: line 80: "" : arithmetic syntax error: operand expected (error token is """ ")
0
4 0
5 0
6 0
== arithcmd ==
1 1
2 1
3 1
./arith10.sub: line 89: ((: 1 - : arithmetic syntax error: operand expected (error token is "- ")
4 1
== letbltin ==
1 1
2 1
./arith10.sub: line 94: let: 0 - "": arithmetic syntax error: operand expected (error token is """")
3 1
./arith10.sub: line 95: let: 0 - "": arithmetic syntax error: operand expected (error token is """")
4 1
8 12
./arith.tests: line 332: ((: x=9 y=41 : arithmetic syntax error in expression (error token is "y=41 ")
./arith.tests: line 336: a b: arithmetic syntax error in expression (error token is "b")
./arith.tests: line 337: ((: a b: arithmetic syntax error in expression (error token is "b")
./arith.tests: line 335: ((: x=9 y=41 : arithmetic syntax error in expression (error token is "y=41 ")
./arith.tests: line 339: a b: arithmetic syntax error in expression (error token is "b")
./arith.tests: line 340: ((: a b: arithmetic syntax error in expression (error token is "b")
42
42
42
42
42
42
./arith.tests: line 352: 'foo' : arithmetic syntax error: operand expected (error token is "'foo' ")
./arith.tests: line 355: b[c]d: arithmetic syntax error in expression (error token is "d")
./arith.tests: line 355: 'foo' : arithmetic syntax error: operand expected (error token is "'foo' ")
./arith.tests: line 358: b[c]d: arithmetic syntax error in expression (error token is "d")
+3
View File
@@ -321,6 +321,9 @@ ${THIS_SH} ./arith8.sub
# expressions with unset variables and nounset enabled
${THIS_SH} ./arith9.sub
# empty expressions in various arithmetic evaluation contexts
${THIS_SH} ./arith10.sub
x=4
y=7
+95
View File
@@ -0,0 +1,95 @@
# Copyright 2025 The Free Software Foundation
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# let's see how various arithmetic contexts handle embedded double quotes and
# empty expressions
declare -a a
afunc()
{
a[0]=0
( a[" "]=10 ; declare -p a )
( (( a[" "]=11 )) ; declare -p a )
( : $(( a[" "]=12 )) ; declare -p a )
( let a\[" "\]=13 ; declare -p a )
( declare "a[\" \"]=14" ; declare -p a )
( a[\" \"]=15; declare -p a )
( (( a[\" \"]=16 )) ; declare -p a )
( : $(( a[\" \"]=17 )) ; declare -p a )
( let "a[\" \"]"=18 ; declare -p a )
( a[\"\"]=19 ; declare -p a )
( (( a[\"\"]=20 )) ; declare -p a )
( : $(( a[\"\"]=21 )) ; declare -p a )
( let "a[\"\"]"=22 ; declare -p a )
( a[""]=23 ; declare -p a )
( (( a[""]=24 )); declare -p a )
( : $(( a[""]=25 )); declare -p a )
( let 'a[""]=26' ; declare -p a )
}
echo == arraysub ==
shopt -u assoc_expand_once
echo === assoc_expand_once unset ===
afunc
unset a
declare -a a
shopt -s assoc_expand_once
echo === assoc_expand_once set ===
afunc
unset a
echo == substring ==
a=12345
echo ${a:0:2}
echo ${a::2}
echo ${a:2:0}
echo ${a:2:}
echo ${a:2}
echo == cond ==
[[ "" -gt 1 ]] ; echo $?
[[ 1 -le "" ]] ; echo $?
[[ 0 -eq "" ]] ; echo $?
echo == arithsub ==
echo $(( )) ; echo 1 $?
echo $(( "" )) ; echo 2 $?
echo $(( \"\" )) ; echo 3 $?
echo $(()) ; echo 4 $?
a=$(( )) ; echo 5 $?
a=$(( "" )) ; echo 6 $?
echo == arithcmd ==
(( )) ; echo 1 $?
(( "" )) ; echo 2 $?
(( " " )) ; echo 3 $?
(( 1 - "" )) ; echo 4 $?
echo == letbltin ==
let '' ; echo 1 $?
let ' ' ; echo 2 $?
let '0 - ""' ; echo 3 $?
let "0 - \"\"" ; echo 4 $?
+1 -1
View File
@@ -133,7 +133,7 @@ length = 3
value = new1 new2 new3
./array.tests: line 267: syntax error near unexpected token `&'
./array.tests: line 267: `badarray=( metacharacters like & need to be quoted in compound assignments)'
./array.tests: line 271: narray: unbound variable
./array.tests: line 271: narray[4]: unbound variable
./array1.sub: line 1: syntax error near unexpected token `('
./array1.sub: line 1: `printf "%s\n" -a a=(a 'b c')'
./array2.sub: line 1: declare: `[]=asdf': not a valid identifier
+11
View File
@@ -68,6 +68,17 @@ z x v t r p n l j h f d b
10 8 6 4 2 0
10 8 6 4 2 0
-50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0
{1..7} {1..8} {1..9} {2..7} {2..8} {2..9} {3..7} {3..8} {3..9}
{a..1} {a..2} {a..3} {b..1} {b..2} {b..3} {c..1} {c..2} {c..3}
{a..1} {a..10} {b..1} {b..10} {c..1} {c..10}
{a..1} {a..2} {a..3} {a..4} {c..1} {c..2} {c..3} {c..4}
{1..4} {2..4} {3..4}
{6..7} {6..8} {6..9}
{abcde.f}
X{..a}Z
0{1..}2
{a..1..5}
x{1..a}0 x{1..a}1 x{1..a}2 y{1..a}0 y{1..a}1 y{1..a}2
{1..10.f}
{1..ff}
{1..10..ff}
+19
View File
@@ -130,6 +130,25 @@ echo {10..0..2}
echo {10..0..-2}
echo {-50..-0..5}
# the outer sequence expression is invalid but the other brace expansions are ok
# fixed post-bash-5.2
echo {{1,2,3}..{7,8,9}}
echo {{a..c}..{1..3}}
echo {{a..c}..{1,10}}
echo {{a,c}..{1..4}}
echo {{1,2,3}..4}
echo {6..{7,8,9}}
# these are all invalid brace expansions
echo {abcde.f}
echo X{..a}Z
echo 0{1..}2
echo {a..1..5}
echo {x,y}{1..a}{0,1,2}
# bad
echo {1..10.f}
echo {1..ff}