commit bash-20200527 snapshot

This commit is contained in:
Chet Ramey
2020-05-29 14:29:34 -04:00
parent ce1a3c07c4
commit 37adc8b99d
23 changed files with 443 additions and 601 deletions
+49
View File
@@ -8407,3 +8407,52 @@ doc/{bash.1,bashref.texi}
- BASH_COMPAT: overhauled the text, refers to Shell Compatibility Mode
section
5/27
----
variables.c,/lib/sh/random.c
- moved functions that manage 16-bit and 32-bit random values to
lib/sh/random.c
alias.c
- add_alias: don't bother checking null alias values for ending in
space or tab
braces.c,include/typemax.h
- move sh_imaxabs and overflow and underflow detection to typemax.h
so the expression evaluation code can use it in the future
5/28
----
lib/readline/kill.c
- _rl_bracketed_read_mbstring: make sure to fill in mb[0] even if
the locale says MB_CUR_MAX == 1 in case a caller uses it. Partial
fix for bug reported by Phi Debian <phi.debian@gmail.com>
lib/readline/vi_mode.c
- _rl_vi_change_char: make sure _rl_vi_last_replacement gets filled in
in the case where MB_CUR_MAX == 1. Rest of fix for bug reported by
Phi Debian <phi.debian@gmail.com>
- rl_vi_change_char: same fix for _rl_vi_last_replacement
5/29
----
lib/malloc/malloc.c
- __P -> PARAMS
- union mhead: now 16 bytes to force 16-byte alignment; extra 8 bytes
at the end of struct minfo to use for guard bytes. Enabled if
pointers are 64 bits (SIZEOF_CHAR_P == 8)
- if we have 64-bit pointers, prepopulate the 64-byte bin first instead
of the 32-byte bin (pointers and WORD_DESCs still fit into 32 bytes,
but WORD_LISTs are now 36 bytes with malloc overhead). We can still
split 64-byte blocks to satisfy 32-byte requests
- internal_malloc: fill in the new 8 mh_magic8 bytes with MAGIC1 guard
bytes
- internal_malloc: print a warning message if the returned pointer is
not aligned according to MALIGN_MASK
- internal_free: detect underflow by checking that mh_magic8 is full
of MAGIC1 bytes
- internal_realloc: detect underflow by checking that mh_magic8 is full
of MAGIC1 bytes
lib/malloc/stats.c
- _print_malloc_stats: slight adjustment for better column alignment
+1
View File
@@ -420,6 +420,7 @@ lib/sh/netopen.c f
lib/sh/oslib.c f
lib/sh/pathcanon.c f
lib/sh/pathphys.c f
lib/sh/random.c f
lib/sh/rename.c f
lib/sh/setlinebuf.c f
lib/sh/shmatch.c f
+1 -1
View File
@@ -231,7 +231,7 @@ SHLIB_SOURCE = ${SH_LIBSRC}/clktck.c ${SH_LIBSRC}/getcwd.c \
${SH_LIBSRC}/input_avail.c ${SH_LIBSRC}/mbscasecmp.c \
${SH_LIBSRC}/fnxform.c ${SH_LIBSRC}/unicode.c \
${SH_LIBSRC}/wcswidth.c ${SH_LIBSRC}/wcsnwidth.c \
${SH_LIBSRC}/shmbchar.c ${SH_LIBSRC}/utf8.c
${SH_LIBSRC}/shmbchar.c ${SH_LIBSRC}/utf8.c ${SH_LIBSRC}/random.c
SHLIB_LIB = -lsh
SHLIB_LIBNAME = libsh.a
+12 -6
View File
@@ -127,9 +127,12 @@ add_alias (name, value)
free (temp->value);
temp->value = savestring (value);
temp->flags &= ~AL_EXPANDNEXT;
n = value[strlen (value) - 1];
if (n == ' ' || n == '\t')
temp->flags |= AL_EXPANDNEXT;
if (value[0])
{
n = value[strlen (value) - 1];
if (n == ' ' || n == '\t')
temp->flags |= AL_EXPANDNEXT;
}
}
else
{
@@ -138,9 +141,12 @@ add_alias (name, value)
temp->value = savestring (value);
temp->flags = 0;
n = value[strlen (value) - 1];
if (n == ' ' || n == '\t')
temp->flags |= AL_EXPANDNEXT;
if (value[0])
{
n = value[strlen (value) - 1];
if (n == ' ' || n == '\t')
temp->flags |= AL_EXPANDNEXT;
}
elt = hash_insert (savestring (name), aliases, HASH_NOSRCH);
elt->data = temp;
-19
View File
@@ -356,25 +356,6 @@ expand_amble (text, tlen, flags)
#define ST_CHAR 2
#define ST_ZINT 3
#ifndef sh_imaxabs
# define sh_imaxabs(x) (((x) >= 0) ? (x) : -(x))
#endif
/* Handle signed arithmetic overflow and underflow. Have to do it this way
to avoid compilers optimizing out simpler overflow checks. */
/* Make sure that a+b does not exceed MAXV or is smaller than MINV (if b < 0).
Assumes that b > 0 if a > 0 and b < 0 if a < 0 */
#define ADDOVERFLOW(a,b,minv,maxv) \
((((a) > 0) && ((b) > ((maxv) - (a)))) || \
(((a) < 0) && ((b) < ((minv) - (a)))))
/* Make sure that a-b is not smaller than MINV or exceeds MAXV (if b < 0).
Assumes that b > 0 if a > 0 and b < 0 if a < 0 */
#define SUBOVERFLOW(a,b,minv,maxv) \
((((b) > 0) && ((a) < ((minv) + (b)))) || \
(((b) < 0) && ((a) > ((maxv) + (b)))))
static char **
mkseq (start, end, incr, type, width)
intmax_t start, end, incr;
+3 -2
View File
@@ -5206,8 +5206,9 @@ start it, or using a substring that appears in its command line.
For example,
.B %ce
refers to a stopped
.B ce
job. If a prefix matches more than one job,
job whose command name begins with
.BR ce .
If a prefix matches more than one job,
.B bash
reports an error. Using
.BR %?ce ,
+2 -1
View File
@@ -8257,7 +8257,8 @@ previous job with a @samp{-}.
A job may also be referred to
using a prefix of the name used to start it, or using a substring
that appears in its command line. For example, @samp{%ce} refers
to a stopped @code{ce} job. Using @samp{%?ce}, on the
to a stopped job whose command name begins with @samp{ce}.
Using @samp{%?ce}, on the
other hand, refers to any job containing the string @samp{ce} in
its command line. If the prefix or substring matches more than one job,
Bash reports an error.
-158
View File
@@ -1,158 +0,0 @@
@node Shell Compatibility Mode
@section Shell Compatibility Mode
@cindex Compatibility Level
@cindex Compatibility Mode
Bash-4.0 introduced the concept of a `shell compatibility level', specified
as a set of options to the shopt builtin
(@code{compat31},
@code{compat32},
@code{compat40},
@code{compat41},
and so on).
There is only one current
compatibility level -- each option is mutually exclusive.
The compatibility level is intended to allow users to select behavior
from previous versions that is incompatible with newer versions
while they migrate scripts to use current features and
behavior. It's intended to be a temporary solution.
This section does not mention behavior that is standard for a particular
version (e.g., setting @code{compat32} means that quoting the rhs of the regexp
matching operator quotes special regexp characters in the word, which is
default behavior in bash-3.2 and above).
If a user enables, say, @code{compat32}, it may affect the behavior of other
compatibility levels up to and including the current compatibility level.
The idea is that each compatibility level controls behavior that changed
in that version of Bash, but that granularity may not be sufficient for
all uses, and as a result users should employ compatibility levels carefully.
Read the documentation for a particular feature to find out the
current behavior.
Bash-4.3 introduced a new shell variable: @env{BASH_COMPAT}.
The value assigned
to this variable (a decimal version number like 4.2, or an integer
corresponding to the @code{compat}@var{NN} option, like 42) determines the
compatibility level.
Starting with bash-4.4, Bash has begun deprecating older compatibility
levels.
Eventually, the options will be removed in favor of @env{BASH_COMPAT}.
Bash-5.0 is the final version for which there will be an individual shopt
option for the previous version. Users should use @env{BASH_COMPAT}
on bash-5.0 and later versions.
The following table describes the behavior changes controlled by each
compatibility level setting.
The @code{compat}@var{NN} tag is used as shorthand for setting the
compatibility level
to @var{NN} using one of the following mechanisms.
For versions prior to bash-5.0, the compatibility level may be set using
the corresponding @code{compat}@var{NN} shopt option.
For bash-4.3 and later versions, the @env{BASH_COMPAT} variable is preferred,
and it is required for bash-5.1 and later versions.
@table @code
@item compat31
@itemize @bullet
@item
quoting the rhs of the @code{[[} command's regexp matching operator (=~)
has no special effect
@end itemize
@item compat32
@itemize @bullet
@item
interrupting a command list such as "a ; b ; c" causes the execution
of the next command in the list (in bash-4.0 and later versions,
the shell acts as if it received the interrupt, so
interrupting one command in a list aborts the execution of the
entire list)
@end itemize
@item compat40
@itemize @bullet
@item
the @samp{<} and @samp{>} operators to the @code{[[} command do not
consider the current locale when comparing strings; they use ASCII
ordering.
Bash versions prior to bash-4.1 use ASCII collation and strcmp(3);
bash-4.1 and later use the current locale's collation sequence and
strcoll(3).
@end itemize
@item compat41
@itemize @bullet
@item
in posix mode, @code{time} may be followed by options and still be
recognized as a reserved word (this is @sc{posix} interpretation 267)
@item
in posix mode, the parser requires that an even number of single
quotes occur in the @var{word} portion of a double-quoted $@{@dots{}@}
parameter expansion and treats them specially, so that characters within
the single quotes are considered quoted
(this is @sc{posix} interpretation 221)
@end itemize
@item compat42
@itemize @bullet
@item
the replacement string in double-quoted pattern substitution is not
run through quote removal, as it is in versions after bash-4.2
@item
in posix mode, single quotes are considered special when expanding
the @var{word} portion of a double-quoted a $@{@dots{}@} parameter expansion
and can be used to quote a closing brace or other special character
(this is part of @sc{posix} interpretation 221);
in later versions, single quotes
are not special within double-quoted word expansions
@end itemize
@item compat43
@itemize @bullet
@item
the shell does not print a warning message if an attempt is made to
use a quoted compound assignment as an argument to declare
(declare -a foo='(1 2)'). Later versions warn that this usage is
deprecated
@item
word expansion errors are considered non-fatal errors that cause the
current command to fail, even in posix mode
(the default behavior is to make them fatal errors that cause the shell
to exit)
@item
when executing a shell function, the loop state (while/until/etc.)
is not reset, so @code{break} or @code{continue} in that function will break
or continue loops in the calling context. Bash-4.4 and later reset
the loop state to prevent this
@end itemize
@item compat44
@itemize @bullet
@item
the shell sets up the values used by @env{BASH_ARGV} and @env{BASH_ARGC}
so they can expand to the shell's positional parameters even if extended
debug mode is not enabled
@item
a subshell inherits loops from its parent context, so @code{break}
or @code{continue} will cause the subshell to exit.
Bash-5.0 and later reset the loop state to prevent the exit
@item
variable assignments preceding builtins like @code{export} and @code{readonly}
that set attributes continue to affect variables with the same
name in the calling environment even if the shell is not in posix
mode
@end itemize
@item compat50 (set using BASH_COMPAT)
@itemize @bullet
@item
Bash-5.1 changed the way @code{$RANDOM} is generated to introduce slightly
more randomness. If the shell compatibility level is set to 50 or
lower, it reverts to the method from bash-5.0 and previous versions,
so seeding the random number generator by assigning a value to
@env{RANDOM} wll produce the same sequence as in bash-5.0
@end itemize
@end table
-169
View File
@@ -1,169 +0,0 @@
.SH Shell Compatibility Mode
Bash-4.0 introduced the concept of a `shell compatibility level', specified
as a set of options to the shopt builtin
.BR compat31 ,
.BR compat32 ,
.BR compat40 ,
.BR compat41 ,
and so on).
There is only one current
compatibility level -- each option is mutually exclusive.
The compatibility level is intended to allow users to select behavior
from previous versions that is incompatible with newer versions
while they migrate scripts to use current features and
behavior. It's intended to be a temporary solution.
.PP
This section does not mention behavior that is standard for a particular
version (e.g., setting \fBcompat32\fP means that quoting the rhs of the regexp
matching operator quotes special regexp characters in the word, which is
default behavior in bash-3.2 and above).
.PP
If a user enables, say, \fBcompat32\fP, it may affect the behavior of other
compatibility levels up to and including the current compatibility level.
The idea is that each compatibility level controls behavior that changed
in that version of \fBbash\fP,
but that behavior may have been present in earlier versions.
For instance, the change to use locale-based comparisons with the \fB[[\fP
command came in bash-4.1, and earlier versions used ASCII-based comparisons,
so enabling \fBcompat32\fP will enable ASCII-based comparisons as well.
That granularity may not be sufficient for
all uses, and as a result users should employ compatibility levels carefully.
Read the documentation for a particular feature to find out the
current behavior.
.PP
Bash-4.3 introduced a new shell variable:
.SM
.BR BASH_COMPAT .
The value assigned
to this variable (a decimal version number like 4.2, or an integer
corresponding to the \fBcompat\fP\fINN\fP option, like 42) determines the
compatibility level.
.PP
Starting with bash-4.4, Bash has begun deprecating older compatibility
levels.
Eventually, the options will be removed in favor of
.SM
.BR BASH_COMPAT .
.PP
Bash-5.0 is the final version for which there will be an individual shopt
option for the previous version. Users should use
.SM
.B BASH_COMPAT
on bash-5.0 and later versions.
.PP
The following table describes the behavior changes controlled by each
compatibility level setting.
The \fBcompat\fP\fINN\fP tag is used as shorthand for setting the
compatibility level
to \fINN\fP using one of the following mechanisms.
For versions prior to bash-5.0, the compatibility level may be set using
the corresponding \fBcompat\fP\fINN\fP shopt option.
For bash-4.3 and later versions, the
.SM
.B BASH_COMPAT
variable is preferred,
and it is required for bash-5.1 and later versions.
.PP
.TP
\fBcompat31\fP
.IP \(bu
quoting the rhs of the \fB[[\fP command's regexp matching operator (=~)
has no special effect
.TP
\fBcompat32\fP
.IP \(bu
interrupting a command list such as "a ; b ; c" causes the execution
of the next command in the list (in bash-4.0 and later versions,
the shell acts as if it received the interrupt, so
interrupting one command in a list aborts the execution of the
entire list)
.TP
\fBcompat40\fP
.IP \(bu
the \fB<\fP and \fB>\fP operators to the \fB[[\fP command do not
consider the current locale when comparing strings; they use ASCII
ordering.
Bash versions prior to bash-4.1 use ASCII collation and
.IR strcmp (3);
bash-4.1 and later use the current locale's collation sequence and
.IR strcoll (3).
.TP
\fBcompat41\fP
.IP \(bu
in \fIposix\fP mode, \fBtime\fP may be followed by options and still be
recognized as a reserved word (this is POSIX interpretation 267)
.IP \(bu
in \fIposix\fP mode, the parser requires that an even number of single
quotes occur in the \fIword\fP portion of a double-quoted
parameter expansion and treats them specially, so that characters within
the single quotes are considered quoted
(this is POSIX interpretation 221)
.TP
\fBcompat42\fP
.IP \(bu
the replacement string in double-quoted pattern substitution does not
undergo quote removal, as it does in versions after bash-4.2
.IP \(bu
in posix mode, single quotes are considered special when expanding
the \fIword\fP portion of a double-quoted parameter expansion
and can be used to quote a closing brace or other special character
(this is part of POSIX interpretation 221);
in later versions, single quotes
are not special within double-quoted word expansions
.TP
\fBcompat43\fP
the shell does not print a warning message if an attempt is made to
use a quoted compound assignment as an argument to declare
(declare -a foo='(1 2)'). Later versions warn that this usage is
deprecated
.IP \(bu
word expansion errors are considered non-fatal errors that cause the
current command to fail, even in posix mode
(the default behavior is to make them fatal errors that cause the shell
to exit)
.IP \(bu
when executing a shell function, the loop state (while/until/etc.)
is not reset, so \fBbreak\fP or \fBcontinue\fP in that function will break
or continue loops in the calling context. Bash-4.4 and later reset
the loop state to prevent this
.TP
\fBcompat44\fP
.IP \(bu
the shell sets up the values used by
.SM
.B BASH_ARGV
and
.SM
.B BASH_ARGC
so they can expand to the shell's positional parameters even if extended
debug mode is not enabled
.IP \(bu
a subshell inherits loops from its parent context, so \fBbreak\fP
or \fBcontinue\fP will cause the subshell to exit.
Bash-5.0 and later reset the loop state to prevent the exit
.IP \(bu
variable assignments preceding builtins like \fBexport\fP and \fBreadonly\fP
that set attributes continue to affect variables with the same
name in the calling environment even if the shell is not in posix
mode
.TP
\fBcompat50\fP
.IP \(bu
Bash-5.1 changed the way
.SM
.B $RANDOM
is generated to introduce slightly
more randomness. If the shell compatibility level is set to 50 or
lower, it reverts to the method from bash-5.0 and previous versions,
so seeding the random number generator by assigning a value to
.SM
.B RANDOM
will produce the same sequence as in bash-5.0
+1
View File
@@ -549,6 +549,7 @@ expassign ()
switch (op)
{
case MUL:
/* Handle INTMAX_MIN and INTMAX_MAX * -1 specially here? */
lvalue *= value;
break;
case DIV:
+8 -1
View File
@@ -1,7 +1,7 @@
/* externs.h -- extern function declarations which do not appear in their
own header file. */
/* Copyright (C) 1993-2010 Free Software Foundation, Inc.
/* Copyright (C) 1993-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -308,6 +308,13 @@ extern char *sh_canonpath PARAMS((char *, int));
extern char *sh_physpath PARAMS((char *, int));
extern char *sh_realpath PARAMS((const char *, char *));
/* declarations for functions defined in lib/sh/random.c */
extern int brand PARAMS((void));
extern void sbrand PARAMS((unsigned long)); /* set bash random number generator. */
extern void seedrand PARAMS((void)); /* seed generator randomly */
extern void seedrand32 PARAMS((void));
extern u_bits32_t get_urandom32 PARAMS((void));
/* declarations for functions defined in lib/sh/setlinebuf.c */
#ifdef NEED_SH_SETLINEBUF_DECL
extern int sh_setlinebuf PARAMS((FILE *));
+19
View File
@@ -109,4 +109,23 @@ static const unsigned long long int maxquad = ULLONG_MAX;
# define SIZE_MAX 65535 /* POSIX minimum max */
#endif
#ifndef sh_imaxabs
# define sh_imaxabs(x) (((x) >= 0) ? (x) : -(x))
#endif
/* Handle signed arithmetic overflow and underflow. Have to do it this way
to avoid compilers optimizing out simpler overflow checks. */
/* Make sure that a+b does not exceed MAXV or is smaller than MINV (if b < 0).
Assumes that b > 0 if a > 0 and b < 0 if a < 0 */
#define ADDOVERFLOW(a,b,minv,maxv) \
((((a) > 0) && ((b) > ((maxv) - (a)))) || \
(((a) < 0) && ((b) < ((minv) - (a)))))
/* Make sure that a-b is not smaller than MINV or exceeds MAXV (if b < 0).
Assumes that b > 0 if a > 0 and b < 0 if a < 0 */
#define SUBOVERFLOW(a,b,minv,maxv) \
((((b) > 0) && ((a) < ((minv) + (b)))) || \
(((b) < 0) && ((a) > ((maxv) + (b)))))
#endif /* _SH_TYPEMAX_H */
+75 -20
View File
@@ -1,6 +1,6 @@
/* malloc.c - dynamic memory allocation for bash. */
/* Copyright (C) 1985-2005 Free Software Foundation, Inc.
/* Copyright (C) 1985-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne-Again SHell.
@@ -25,6 +25,8 @@
*
* Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
*
* [VERY] old explanation:
*
* This is a very fast storage allocator. It allocates blocks of a small
* number of different sizes, and keeps free lists of each size. Blocks
* that don't exactly fit are passed up to the next larger size. In this
@@ -138,22 +140,35 @@
enough room in the block for the new size. Range checking is always
done. */
union mhead {
#if SIZEOF_CHAR_P == 8
bits64_t mh_align[2]; /* 16 */
#else
bits64_t mh_align; /* 8 */
#endif
struct {
char mi_alloc; /* ISALLOC or ISFREE */ /* 1 */
char mi_index; /* index in nextf[] */ /* 1 */
/* Remainder are valid only when block is allocated */
u_bits16_t mi_magic2; /* should be == MAGIC2 */ /* 2 */
u_bits32_t mi_nbytes; /* # of bytes allocated */ /* 4 */
#if SIZEOF_CHAR_P == 8
char mi_magic8[8]; /* MAGIC1 guard bytes */ /* 8 */
#endif
} minfo;
};
#define mh_alloc minfo.mi_alloc
#define mh_index minfo.mi_index
#define mh_nbytes minfo.mi_nbytes
#define mh_magic2 minfo.mi_magic2
#define mh_magic8 minfo.mi_magic8
#define MOVERHEAD sizeof(union mhead)
#if SIZEOF_CHAR_P == 8
#define MALIGN_MASK 15
#else
#define MALIGN_MASK 7 /* one less than desired alignment */
#endif
typedef union _malloc_guard {
char s[4];
@@ -167,6 +182,8 @@ typedef union _malloc_guard {
to describe the overhead for when the block is in use,
and we do not want the free-list pointer to count in that. */
/* If SIZEOF_CHAR_P == 8, this goes into the mh_magic8 buffer at the end of
the rest of the struct. This may need adjusting. */
#define CHAIN(a) \
(*(union mhead **) (sizeof (char *) + (char *) (a)))
@@ -174,13 +191,14 @@ typedef union _malloc_guard {
and end of each allocated block, and make sure they are undisturbed
whenever a free or a realloc occurs. */
/* Written in the 2 bytes before the block's real space (-4 bytes) */
/* Written in the bytes before the block's real space (-SIZEOF_CHAR_P bytes) */
#define MAGIC1 0x55
#define MAGIC2 0x5555
#define MSLOP 4 /* 4 bytes extra for u_bits32_t size */
/* How many bytes are actually allocated for a request of size N --
rounded up to nearest multiple of 8 after accounting for malloc
overhead. */
rounded up to nearest multiple of 2*SIZEOF_CHAR_P after accounting for
malloc overhead. */
#define ALLOCATED_BYTES(n) \
(((n) + MOVERHEAD + MSLOP + MALIGN_MASK) & ~MALIGN_MASK)
@@ -277,24 +295,24 @@ extern int errno;
#endif
/* Declarations for internal functions */
static PTR_T internal_malloc __P((size_t, const char *, int, int));
static PTR_T internal_realloc __P((PTR_T, size_t, const char *, int, int));
static void internal_free __P((PTR_T, const char *, int, int));
static PTR_T internal_memalign __P((size_t, size_t, const char *, int, int));
static PTR_T internal_malloc PARAMS((size_t, const char *, int, int));
static PTR_T internal_realloc PARAMS((PTR_T, size_t, const char *, int, int));
static void internal_free PARAMS((PTR_T, const char *, int, int));
static PTR_T internal_memalign PARAMS((size_t, size_t, const char *, int, int));
#ifndef NO_CALLOC
static PTR_T internal_calloc __P((size_t, size_t, const char *, int, int));
static void internal_cfree __P((PTR_T, const char *, int, int));
static PTR_T internal_calloc PARAMS((size_t, size_t, const char *, int, int));
static void internal_cfree PARAMS((PTR_T, const char *, int, int));
#endif
#ifndef NO_VALLOC
static PTR_T internal_valloc __P((size_t, const char *, int, int));
static PTR_T internal_valloc PARAMS((size_t, const char *, int, int));
#endif
#if defined (botch)
extern void botch ();
#else
static void botch __P((const char *, const char *, int));
static void botch PARAMS((const char *, const char *, int));
#endif
static void xbotch __P((PTR_T, int, const char *, const char *, int));
static void xbotch PARAMS((PTR_T, int, const char *, const char *, int));
#if !HAVE_DECL_SBRK
extern char *sbrk ();
@@ -302,7 +320,7 @@ extern char *sbrk ();
#ifdef SHELL
extern int interrupt_immediately, running_trap;
extern int signal_is_trapped __P((int));
extern int signal_is_trapped PARAMS((int));
#endif
#ifdef MALLOC_STATS
@@ -321,8 +339,8 @@ int malloc_mmap_threshold = MMAP_THRESHOLD;
char _malloc_trace_buckets[NBUCKETS];
/* These should really go into a header file. */
extern void mtrace_alloc __P((const char *, PTR_T, size_t, const char *, int));
extern void mtrace_free __P((PTR_T, int, const char *, int));
extern void mtrace_alloc PARAMS((const char *, PTR_T, size_t, const char *, int));
extern void mtrace_free PARAMS((PTR_T, int, const char *, int));
#endif
#if !defined (botch)
@@ -693,7 +711,7 @@ morecore (nu)
memtop += sbrk_amt;
/* shouldn't happen, but just in case -- require 8-byte alignment */
/* shouldn't happen, but just in case -- require 8- or 16-byte alignment */
if ((long)mp & MALIGN_MASK)
{
mp = (union mhead *) (((long)mp + MALIGN_MASK) & ~MALIGN_MASK);
@@ -723,8 +741,13 @@ malloc_debug_dummy ()
write (1, "malloc_debug_dummy\n", 19);
}
#if SIZEOF_CHAR_P == 8
#define PREPOP_BIN 3
#define PREPOP_SIZE 64
#else
#define PREPOP_BIN 2
#define PREPOP_SIZE 32
#endif
static int
pagealign ()
@@ -760,8 +783,8 @@ pagealign ()
memtop += sbrk_needed;
/* Take the memory which would otherwise be wasted and populate the most
popular bin (2 == 32 bytes) with it. Add whatever we need to curbrk
to make things 32-byte aligned, compute how many 32-byte chunks we're
popular bin (3 == 64 bytes) with it. Add whatever we need to curbrk
to make things 64-byte aligned, compute how many 64-byte chunks we're
going to get, and set up the bin. */
curbrk += sbrk_needed & (PREPOP_SIZE - 1);
sbrk_needed -= sbrk_needed & (PREPOP_SIZE - 1);
@@ -822,7 +845,7 @@ internal_malloc (n, file, line, flags) /* get a block */
if (nbytes <= binsize(nunits))
break;
/* Silently reject too-large requests. */
/* Silently reject too-large requests. XXX - can increase this if HAVE_MMAP */
if (nunits >= NBUCKETS)
return ((PTR_T) NULL);
@@ -863,6 +886,11 @@ internal_malloc (n, file, line, flags) /* get a block */
p->mh_magic2 = MAGIC2;
p->mh_nbytes = n;
#if SIZEOF_CHAR_P == 8
/* Begin guard */
MALLOC_MEMSET ((char *)p->mh_magic8, MAGIC1, 8);
#endif
/* End guard */
mg.i = n;
z = mg.s;
@@ -897,6 +925,14 @@ internal_malloc (n, file, line, flags) /* get a block */
_malloc_ckwatch (p + 1, file, line, W_ALLOC, n);
#endif
#if defined (MALLOC_DEBUG)
z = (char *) (p + 1);
/* Check alignment of returned pointer */
if ((unsigned long)z & MALIGN_MASK)
fprintf (stderr, "malloc: %s:%d: warning: request for %ld bytes not aligned on %d byte boundary\r\n",
file ? file : _("unknown"), line, p->mh_nbytes, MALIGN_MASK+1);
#endif
return (PTR_T) (p + 1);
}
@@ -956,6 +992,15 @@ internal_free (mem, file, line, flags)
if (IN_BUCKET(nbytes, nunits) == 0)
xbotch (mem, ERR_UNDERFLOW,
_("free: underflow detected; mh_nbytes out of range"), file, line);
#if SIZEOF_CHAR_P == 8
{
int i;
for (i = 0, z = p->mh_magic8; i < 8; i++)
if (*z++ != MAGIC1)
xbotch (mem, ERR_UNDERFLOW,
_("free: underflow detected; magic8 corrupted"), file, line);
}
#endif
ap += p->mh_nbytes;
z = mg.s;
@@ -1087,6 +1132,16 @@ internal_realloc (mem, n, file, line, flags)
if (IN_BUCKET(nbytes, nunits) == 0)
xbotch (mem, ERR_UNDERFLOW,
_("realloc: underflow detected; mh_nbytes out of range"), file, line);
#if SIZEOF_CHAR_P == 8
{
int i;
for (i = 0, z = p->mh_magic8; i < 8; i++)
if (*z++ != MAGIC1)
xbotch (mem, ERR_UNDERFLOW,
_("realloc: underflow detected; magic8 corrupted"), file, line);
}
#endif
m = (char *)mem + (tocopy = p->mh_nbytes);
z = mg.s;
+1 -1
View File
@@ -110,7 +110,7 @@ _print_malloc_stats (s, fp)
if (i == malloc_mmap_threshold+1)
fprintf (fp, "--------\n");
if (v.nmal > 0)
fprintf (fp, "%8lu\t%4d\t%6d\t%5d\t%8d\t%8d %5d %8d\n", (unsigned long)v.blocksize, v.nfree, v.nused, v.nmal, v.nmorecore, v.nlesscore, v.nsplit, v.ncoalesce);
fprintf (fp, "%8lu\t%4d\t%6d\t%5d%8d\t%8d %5d %8d\n", (unsigned long)v.blocksize, v.nfree, v.nused, v.nmal, v.nmorecore, v.nlesscore, v.nsplit, v.ncoalesce);
totfree += v.nfree * v.blocksize;
totused += v.nused * v.blocksize;
}
+3
View File
@@ -820,7 +820,10 @@ _rl_bracketed_read_mbstring (char *mb, int mlen)
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = _rl_read_mbstring (c, mb, mlen);
else
#endif
mb[0] = c;
mb[mlen] = '\0'; /* just in case */
return c;
}
+8 -6
View File
@@ -2014,10 +2014,11 @@ _rl_vi_callback_change_char (_rl_callback_generic_arg *data)
c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
#if defined (HANDLE_MULTIBYTE)
strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
#else
_rl_vi_last_replacement[0] = c;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
else
#endif
_rl_vi_last_replacement[0] = c;
_rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* XXX */
if (c < 0)
@@ -2054,10 +2055,11 @@ rl_vi_change_char (int count, int key)
{
c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
#ifdef HANDLE_MULTIBYTE
strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
#else
_rl_vi_last_replacement[0] = c;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
else
#endif
_rl_vi_last_replacement[0] = c;
_rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* just in case */
}
+9 -3
View File
@@ -2,7 +2,7 @@
# Makefile for the Bash library
#
#
# Copyright (C) 1998-2010 Free Software Foundation, Inc.
# Copyright (C) 1998-2020 Free Software Foundation, Inc.
# 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
@@ -93,7 +93,7 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \
wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \
casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c \
strchrnul.c unicode.c wcswidth.c wcsnwidth.c shmbchar.c strdup.c \
utf8.c
utf8.c random.c
# The header files for this library.
HSOURCES =
@@ -108,7 +108,7 @@ OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \
fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \
fpurge.o zgetline.o mbscmp.o uconvert.o ufuncs.o casemod.o \
input_avail.o mbscasecmp.o fnxform.o unicode.o shmbchar.o \
utf8.o wcsnwidth.o ${LIBOBJS}
utf8.o random.o wcsnwidth.o ${LIBOBJS}
SUPPORT = Makefile
@@ -170,6 +170,7 @@ netopen.o: netopen.c
oslib.o: oslib.c
pathcanon.o: pathcanon.c
pathphys.o: pathphys.c
random.o: random.c
rename.o: rename.c
setlinebuf.o: setlinebuf.c
shmatch.o: shmatch.c
@@ -248,6 +249,7 @@ netopen.o: ${BUILD_DIR}/config.h
oslib.o: ${BUILD_DIR}/config.h
pathcanon.o: ${BUILD_DIR}/config.h
pathphys.o: ${BUILD_DIR}/config.h
random.o: ${BUILD_DIR}/config.h
rename.o: ${BUILD_DIR}/config.h
setlinebuf.o: ${BUILD_DIR}/config.h
shmatch.o: ${BUILD_DIR}/config.h
@@ -380,6 +382,10 @@ pathphys.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
pathphys.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
#pathphys.o: ${BUILD_DIR}/version.h
random.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h
random.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
random.o: ${BASHINCDIR}/filecntl.h
rename.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h
rename.o: ${BASHINCDIR}/posixstat.h
+240
View File
@@ -0,0 +1,240 @@
/* random.c -- Functions for managing 16-bit and 32-bit random numbers. */
/* Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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.
Bash 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 Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "bashtypes.h"
#if defined (HAVE_SYS_RANDOM_H)
# include <sys/random.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "filecntl.h"
#include <stdio.h>
#include "bashansi.h"
#include "shell.h"
extern time_t shell_start_time;
extern int last_random_value;
static u_bits32_t intrand32 PARAMS((u_bits32_t));
static u_bits32_t genseed PARAMS((void));
static u_bits32_t brand32 PARAMS((void));
static void sbrand32 PARAMS((u_bits32_t));
static void perturb_rand32 PARAMS((void));
/* The random number seed. You can change this by setting RANDOM. */
static u_bits32_t rseed = 1;
/* Returns a 32-bit pseudo-random number. */
static u_bits32_t
intrand32 (last)
u_bits32_t last;
{
/* Minimal Standard generator from
"Random number generators: good ones are hard to find",
Park and Miller, Communications of the ACM, vol. 31, no. 10,
October 1988, p. 1195. Filtered through FreeBSD.
x(n+1) = 16807 * x(n) mod (m).
We split up the calculations to avoid overflow.
h = last / q; l = x - h * q; t = a * l - h * r
m = 2147483647, a = 16807, q = 127773, r = 2836
There are lots of other combinations of constants to use; look at
https://www.gnu.org/software/gsl/manual/html_node/Other-random-number-generators.html#Other-random-number-generators */
bits32_t h, l, t;
u_bits32_t ret;
/* Can't seed with 0. */
ret = (last == 0) ? 123459876 : last;
h = ret / 127773;
l = ret - (127773 * h);
t = 16807 * l - 2836 * h;
ret = (t < 0) ? t + 0x7fffffff : t;
return (ret);
}
static u_bits32_t
genseed ()
{
struct timeval tv;
u_bits32_t iv;
gettimeofday (&tv, NULL);
iv = (u_bits32_t)seedrand; /* let the compiler truncate */
iv = tv.tv_sec ^ tv.tv_usec ^ getpid () ^ getppid () ^ current_user.uid ^ iv;
return (iv);
}
#define BASH_RAND_MAX 32767 /* 0x7fff - 16 bits */
/* Returns a pseudo-random number between 0 and 32767. */
int
brand ()
{
unsigned int ret;
rseed = intrand32 (rseed);
if (shell_compatibility_level > 50)
ret = (rseed >> 16) ^ (rseed & 65535);
else
ret = rseed;
return (ret & BASH_RAND_MAX);
}
/* Set the random number generator seed to SEED. */
void
sbrand (seed)
unsigned long seed;
{
rseed = seed;
last_random_value = 0;
}
void
seedrand ()
{
u_bits32_t iv;
iv = genseed ();
sbrand (iv);
}
static u_bits32_t rseed32 = 1073741823;
static int last_rand32;
static int urandfd = -1;
#define BASH_RAND32_MAX 0x7fffffff /* 32 bits */
/* Returns a 32-bit pseudo-random number between 0 and 4294967295. */
static u_bits32_t
brand32 ()
{
u_bits32_t ret;
rseed32 = intrand32 (rseed32);
return (rseed32 & BASH_RAND32_MAX);
}
static void
sbrand32 (seed)
u_bits32_t seed;
{
last_rand32 = rseed32 = seed;
}
void
seedrand32 ()
{
u_bits32_t iv;
iv = genseed ();
sbrand32 (iv);
}
static void
perturb_rand32 ()
{
rseed32 ^= genseed ();
}
/* Force another attempt to open /dev/urandom on the next call to get_urandom32 */
void
urandom_close ()
{
if (urandfd >= 0)
close (urandfd);
urandfd = -1;
}
#if !defined (HAVE_GETRANDOM)
/* Imperfect emulation of getrandom(2). */
#ifndef GRND_NONBLOCK
# define GRND_NONBLOCK 1
# define GRND_RANDOM 2
#endif
static ssize_t
getrandom (buf, len, flags)
void *buf;
size_t len;
unsigned int flags;
{
int oflags;
ssize_t r;
static int urand_unavail = 0;
#if HAVE_GETENTROPY
r = getentropy (buf, len);
return (r == 0) ? len : -1;
#endif
if (urandfd == -1 && urand_unavail == 0)
{
oflags = O_RDONLY;
if (flags & GRND_NONBLOCK)
oflags |= O_NONBLOCK;
urandfd = open ("/dev/urandom", oflags, 0);
if (urandfd >= 0)
SET_CLOSE_ON_EXEC (urandfd);
else
{
urand_unavail = 1;
return -1;
}
}
if (urandfd >= 0 && (r = read (urandfd, buf, len)) == len)
return (r);
return -1;
}
#endif
u_bits32_t
get_urandom32 ()
{
u_bits32_t ret;
if (getrandom ((void *)&ret, sizeof (ret), GRND_NONBLOCK) == sizeof (ret))
return (last_rand32 = ret);
#if defined (HAVE_ARC4RANDOM)
ret = arc4random ();
#else
if (subshell_environment)
perturb_rand32 ();
do
ret = brand32 ();
while (ret == last_rand32);
#endif
return (last_rand32 = ret);
}
+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
+3
View File
@@ -11,6 +11,9 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# a lot of this is technically undefined behavior due to signed 64-bit
# integer overflow, but we're testing exception handling here
intmax_max=$((2**63 - 1))
intmax_min1=$((2**63))
intmax_min2=$((-2**63))
+2 -2
View File
@@ -140,9 +140,9 @@ three
one
two
three
5.0
5.1
echo ${BASH_VERSION%\.*}
5.0
5.1
echo ${BASH_VERSION%\.*}
a
b
+1 -1
View File
@@ -624,7 +624,7 @@ c Sub = 0 2 4 8
<'ab cd'>
<'4'> <'ab cd'>
<>
argv[1] = <host(2)[5.0]$ >
argv[1] = <host(2)[5.1]$ >
<
>
<' \t\n'>
+4 -210
View File
@@ -32,10 +32,6 @@
# endif /* !__QNXNTO__ */
#endif /* __QNX__ */
#if defined (HAVE_SYS_RANDOM_H)
# include <sys/random.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
@@ -206,19 +202,6 @@ static SHELL_VAR *assign_seconds PARAMS((SHELL_VAR *, char *, arrayind_t, char *
static SHELL_VAR *get_seconds PARAMS((SHELL_VAR *));
static SHELL_VAR *init_seconds_var PARAMS((void));
static u_bits32_t intrand32 PARAMS((u_bits32_t));
static u_bits32_t genseed PARAMS((void));
static int brand PARAMS((void));
static void sbrand PARAMS((unsigned long)); /* set bash random number generator. */
static void seedrand PARAMS((void)); /* seed generator randomly */
static u_bits32_t brand32 PARAMS((void));
static void sbrand32 PARAMS((u_bits32_t));
static void seedrand32 PARAMS((void));
static void perturb_rand32 PARAMS((void));
static u_bits32_t get_urandom32 PARAMS((void));
static SHELL_VAR *assign_random PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
static SHELL_VAR *get_random PARAMS((SHELL_VAR *));
@@ -1348,201 +1331,12 @@ init_seconds_var ()
INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds);
return v;
}
/* The random number seed. You can change this by setting RANDOM. */
static u_bits32_t rseed = 1;
static int last_random_value;
/* Functions for $RANDOM and $SRANDOM */
int last_random_value;
static int seeded_subshell = 0;
/* Returns a 32-bit pseudo-random number. */
static u_bits32_t
intrand32 (last)
u_bits32_t last;
{
/* Minimal Standard generator from
"Random number generators: good ones are hard to find",
Park and Miller, Communications of the ACM, vol. 31, no. 10,
October 1988, p. 1195. filtered through FreeBSD.
x(n+1) = 16807 * x(n) mod (2**31 - 1).
We split up the calculations to avoid overflow.
h = last / q; l = x - h * q; t = a * l - h * r
m = 2147483647, a = 16807, q = 127773, r = 2836
There are lots of other combinations of constants to use; look at
https://www.gnu.org/software/gsl/manual/html_node/Other-random-number-generators.html#Other-random-number-generators */
bits32_t h, l, t;
u_bits32_t ret;
/* Can't seed with 0. */
ret = (last == 0) ? 123459876 : last;
h = ret / 127773;
l = ret - (127773 * h);
t = 16807 * l - 2836 * h;
ret = (t < 0) ? t + 0x7fffffff : t;
return (ret);
}
static u_bits32_t
genseed ()
{
struct timeval tv;
u_bits32_t iv;
gettimeofday (&tv, NULL);
iv = (u_bits32_t)seedrand; /* let the compiler truncate */
iv = tv.tv_sec ^ tv.tv_usec ^ getpid () ^ getppid () ^ current_user.uid ^ iv;
return (iv);
}
#define BASH_RAND_MAX 32767 /* 0x7fff - 16 bits */
/* Returns a pseudo-random number between 0 and 32767. */
static int
brand ()
{
unsigned int ret;
rseed = intrand32 (rseed);
if (shell_compatibility_level > 50)
ret = (rseed >> 16) ^ (rseed & 65535);
else
ret = rseed;
return (ret & BASH_RAND_MAX);
}
/* Set the random number generator seed to SEED. */
static void
sbrand (seed)
unsigned long seed;
{
rseed = seed;
last_random_value = 0;
}
static void
seedrand ()
{
u_bits32_t iv;
iv = genseed ();
sbrand (iv);
}
static u_bits32_t rseed32 = 1073741823;
static int last_rand32;
static int urandfd = -1;
#define BASH_RAND32_MAX 0x7fffffff /* 32 bits */
/* Returns a 32-bit pseudo-random number between 0 and 4294967295. */
static u_bits32_t
brand32 ()
{
u_bits32_t ret;
rseed32 = intrand32 (rseed32);
return (rseed32 & BASH_RAND32_MAX);
}
static void
sbrand32 (seed)
u_bits32_t seed;
{
last_rand32 = rseed32 = seed;
}
static void
seedrand32 ()
{
u_bits32_t iv;
iv = genseed ();
sbrand32 (iv);
}
static void
perturb_rand32 ()
{
rseed32 ^= genseed ();
}
/* Force another attempt to open /dev/urandom on the next call to get_urandom32 */
void
urandom_close ()
{
if (urandfd >= 0)
close (urandfd);
urandfd = -1;
}
#if !defined (HAVE_GETRANDOM)
/* Imperfect emulation of getrandom(2). */
#ifndef GRND_NONBLOCK
# define GRND_NONBLOCK 1
# define GRND_RANDOM 2
#endif
static ssize_t
getrandom (buf, len, flags)
void *buf;
size_t len;
unsigned int flags;
{
int oflags;
ssize_t r;
static int urand_unavail = 0;
#if HAVE_GETENTROPY
r = getentropy (buf, len);
return (r == 0) ? len : -1;
#endif
if (urandfd == -1 && urand_unavail == 0)
{
oflags = O_RDONLY;
if (flags & GRND_NONBLOCK)
oflags |= O_NONBLOCK;
urandfd = open ("/dev/urandom", oflags, 0);
if (urandfd >= 0)
SET_CLOSE_ON_EXEC (urandfd);
else
{
urand_unavail = 1;
return -1;
}
}
if (urandfd >= 0 && (r = read (urandfd, buf, len)) == len)
return (r);
return -1;
}
#endif
static u_bits32_t
get_urandom32 ()
{
u_bits32_t ret;
if (getrandom ((void *)&ret, sizeof (ret), GRND_NONBLOCK) == sizeof (ret))
return (last_rand32 = ret);
#if defined (HAVE_ARC4RANDOM)
ret = arc4random ();
#else
if (subshell_environment)
perturb_rand32 ();
do
ret = brand32 ();
while (ret == last_rand32);
#endif
return (last_rand32 = ret);
}
static SHELL_VAR *
assign_random (self, value, unused, key)
SHELL_VAR *self;