POSIX requires accepting unquoted newlines in word in parameter expansions
like ${param+word}, ${param#word}, although the Bourne shell did not support
it, it is not commonly used and might make it harder to find a missing
closing brace.
It was also strange that something like
foo="${bar#
}"
was rejected.
Reported by: Martijn Dekker via Robert Elz
Mainly focus on files that use BSD 3-Clause license.
The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.
Special thanks to Wind River for providing access to "The Duke of
Highlander" tool: an older (2014) run over FreeBSD tree was useful as a
starting point.
Renumber cluase 4 to 3, per what everybody else did when BSD granted
them permission to remove clause 3. My insistance on keeping the same
numbering for legal reasons is too pedantic, so give up on that point.
Submitted by: Jan Schaumann <jschauma@stevens.edu>
Pull Request: https://github.com/freebsd/freebsd/pull/96
case of \c in the prompt format string is a no-op. We already passed
this test at the top of the loop, and i has not yet been incremented in
this path. Change this test to (i < PROMPTLEN - 2).
Reported by: Coverity
CID: 1008328
Reviewed by: cem
MFC after: 1 week
Replace the magic constant 127 in the loop interation count with
"PROMPTLEN - 1".
gethostname() is not guaranteed to NUL terminate the destination
string if it is too short. Decrease the length passed to gethostname()
by one, and add a NUL at the end of the buffer to make sure the
following loop to find the end of the name properly terminates.
The default: case is the likely cause of Coverity CID 1008328. If
i is 126 at the top of the loop interation where the default case
is triggered, i will be incremented to 127 by the default case,
then incremented to 128 at the top of the loop before being compared
to 127 (PROMPTLENT - 1) and terminating the loop. Then the NUL
termination code after the loop will write to ps[128]. Fix by
checking for overflow before incrementing the index and storing the
second character in the buffer.
These fixes are not guaranteed to satisfy Coverity. The code that
increments i in the 'h'/'H' and 'w'/'W' cases may be beyond its
capability to analyze, but the code appears to be safe.
Reported by: Coverity
CID: 1008328
Reviewed by: jilles, cem
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D6482
If the hostname is empty and \h is used in $PS1,
the remainder of the prompt following \h will be empty.
Likewise for $PWD and \w. Fix it.
Reviewed by: jilles
MFC after: 1 week
Sponsored by: Dell Inc.
Differential Revision: https://reviews.freebsd.org/D6188
Shell syntax is too complicated to detect command substitution and unquoted
operators reliably without implementing much of sh's parser. Therefore, have
sh do this detection.
While changing sh's support anyway, also read input from a pipe instead of
arguments to avoid {ARG_MAX} limits and improve privacy, and output count
and length using 16 instead of 8 digits.
The basic concept is:
execl("/bin/sh", "sh", "-c", "freebsd_wordexp ${1:+\"$1\"} -f "$2",
"", flags & WRDE_NOCMD ? "-p" : "", <pipe with words>);
The WRDE_BADCHAR error is still implemented in libc. POSIX requires us to
fail strings containing unquoted braces with code WRDE_BADCHAR. Since this
is normally not a syntax error in sh, there is still a need for checking
code in libc, we_check().
The new we_check() is an optimistic check that all the characters
<newline> | & ; < > ( ) { }
are quoted. To avoid duplicating too much sh logic, such characters are
permitted when quoting characters are seen, even if the quoting characters
may themselves be quoted. This code reports all WRDE_BADCHAR errors; bad
characters that get past it and are a syntax error in sh return WRDE_SYNTAX.
Although many implementations of WRDE_NOCMD erroneously allow some command
substitutions (and ours even documented this), there appears to be code that
relies on its security (codesearch.debian.net shows quite a few uses).
Passing untrusted data to wordexp() still exposes a denial of service
possibility and a fairly large attack surface.
Reviewed by: wblock (man page only)
MFC after: 2 weeks
Relnotes: yes
Security: fixes command execution with wordexp(untrusted, WRDE_NOCMD)
An invalid substitution like ${var@} does not cause a parse error but is
stored in the intermediate representation, to be written as part of the
error message. If there is a CTL* byte in the stored part, this confuses
some code such as the code to skip an unused alternative such as in
${var-alternative}.
To keep things simple, do not store CTL* bytes.
Found with afl-fuzz.
MFC after: 1 week
The negative value was not expected and generated the low 8 bits as a byte,
which may be an invalid character encoding.
The final shift in creating the negative value was undefined as well.
Make the temporary variable unsigned to fix this.
If an alias's value ends with a space or tab, the next word is also
checked for aliases.
This is a POSIX feature. It is useful with utilities like command and
nohup (alias them to themselves followed by a space).
The erflag argument was only used by old-style (``) command substitutions.
We can remove it and handle the special case in the command substitution
code.
NEOF needs to be a non-null pointer distinct from valid union node pointers.
It is not dereferenced.
The new NEOF is much like SIG_ERR except that it is an object pointer
instead of a function pointer.
The variable tokpushback can now be static.
As per POSIX, a simple command must have at least one redirection,
assignment word or command word.
These occured in rare cases such as eval "f()" .
The extension of allowing no commands inside { }, if, while, for, etc.
remains.
Replace the RESET blocks with regular functions and a reset() function that
calls them all.
This code generation tool is unusual and does not appear to provide much
benefit. I do not think isolating the knowledge about which modules need to
be reset is worth an almost 500-line build tool and wider scope for
variables used by the reset functions.
Also, relying on reset functions is often wrong: the cleanup should be done
in exception handlers so that no stale state remains after 'command eval'
and the like.
It now passes WARNS=7 with clang on i386.
GCC 4.2.1 does not understand setjmp() properly so will always trigger
-Wuninitialized. I will not add the volatile keywords to suppress this.
Replacing ;; with the new control operator ;& will cause the next list to be
executed as well without checking its pattern, continuing until a list ends
with ;; or until the end of the case statement. This is like omitting
"break" in a C "switch" statement.
The sequence ;& was formerly invalid.
This feature is proposed for the next POSIX issue in Austin Group issue
#449.
The function name expandstr() and the general idea of doing this kind of
expansion by treating the text as a here document without end marker is from
dash.
All variants of parameter expansion and arithmetic expansion also work (the
latter is not required by POSIX but it does not take extra code and many
other shells also allow it).
Command substitution is prevented because I think it causes too much code to
be re-entered (for example creating an unbounded recursion of trace lines).
Unfortunately, our LINENO is somewhat crude, otherwise PS4='$LINENO+ ' would
be quite useful.
This is sometimes used with eval or old-style command substitution, and most
shells other than ash derivatives allow it.
It can also be used with scripts that violate POSIX's requirement on the
application that they end in a newline (scripts must be text files except
that line length is unlimited).
Example:
v=`cat <<EOF
foo
EOF`
echo $v
This commit does not add support for the similar construct with new-style
command substitution, like
v=$(cat <<EOF
foo
EOF)
This continues to require a newline after the terminator.
Because we have no iconv in base, support for other charsets is not
possible.
Note that \u/\U are processed using the locale that was active when the
shell started. This is necessary to avoid behaviour that depends on the
parse/execute split (for example when placing braces around an entire
script). Therefore, UTF-8 encoding is implemented manually.
A string between $' and ' may contain backslash escape sequences similar to
the ones in a C string constant (except that a single-quote must be escaped
and a double-quote need not be). Details are in the sh(1) man page.
This construct is useful to include unprintable characters, tabs and
newlines in strings; while this can be done with a command substitution
containing a printf command, that needs ugly workarounds if the result is to
end with a newline as command substitution removes all trailing newlines.
The construct may also be useful in future to describe unprintable
characters without needing to write those characters themselves in 'set -x',
'export -p' and the like.
The implementation attempts to comply to the proposal for the next issue of
the POSIX specification. Because this construct is not in POSIX.1-2008,
using it in scripts intended to be portable is unwise.
Matching the minimal locale support in the rest of sh, the \u and \U
sequences are currently not useful.
Exp-run done by: pav (with some other sh(1) changes)
In particular, this makes things like ${#foo[0]} and ${#foo[@]} errors
rather than silent equivalents of ${#foo}.
PR: bin/151720
Submitted by: Mark Johnston
Exp-run done by: pav (with some other sh(1) changes)