summaryrefslogtreecommitdiffstats
path: root/bin/sh/parser.c
Commit message (Collapse)AuthorAgeFilesLines
* The (i < PROMPTLEN - 1) test added by r300442 in the code for the defaulttruckman2016-06-011-1/+1
| | | | | | | | | | | 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
* Hopefully fix Coverity CID 1008328 (Out-of-bounds write) in /bin/sh.truckman2016-05-231-4/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* sh: Handle empty hostname and $PWD when building promptvangyzen2016-05-041-2/+3
| | | | | | | | | | | 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
* sh: Write LINENO value to stack string directly.jilles2016-04-161-4/+6
|
* sh: Simplify code by removing variable bracketed_name.jilles2016-04-131-3/+1
|
* sh(1): replace 0 with NULL for pointers.pfg2016-04-091-1/+1
| | | | | | Found with devel/coccinelle. Reviewed by: jilles
* sh: Remove a redundant STPUTC check.jilles2016-03-021-1/+1
|
* sh: Optimize setprompt(0).jilles2016-02-211-0/+2
| | | | Avoid doing work to print an empty prompt (such as when reading scripts).
* wordexp: Rewrite to make WRDE_NOCMD reliable.jilles2015-09-301-0/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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)
* sh: Allow empty << EOF markers.jilles2015-09-021-2/+8
|
* sh: Don't create bad parse result when postponing a bad substitution error.jilles2015-08-231-2/+3
| | | | | | | | | | | | | | 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
* sh: Avoid negative character values from $'\Uffffffff' etc.jilles2015-08-201-5/+6
| | | | | | | | | 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.
* sh: Prefer "" to nullstr where possible.jilles2015-02-151-1/+1
|
* sh: Prepend "$0: " to error messages if there is no command name.jilles2014-11-221-0/+2
|
* sh: Allow backslash-newline continuation in more places:jilles2014-10-191-32/+43
| | | | | | | * directly after a $ * directly after ${ * between the characters of a multi-character operator token * within a parameter name
* sh: Make parseredir() a proper function instead of an emulated nestedjilles2014-10-151-59/+58
| | | | function.
* sh: Remove more gotos.jilles2014-10-151-10/+7
|
* sh: Fix LINENO and prompt after $'\0 and newline.jilles2014-10-031-0/+7
|
* sh: Remove arbitrary length limit on << EOF markers.jilles2014-09-141-21/+17
| | | | This also simplifies the code.
* sh: Make checkend() a real function instead of an emulated nested function.jilles2014-09-141-36/+39
| | | | | No functional change is intended, but the generated code is slightly different.
* sh: Add some const keywords.jilles2014-09-141-1/+1
|
* sh: Allow aliases to force alias substitution on the following word.jilles2014-01-261-0/+6
| | | | | | | | 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).
* sh: Simplify list() in the parser.jilles2013-08-301-21/+22
| | | | | | 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.
* sh: Separate out nbinary allocation into a function.jilles2013-08-301-21/+22
|
* sh: Use makename() where possible.jilles2013-08-301-22/+5
|
* sh: Add a function for the case where one token is required in the parse.jilles2013-08-301-31/+23
|
* sh: Cast -1 to pointer rather than pointer to variable of wrong type.jilles2013-08-301-1/+1
| | | | | | | | | | 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.
* sh: Disallow empty simple commands.jilles2013-08-251-8/+4
| | | | | | | | | | 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.
* sh: Remove unnecessary reset functions.jilles2013-08-161-8/+1
| | | | These are already handled by exception handlers.
* sh: Allow a lone redirection before '|', ';;' or ';&'.jilles2013-08-141-0/+3
| | | | | | | Example: </dev/null | : PR: 181240 MFC after: 1 week
* sh: Remove an incorrect comment.jilles2013-07-251-1/+1
|
* sh: Remove #define MKINIT.jilles2013-07-251-2/+2
| | | | MKINIT only served for the removed mkinit. Many variables can be static now.
* sh: Remove mkinit.jilles2013-07-251-4/+4
| | | | | | | | | | | | | | 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.
* sh: Fix various compiler warnings.jilles2013-04-011-5/+6
| | | | | | | 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.
* sh: Fix crash when parsing '{ } &'.jilles2013-01-131-2/+2
| | | | MFC after: 1 week
* sh: Don't lose $? when backquoted command ends with semicolon or newline.jilles2013-01-131-1/+2
| | | | | | | | | An empty simple command was added and overwrote the exit status with 0. This affects `...` but not $(...). Example: v=`false;`; echo $?
* sh: Remove special support for background simple commands.jilles2011-06-181-3/+2
| | | | It expands the arguments in the parent shell process, which is incorrect.
* sh: Add case statement fallthrough (with ';&' instead of ';;').jilles2011-06-171-4/+10
| | | | | | | | | | | | 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.
* sh: Do parameter expansion before printing PS4 (set -x).jilles2011-06-091-0/+44
| | | | | | | | | | | | | | | | 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.
* sh: Expand aliases after assignments and redirections.jilles2011-05-211-0/+22
|
* sh: Allow terminating a heredoc with a terminator at EOF without a newline.jilles2011-05-201-3/+5
| | | | | | | | | | | | | | | | | | | | | | 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.
* sh: Add \u/\U support (in $'...') for UTF-8.jilles2011-05-081-0/+23
| | | | | | | | | | 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.
* sh: Add $'quoting' (C-style escape sequences).jilles2011-05-051-6/+139
| | | | | | | | | | | | | | | | | | | | | | | | 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)
* sh: Detect an error for ${#var<GARBAGE>}.jilles2011-05-041-0/+2
| | | | | | | | | 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)
* sh: Do not word split "${#parameter}".jilles2011-04-201-2/+2
| | | | | | | | | | | | | This is only a problem if IFS contains digits, which is unusual but valid. Because of an incorrect fix for PR bin/12137, "${#parameter}" was treated as ${#parameter}. The underlying problem was that "${#parameter}" erroneously added CTLESC bytes before determining the length. This was properly fixed for PR bin/56147 but the incorrect fix was not backed out. Reported by: Seeker on forums.freebsd.org MFC after: 2 weeks
* sh: Fix some parameter expansion variants ${#...}.jilles2011-03-131-19/+30
| | | | | | | | | These already worked: $# ${#} ${##} ${#-} ${#?} These now work as well: ${#+word} ${#-word} ${##word} ${#%word} There is an ambiguity in the standard with ${#?}: it could be the length of $? or it could be $# giving an error in the (impossible) case that it is not set. We continue to use the former interpretation as it seems more useful.
* sh: Fix two things about {(...)} <redir:jilles2011-02-051-1/+4
| | | | | | | | * In {(...) <redir1;} <redir2, do not drop redir1. * Maintain the difference between (...) <redir and {(...)} <redir: In (...) <redir, the redirection is performed in the child, while in {(...)} <redir it should be performed in the parent (like {(...); :;} <redir)
* sh: Allow arbitrary large numbers in CHECKSTRSPACE.jilles2010-12-261-2/+1
| | | | | | Reduce "stack string" API somewhat and simplify code. Add a check for integer overflow of the "stack string" length (probably incomplete).
* Remove duplicate check, turning dead code into live code.uqs2010-12-131-2/+0
| | | | | Coverity CID: 5114 Reviewed by: jilles
* sh: Code size optimizations to "stack string" memory allocation:jilles2010-11-231-7/+6
| | | | | | | | * Prefer one CHECKSTRSPACE with multiple USTPUTC to multiple STPUTC. * Add STPUTS macro (based on function) and use it instead of loops that add nul-terminated strings to the stack string. No functional change is intended, but code size is about 1K less on i386.
OpenPOWER on IntegriCloud