[Midnightbsd-cvs] src [6842] stable/0.5: 0.5.1-RELEASE is a security update for mksh

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Oct 4 14:39:09 EDT 2014


Revision: 6842
          http://svnweb.midnightbsd.org/src/?rev=6842
Author:   laffer1
Date:     2014-10-04 14:39:09 -0400 (Sat, 04 Oct 2014)
Log Message:
-----------
0.5.1-RELEASE is a security update for mksh

Modified Paths:
--------------
    stable/0.5/UPDATING
    stable/0.5/bin/mksh/Makefile
    stable/0.5/contrib/mksh/Build.sh
    stable/0.5/contrib/mksh/check.pl
    stable/0.5/contrib/mksh/check.t
    stable/0.5/contrib/mksh/dot.mkshrc
    stable/0.5/contrib/mksh/edit.c
    stable/0.5/contrib/mksh/eval.c
    stable/0.5/contrib/mksh/exec.c
    stable/0.5/contrib/mksh/funcs.c
    stable/0.5/contrib/mksh/jobs.c
    stable/0.5/contrib/mksh/main.c
    stable/0.5/contrib/mksh/mirhash.h
    stable/0.5/contrib/mksh/mksh.1
    stable/0.5/contrib/mksh/sh.h
    stable/0.5/contrib/mksh/var.c
    stable/0.5/sys/conf/newvers.sh

Removed Paths:
-------------
    stable/0.5/contrib/mksh/alloc.c
    stable/0.5/contrib/mksh/copyright
    stable/0.5/contrib/mksh/setmode.c

Property Changed:
----------------
    stable/0.5/contrib/mksh/

Modified: stable/0.5/UPDATING
===================================================================
--- stable/0.5/UPDATING	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/UPDATING	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,5 +1,11 @@
 Updating Information for MidnightBSD users.
 
+20141004:
+	0.5.1 
+	mksh R50c is a minor security update to fix an issue with the
+	handling of environment variables that could provide a limited
+	attack vector.
+
 20140919:
 	0.5-RELEASE
 

Modified: stable/0.5/bin/mksh/Makefile
===================================================================
--- stable/0.5/bin/mksh/Makefile	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/bin/mksh/Makefile	2014-10-04 18:39:09 UTC (rev 6842)
@@ -38,7 +38,7 @@
 		-DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 -DHAVE_PERSISTENT_HISTORY=1 \
 		-DHAVE_SILENT_IDIVWRAPV=0 \
 		-DMKSH_BINSHREDUCED -DMKSH_MIDNIGHTBSD01ASH_COMPAT \
-		-DMKSH_DISABLE_DEPRECATED  -DMKSH_BUILD_R=501
+		-DMKSH_DISABLE_DEPRECATED  -DMKSH_BUILD_R=503
 
 WARNS?=	0
 MAN=	mksh.1 

Index: stable/0.5/contrib/mksh
===================================================================
--- stable/0.5/contrib/mksh	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh	2014-10-04 18:39:09 UTC (rev 6842)

Property changes on: stable/0.5/contrib/mksh
___________________________________________________________________
Modified: svn:mergeinfo
## -1,2 +1,2 ##
 /branches/MIROS/contrib/mksh:5952-6384
-/vendor/MirOS/mksh/dist:6385-6708
\ No newline at end of property
+/vendor/MirOS/mksh/dist:6385-6841
\ No newline at end of property
Modified: stable/0.5/contrib/mksh/Build.sh
===================================================================
--- stable/0.5/contrib/mksh/Build.sh	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/Build.sh	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,5 +1,5 @@
 #!/bin/sh
-srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.662 2014/06/29 10:56:08 tg Exp $'
+srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.664 2014/09/03 19:22:48 tg Exp $'
 #-
 # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 #		2011, 2012, 2013, 2014
@@ -1784,7 +1784,7 @@
 		#define EXTERN
 		#define MKSH_INCLUDES_ONLY
 		#include "sh.h"
-		__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.662 2014/06/29 10:56:08 tg Exp $");
+		__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.664 2014/09/03 19:22:48 tg Exp $");
 		int main(void) { printf("Hello, World!\n"); return (isatty(0)); }
 EOF
 	case $cm in
@@ -2310,7 +2310,7 @@
 addsrcs USE_PRINTF_BUILTIN printf.c
 test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
 test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
-add_cppflags -DMKSH_BUILD_R=501
+add_cppflags -DMKSH_BUILD_R=502
 
 $e $bi$me: Finished configuration testing, now producing output.$ao
 
@@ -2620,7 +2620,7 @@
 MKSH_DONT_EMIT_IDSTRING		omit RCS IDs from binary
 MKSH_MIDNIGHTBSD01ASH_COMPAT	set -o sh: additional compatibility quirk
 MKSH_NOPROSPECTOFWORK		disable jobs, co-processes, etc. (do not use)
-MKSH_NOPWNAM			skip PAM calls, for -static on eglibc, Solaris
+MKSH_NOPWNAM			skip PAM calls, for -static on glibc or Solaris
 MKSH_NO_CMDLINE_EDITING		disable command line editing code entirely
 MKSH_NO_DEPRECATED_WARNING	omit warning when deprecated stuff is run
 MKSH_NO_EXTERNAL_CAT		omit hack to skip cat builtin when flags passed

Deleted: stable/0.5/contrib/mksh/alloc.c
===================================================================
--- stable/0.5/contrib/mksh/alloc.c	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/alloc.c	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,132 +0,0 @@
-/*	$OpenBSD: alloc.c,v 1.8 2008/07/21 17:30:08 millert Exp $	*/
-
-/*-
- * Copyright (c) 2002 Marc Espie.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD
- * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *-
- * area-based allocation built on malloc/free
- */
-
-#include "sh.h"
-
-__RCSID("$MirOS: src/bin/mksh/alloc.c,v 1.8 2008/08/02 17:45:09 tg Exp $");
-
-struct link {
-	struct link *prev;
-	struct link *next;
-};
-
-Area *
-ainit(Area *ap)
-{
-	ap->freelist = NULL;
-	return (ap);
-}
-
-void
-afreeall(Area *ap)
-{
-	struct link *l, *l2;
-
-	for (l = ap->freelist; l != NULL; l = l2) {
-		l2 = l->next;
-		free(l);
-	}
-	ap->freelist = NULL;
-}
-
-#define L2P(l)	( (void *)(((char *)(l)) + sizeof (struct link)) )
-#define P2L(p)	( (struct link *)(((ptrdiff_t)(p)) - sizeof (struct link)) )
-
-void *
-alloc(size_t size, Area *ap)
-{
-	struct link *l;
-
-	if ((l = malloc(sizeof (struct link) + size)) == NULL)
-		internal_errorf("unable to allocate memory");
-	l->next = ap->freelist;
-	l->prev = NULL;
-	if (ap->freelist)
-		ap->freelist->prev = l;
-	ap->freelist = l;
-
-	return (L2P(l));
-}
-
-void *
-aresize(void *ptr, size_t size, Area *ap)
-{
-	struct link *l, *l2, *lprev, *lnext;
-
-	if (ptr == NULL)
-		return (alloc(size, ap));
-
-	l = P2L(ptr);
-	lprev = l->prev;
-	lnext = l->next;
-
-	if ((l2 = realloc(l, sizeof (struct link) + size)) == NULL)
-		internal_errorf("unable to allocate memory");
-	if (lprev)
-		lprev->next = l2;
-	else
-		ap->freelist = l2;
-	if (lnext)
-		lnext->prev = l2;
-
-	return (L2P(l2));
-}
-
-void
-afree(void *ptr, Area *ap)
-{
-	struct link *l;
-#ifdef MKSH_AFREE_DEBUG
-	struct link *lp;
-#endif
-
-	if (!ptr)
-		return;
-
-	l = P2L(ptr);
-
-#ifdef MKSH_AFREE_DEBUG
-	for (lp = ap->freelist; lp != NULL; lp = lp->next)
-		if (l == lp)
-			break;
-	if (lp == NULL) {
-		internal_warningf("afree: pointer %p not allocated", ptr);
-		exit(255);
-	}
-#endif
-
-	if (l->prev)
-		l->prev->next = l->next;
-	else
-		ap->freelist = l->next;
-	if (l->next)
-		l->next->prev = l->prev;
-
-	free(l);
-}

Modified: stable/0.5/contrib/mksh/check.pl
===================================================================
--- stable/0.5/contrib/mksh/check.pl	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/check.pl	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,4 +1,4 @@
-# $MirOS: src/bin/mksh/check.pl,v 1.36 2014/06/09 13:25:50 tg Exp $
+# $MirOS: src/bin/mksh/check.pl,v 1.37 2014/08/19 07:43:32 tg Exp $
 # $OpenBSD: th,v 1.1 2013/12/02 20:39:44 millert Exp $
 #-
 # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
@@ -348,6 +348,7 @@
     print " ($nifailed ignored)" if $nifailed;
     print " ($nxfailed unexpected)" if $nxfailed;
     print " (as expected)" if $nfailed && !$nxfailed && !$nifailed;
+    print " ($nfailed expected)" if $nfailed && ($nxfailed || $nifailed);
     print "\nTotal passed: $tot_passed";
     print " ($nxpassed unexpected)" if $nxpassed;
     print "\n";

Modified: stable/0.5/contrib/mksh/check.t
===================================================================
--- stable/0.5/contrib/mksh/check.t	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/check.t	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,4 +1,4 @@
-# $MirOS: src/bin/mksh/check.t,v 1.654 2014/06/29 11:28:26 tg Exp $
+# $MirOS: src/bin/mksh/check.t,v 1.659 2014/10/03 17:32:09 tg Exp $
 # OpenBSD src/regress/bin/ksh updated: 2013/12/02 20:39:44
 #-
 # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@@ -27,7 +27,7 @@
 # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
 
 expected-stdout:
-	@(#)MIRBSD KSH R50 2014/06/29
+	@(#)MIRBSD KSH R50 2014/10/03
 description:
 	Check version of shell.
 stdin:
@@ -36,7 +36,7 @@
 category: shell:legacy-no
 ---
 expected-stdout:
-	@(#)LEGACY KSH R50 2014/06/29
+	@(#)LEGACY KSH R50 2014/10/03
 description:
 	Check version of legacy shell.
 stdin:
@@ -3733,6 +3733,400 @@
 expected-stdout:
 	 <1> <shift> <1> <2>
 ---
+name: IFS-subst-3
+description:
+	Check leading IFS non-whitespace after trim does make a field
+stdin:
+	showargs() { for i; do echo -n " <$i>"; done; echo; }
+	IFS=:
+	showargs 1 ${-+:foo:bar}
+expected-stdout:
+	 <1> <> <foo> <bar>
+---
+name: IFS-subst-4-1
+description:
+	reported by mikeserv
+stdin:
+	a='space divded  argument
+	here'
+	IFS=\  ; set -- $a
+	IFS= ; q="$*" ; nq=$*
+	printf '<%s>\n' "$*" $* "$q" "$nq"
+	[ "$q" = "$nq" ] && echo =true || echo =false
+expected-stdout:
+	<spacedivdedargument
+	here>
+	<space>
+	<divded>
+	<argument
+	here>
+	<spacedivdedargument
+	here>
+	<spacedivdedargument
+	here>
+	=true
+---
+name: IFS-subst-4-2
+description:
+	extended testsuite based on problem by mikeserv
+stdin:
+	a='space divded  argument
+	here'
+	IFS=\  ; set -- $a
+	IFS= ; q="$@" ; nq=$@
+	printf '<%s>\n' "$*" $* "$q" "$nq"
+	[ "$q" = "$nq" ] && echo =true || echo =false
+expected-stdout:
+	<spacedivdedargument
+	here>
+	<space>
+	<divded>
+	<argument
+	here>
+	<space divded argument
+	here>
+	<space divded argument
+	here>
+	=true
+---
+name: IFS-subst-4-3
+description:
+	extended testsuite based on problem by mikeserv
+stdin:
+	a='space divded  argument
+	here'
+	IFS=\ ; set -- $a; IFS=
+	qs="$*"
+	nqs=$*
+	qk="$@"
+	nqk=$@
+	printf '= qs '; printf '<%s>\n' "$qs"
+	printf '=nqs '; printf '<%s>\n' "$nqs"
+	printf '= qk '; printf '<%s>\n' "$qk"
+	printf '=nqk '; printf '<%s>\n' "$nqk"
+	printf '~ qs '; printf '<%s>\n' "$*"
+	printf '~nqs '; printf '<%s>\n' $*
+	printf '~ qk '; printf '<%s>\n' "$@"
+	printf '~nqk '; printf '<%s>\n' $@
+expected-stdout:
+	= qs <spacedivdedargument
+	here>
+	=nqs <spacedivdedargument
+	here>
+	= qk <space divded argument
+	here>
+	=nqk <space divded argument
+	here>
+	~ qs <spacedivdedargument
+	here>
+	~nqs <space>
+	<divded>
+	<argument
+	here>
+	~ qk <space>
+	<divded>
+	<argument
+	here>
+	~nqk <space>
+	<divded>
+	<argument
+	here>
+---
+name: IFS-subst-4-4
+description:
+	extended testsuite based on problem by mikeserv
+stdin:
+	a='space divded  argument
+	here'
+	IFS=\ ; set -- $a; IFS=
+	qs="$*"
+	printf '= qs '; printf '<%s>\n' "$qs"
+	printf '~ qs '; printf '<%s>\n' "$*"
+	nqs=$*
+	printf '=nqs '; printf '<%s>\n' "$nqs"
+	printf '~nqs '; printf '<%s>\n' $*
+	qk="$@"
+	printf '= qk '; printf '<%s>\n' "$qk"
+	printf '~ qk '; printf '<%s>\n' "$@"
+	nqk=$@
+	printf '=nqk '; printf '<%s>\n' "$nqk"
+	printf '~nqk '; printf '<%s>\n' $@
+expected-stdout:
+	= qs <spacedivdedargument
+	here>
+	~ qs <spacedivdedargument
+	here>
+	=nqs <spacedivdedargument
+	here>
+	~nqs <space>
+	<divded>
+	<argument
+	here>
+	= qk <space divded argument
+	here>
+	~ qk <space>
+	<divded>
+	<argument
+	here>
+	=nqk <space divded argument
+	here>
+	~nqk <space>
+	<divded>
+	<argument
+	here>
+---
+name: IFS-subst-4-4p
+description:
+	extended testsuite based on problem by mikeserv
+stdin:
+	a='space divded  argument
+	here'
+	IFS=\ ; set -- $a; IFS=
+	unset v
+	qs=${v:-"$*"}
+	printf '= qs '; printf '<%s>\n' "$qs"
+	printf '~ qs '; printf '<%s>\n' ${v:-"$*"}
+	nqs=${v:-$*}
+	printf '=nqs '; printf '<%s>\n' "$nqs"
+	printf '~nqs '; printf '<%s>\n' ${v:-$*}
+	qk=${v:-"$@"}
+	printf '= qk '; printf '<%s>\n' "$qk"
+	printf '~ qk '; printf '<%s>\n' ${v:-"$@"}
+	nqk=${v:-$@}
+	printf '=nqk '; printf '<%s>\n' "$nqk"
+	printf '~nqk '; printf '<%s>\n' ${v:-$@}
+expected-stdout:
+	= qs <spacedivdedargument
+	here>
+	~ qs <spacedivdedargument
+	here>
+	=nqs <spacedivdedargument
+	here>
+	~nqs <space>
+	<divded>
+	<argument
+	here>
+	= qk <space divded argument
+	here>
+	~ qk <space>
+	<divded>
+	<argument
+	here>
+	=nqk <space divded argument
+	here>
+	~nqk <space>
+	<divded>
+	<argument
+	here>
+---
+name: IFS-subst-4-5
+description:
+	extended testsuite based on problem by mikeserv
+stdin:
+	a='space divded  argument
+	here'
+	IFS=\ ; set -- $a; IFS=,
+	qs="$*"
+	printf '= qs '; printf '<%s>\n' "$qs"
+	printf '~ qs '; printf '<%s>\n' "$*"
+	nqs=$*
+	printf '=nqs '; printf '<%s>\n' "$nqs"
+	printf '~nqs '; printf '<%s>\n' $*
+	qk="$@"
+	printf '= qk '; printf '<%s>\n' "$qk"
+	printf '~ qk '; printf '<%s>\n' "$@"
+	nqk=$@
+	printf '=nqk '; printf '<%s>\n' "$nqk"
+	printf '~nqk '; printf '<%s>\n' $@
+expected-stdout:
+	= qs <space,divded,argument
+	here>
+	~ qs <space,divded,argument
+	here>
+	=nqs <space,divded,argument
+	here>
+	~nqs <space>
+	<divded>
+	<argument
+	here>
+	= qk <space divded argument
+	here>
+	~ qk <space>
+	<divded>
+	<argument
+	here>
+	=nqk <space divded argument
+	here>
+	~nqk <space>
+	<divded>
+	<argument
+	here>
+---
+name: IFS-subst-4-5p
+description:
+	extended testsuite based on problem by mikeserv
+stdin:
+	a='space divded  argument
+	here'
+	IFS=\ ; set -- $a; IFS=,
+	unset v
+	qs=${v:-"$*"}
+	printf '= qs '; printf '<%s>\n' "$qs"
+	printf '~ qs '; printf '<%s>\n' ${v:-"$*"}
+	nqs=${v:-$*}
+	printf '=nqs '; printf '<%s>\n' "$nqs"
+	printf '~nqs '; printf '<%s>\n' ${v:-$*}
+	qk=${v:-"$@"}
+	printf '= qk '; printf '<%s>\n' "$qk"
+	printf '~ qk '; printf '<%s>\n' ${v:-"$@"}
+	nqk=${v:-$@}
+	printf '=nqk '; printf '<%s>\n' "$nqk"
+	printf '~nqk '; printf '<%s>\n' ${v:-$@}
+expected-stdout:
+	= qs <space,divded,argument
+	here>
+	~ qs <space,divded,argument
+	here>
+	=nqs <space,divded,argument
+	here>
+	~nqs <space>
+	<divded>
+	<argument
+	here>
+	= qk <space divded argument
+	here>
+	~ qk <space>
+	<divded>
+	<argument
+	here>
+	=nqk <space divded argument
+	here>
+	~nqk <space>
+	<divded>
+	<argument
+	here>
+---
+name: IFS-subst-5
+description:
+	extended testsuite based on IFS-subst-3
+	differs slightly from ksh93:
+	- omit trailing field in a3zna, a7ina (unquoted $@ expansion)
+	- has extra middle fields in b5ins, b7ina (IFS_NWS unquoted expansion)
+	differs slightly from bash:
+	- omit leading field in a5ins, a7ina (IFS_NWS unquoted expansion)
+	differs slightly from zsh:
+	- differs in assignment, not expansion; probably zsh bug
+	- has extra middle fields in b5ins, b7ina (IFS_NWS unquoted expansion)
+	'emulate sh' zsh has extra fields in
+	- a5ins (IFS_NWS unquoted $*)
+	- b5ins, matching mksh’s
+stdin:
+	"$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
+	echo '=a1zns'
+	"$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
+	echo '=a2zqs'
+	"$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
+	echo '=a3zna'
+	"$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
+	echo '=a4zqa'
+	"$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
+	echo '=a5ins'
+	"$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
+	echo '=a6iqs'
+	"$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
+	echo '=a7ina'
+	"$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
+	echo '=a8iqa'
+	"$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
+	echo '=b1zns'
+	"$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
+	echo '=b2zqs'
+	"$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
+	echo '=b3zna'
+	"$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
+	echo '=b4zqa'
+	"$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
+	echo '=b5ins'
+	"$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
+	echo '=b6iqs'
+	"$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
+	echo '=b7ina'
+	"$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
+	echo '=b8iqa'
+expected-stdout:
+	[2]
+	<2>
+	=a1zns
+	[2]
+	<2>
+	=a2zqs
+	[2]
+	< 2 >
+	=a3zna
+	[]
+	[2]
+	[]
+	< 2 >
+	=a4zqa
+	[2]
+	<,2,>
+	=a5ins
+	[,2,]
+	<,2,>
+	=a6iqs
+	[2]
+	< 2 >
+	=a7ina
+	[]
+	[2]
+	[]
+	< 2 >
+	=a8iqa
+	[A]
+	[B]
+	[C]
+	<ABC>
+	=b1zns
+	[ABC]
+	<ABC>
+	=b2zqs
+	[A]
+	[B]
+	[C]
+	<A B   C>
+	=b3zna
+	[A]
+	[B]
+	[]
+	[]
+	[C]
+	<A B   C>
+	=b4zqa
+	[A]
+	[B]
+	[]
+	[]
+	[C]
+	<A,B,,,C>
+	=b5ins
+	[A,B,,,C]
+	<A,B,,,C>
+	=b6iqs
+	[A]
+	[B]
+	[]
+	[]
+	[C]
+	<A B   C>
+	=b7ina
+	[A]
+	[B]
+	[]
+	[]
+	[C]
+	<A B   C>
+	=b8iqa
+---
 name: IFS-arith-1
 description:
 	http://austingroupbugs.net/view.php?id=832
@@ -7791,6 +8185,17 @@
 expected-stdout:
 	<1> <> <2> <> <+> <> <3> <> <+> <> .
 ---
+name: varexpand-null-3
+description:
+	Ensure concatenating behaviour matches other shells
+	although the line 2<> is probably wrong? XNULLSUB case.
+stdin:
+	x=; printf "1<%s>\n" "$x$@"
+	set A; printf "2<%s>\n" "${@:+}"
+expected-stdout:
+	1<>
+	2<>
+---
 name: print-funny-chars
 description:
 	Check print builtin's capability to output designated characters

Deleted: stable/0.5/contrib/mksh/copyright
===================================================================
--- stable/0.5/contrib/mksh/copyright	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/copyright	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,30 +0,0 @@
-$MirOS: src/bin/mksh/copyright,v 1.28 2009/03/22 16:55:38 tg Rel $
-
-The MirBSD Korn Shell (mksh) is
-
-Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-	Thorsten “mirabilos” Glaser <tg at mirbsd.de>
-
-Provided that these terms and disclaimer and all copyright notices
-are retained or reproduced in an accompanying document, permission
-is granted to deal in this work without restriction, including un‐
-limited rights to use, publicly perform, distribute, sell, modify,
-merge, give away, or sublicence.
-
-This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
-the utmost extent permitted by applicable law, neither express nor
-implied; without malicious intent or gross negligence. In no event
-may a licensor, author or contributor be held liable for indirect,
-direct, other damage, loss, or other issues arising in any way out
-of dealing in the work, even if advised of the possibility of such
-damage or existence of a defect, except proven that it results out
-of said person’s immediate fault when using the work as intended.
-
-
-The developer of mksh recognises the efforts of the pdksh authors,
-who had dedicated their work into Public Domain, and all contribu-
-tors. See the documentation, CVS, and web site for details.
-
-Depending on the target operating environment, setmode.c (3-clause
-BSD licence) or strlcpy.c (ISC licence) may be added during compi-
-lation; refer to these files for details.

Modified: stable/0.5/contrib/mksh/dot.mkshrc
===================================================================
--- stable/0.5/contrib/mksh/dot.mkshrc	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/dot.mkshrc	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,5 +1,5 @@
 # $Id$
-# $MirOS: src/bin/mksh/dot.mkshrc,v 1.88 2014/01/11 18:09:39 tg Exp $
+# $MirOS: src/bin/mksh/dot.mkshrc,v 1.89 2014/07/28 21:45:44 tg Exp $
 #-
 # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
 #		2011, 2012, 2013, 2014
@@ -242,20 +242,23 @@
 
 # pager (not control character safe)
 function smores {
-	local dummy line llen curlin=0
-
-	cat "$@" | while IFS= read -r line; do
-		llen=${%line}
-		(( llen == -1 )) && llen=${#line}
-		(( llen = llen ? (llen + COLUMNS - 1) / COLUMNS : 1 ))
-		if (( (curlin += llen) >= LINES )); then
-			print -n -- '\033[7m--more--\033[0m'
-			read -u1 dummy
-			[[ $dummy = [Qq]* ]] && return 0
-			curlin=$llen
-		fi
-		print -r -- "$line"
-	done
+	(
+		set +m
+		cat "$@" |&
+		trap "rv=\$?; kill $! >/dev/null 2>&1; exit \$rv" EXIT
+		while IFS= read -pr line; do
+			llen=${%line}
+			(( llen == -1 )) && llen=${#line}
+			(( llen = llen ? (llen + COLUMNS - 1) / COLUMNS : 1 ))
+			if (( (curlin += llen) >= LINES )); then
+				print -n -- '\033[7m--more--\033[0m'
+				read -u1 || exit $?
+				[[ $REPLY = [Qq]* ]] && exit 0
+				curlin=$llen
+			fi
+			print -r -- "$line"
+		done
+	)
 }
 
 # base64 encoder and decoder, RFC compliant, NUL safe

Modified: stable/0.5/contrib/mksh/edit.c
===================================================================
--- stable/0.5/contrib/mksh/edit.c	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/edit.c	2014-10-04 18:39:09 UTC (rev 6842)
@@ -28,7 +28,7 @@
 
 #ifndef MKSH_NO_CMDLINE_EDITING
 
-__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.275 2014/01/05 21:57:24 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.276 2014/07/13 11:34:28 tg Exp $");
 
 /*
  * in later versions we might use libtermcap for this, but since external
@@ -1628,7 +1628,7 @@
 	int adj = x_adj_done;
 
 	x_lastcp();
-	while (*str && str < xlp && adj == x_adj_done)
+	while (*str && str < xlp && x_col < xx_cols && adj == x_adj_done)
 		x_zotc3(&str);
 }
 

Modified: stable/0.5/contrib/mksh/eval.c
===================================================================
--- stable/0.5/contrib/mksh/eval.c	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/eval.c	2014-10-04 18:39:09 UTC (rev 6842)
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.150 2014/06/09 11:16:07 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.152 2014/10/03 17:32:11 tg Exp $");
 
 /*
  * string expansion
@@ -244,8 +244,8 @@
 		internal_errorf("expand(NULL)");
 	/* for alias, readonly, set, typeset commands */
 	if ((f & DOVACHECK) && is_wdvarassign(ccp)) {
-		f &= ~(DOVACHECK|DOBLANK|DOGLOB|DOTILDE);
-		f |= DOASNTILDE;
+		f &= ~(DOVACHECK | DOBLANK | DOGLOB | DOTILDE);
+		f |= DOASNTILDE | DOASNFIELD;
 	}
 	if (Flag(FNOGLOB))
 		f &= ~DOGLOB;
@@ -261,7 +261,7 @@
 	fdo = 0;
 	saw_eq = false;
 	/* must be 1/0 */
-	tilde_ok = (f & (DOTILDE|DOASNTILDE)) ? 1 : 0;
+	tilde_ok = (f & (DOTILDE | DOASNTILDE)) ? 1 : 0;
 	doblank = 0;
 	make_magic = false;
 	word = (f&DOBLANK) ? IFS_WS : IFS_WORD;
@@ -422,7 +422,7 @@
 						print_value_quoted(&shf, str_val(st->var));
 						x.str = shf_sclose(&shf);
 						break;
-					}
+					    }
 					case '0': {
 						char *beg, *mid, *end, *stg;
 						mksh_ari_t from = 0, num = -1, flen, finc = 0;
@@ -472,7 +472,7 @@
 							utfincptr(beg, &num);
 						strndupx(x.str, beg, num, ATEMP);
 						goto do_CSUBST;
-					}
+					    }
 					case '/': {
 						char *s, *p, *d, *sbeg, *end;
 						char *pat, *rrep;
@@ -616,7 +616,7 @@
 						if (rrep != null)
 							afree(rrep, ATEMP);
 						goto do_CSUBST;
-					}
+					    }
 					case '#':
 					case '%':
 						/* ! DOBLANK,DOBRACE,DOTILDE */
@@ -649,7 +649,7 @@
 						 * a arithmetic operator.
 						 */
 						if (!(x.var->flag & INTEGER))
-							f |= DOASNTILDE|DOTILDE;
+							f |= DOASNTILDE | DOTILDE;
 						f |= DOTEMP;
 						/*
 						 * These will be done after the
@@ -663,6 +663,7 @@
 						f |= DOTEMP;
 						/* FALLTHROUGH */
 					default:
+						word = IFS_WORD;
 						/* Enable tilde expansion */
 						tilde_ok = 1;
 						f |= DOTILDE;
@@ -671,7 +672,7 @@
 					/* skip word */
 					sp += wdscan(sp, CSUBST) - sp;
 				continue;
-			}
+			    }
 			case CSUBST:
 				/* only get here if expanding word */
  do_CSUBST:
@@ -741,6 +742,7 @@
 					if (f & DOBLANK)
 						doblank++;
 					st = st->prev;
+					word = quote || (!*x.str && (f & DOASNFIELD)) ? IFS_WORD : IFS_WS;
 					continue;
 				case '?': {
 					char *s = Xrestpos(ds, dp, st->base);
@@ -749,7 +751,7 @@
 					    dp == s ?
 					    "parameter null or not set" :
 					    (debunk(s, s, strlen(s) + 1), s));
-				}
+				    }
 				case '0':
 				case '/':
 				case 0x100 | '#':
@@ -756,6 +758,7 @@
 				case 0x100 | 'Q':
 					dp = Xrestpos(ds, dp, st->base);
 					type = XSUB;
+					word = quote || (!*x.str && (f & DOASNFIELD)) ? IFS_WORD : IFS_WS;
 					if (f & DOBLANK)
 						doblank++;
 					st = st->prev;
@@ -795,13 +798,6 @@
 			type = XBASE;
 			if (f & DOBLANK) {
 				doblank--;
-				/*
-				 * XXX not really correct:
-				 *	x=; "$x$@"
-				 * should generate a null argument and
-				 *	set A; "${@:+}"
-				 * shouldn't.
-				 */
 				if (dp == Xstring(ds, dp))
 					word = IFS_WS;
 			}
@@ -825,7 +821,7 @@
 			if ((c = *x.str++) == '\0') {
 				/*
 				 * force null words to be created so
-				 * set -- '' 2 ''; foo "$@" will do
+				 * set -- "" 2 ""; echo "$@" will do
 				 * the right thing
 				 */
 				if (quote && x.split)
@@ -837,9 +833,21 @@
 					continue;
 				}
 				c = ifs0;
+				if ((f & DOASNFIELD)) {
+					/* assignment, do not field-split */
+					if (x.split) {
+						c = ' ';
+						break;
+					}
+					if (c == 0) {
+						continue;
+					}
+				}
 				if (c == 0) {
 					if (quote && !x.split)
 						continue;
+					if (!quote && word == IFS_WS)
+						continue;
 					/* this is so we don't terminate */
 					c = ' ';
 					/* now force-emit a word */
@@ -897,14 +905,14 @@
 			 *	word		|	ws	nws	0
 			 *	-----------------------------------
 			 *	IFS_WORD		w/WS	w/NWS	w
-			 *	IFS_WS			-/WS	w/NWS	-
-			 *	IFS_NWS			-/NWS	w/NWS	w
+			 *	IFS_WS			-/WS	-/NWS	-
+			 *	IFS_NWS			-/NWS	w/NWS	-
 			 * (w means generate a word)
 			 * Note that IFS_NWS/0 generates a word (AT&T ksh
 			 * doesn't do this, but POSIX does).
 			 */
 			if (word == IFS_WORD ||
-			    (!ctype(c, C_IFSWS) && c && word == IFS_NWS)) {
+			    (word == IFS_NWS && c && !ctype(c, C_IFSWS))) {
  emit_word:
 				*dp++ = '\0';
 				cp = Xclose(ds, dp);
@@ -922,7 +930,8 @@
 					    strlen(cp) + 1));
 				fdo = 0;
 				saw_eq = false;
-				tilde_ok = (f & (DOTILDE|DOASNTILDE)) ? 1 : 0;
+				/* must be 1/0 */
+				tilde_ok = (f & (DOTILDE | DOASNTILDE)) ? 1 : 0;
 				if (c == 0)
 					return;
 				Xinit(ds, dp, 128, ATEMP);
@@ -1006,7 +1015,7 @@
 					 * through the sequence ${A=a=}~
 					 */
 					if (type == XBASE &&
-					    (f & (DOTILDE|DOASNTILDE)) &&
+					    (f & (DOTILDE | DOASNTILDE)) &&
 					    (tilde_ok & 2)) {
 						const char *tcp;
 						char *tdp = dp;

Modified: stable/0.5/contrib/mksh/exec.c
===================================================================
--- stable/0.5/contrib/mksh/exec.c	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/exec.c	2014-10-04 18:39:09 UTC (rev 6842)
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.132 2014/06/24 18:38:31 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.133 2014/10/03 17:32:11 tg Exp $");
 
 #ifndef MKSH_DEFAULT_EXECSHELL
 #define MKSH_DEFAULT_EXECSHELL	"/bin/sh"
@@ -635,7 +635,7 @@
 	for (i = 0; t->vars[i]; i++) {
 		/* do NOT lookup in the new var/fn block just created */
 		e->loc = l_expand;
-		cp = evalstr(t->vars[i], DOASNTILDE);
+		cp = evalstr(t->vars[i], DOASNTILDE | DOASNFIELD);
 		e->loc = l_assign;
 		if (Flag(FXTRACE)) {
 			const char *ccp;

Modified: stable/0.5/contrib/mksh/funcs.c
===================================================================
--- stable/0.5/contrib/mksh/funcs.c	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/funcs.c	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,5 +1,5 @@
 /*	$OpenBSD: c_ksh.c,v 1.34 2013/12/17 16:37:05 deraadt Exp $	*/
-/*	$OpenBSD: c_sh.c,v 1.44 2013/09/04 15:49:18 millert Exp $	*/
+/*	$OpenBSD: c_sh.c,v 1.45 2014/08/27 08:26:04 jmc Exp $	*/
 /*	$OpenBSD: c_test.c,v 1.18 2009/03/01 20:11:06 otto Exp $	*/
 /*	$OpenBSD: c_ulimit.c,v 1.19 2013/11/28 10:33:37 sobrado Exp $	*/
 
@@ -38,7 +38,7 @@
 #endif
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.256 2014/06/09 13:25:52 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.258 2014/09/03 19:55:51 tg Exp $");
 
 #if HAVE_KILLPG
 /*
@@ -3643,12 +3643,14 @@
 				break;
 			while (n) {
 				w = write(STDOUT_FILENO, cp, n);
+				eno = errno;
+				/* give the user a chance to ^C out */
+				intrcheck();
 				if (w == -1) {
-					if (errno == EINTR)
+					if (eno == EINTR)
 						/* interrupted, try again */
 						continue;
 					/* an error occured during writing */
-					eno = errno;
 					bi_errorf("%s: %s", "<stdout>",
 					    cstrerror(eno));
 					rv = 1;

Modified: stable/0.5/contrib/mksh/jobs.c
===================================================================
--- stable/0.5/contrib/mksh/jobs.c	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/jobs.c	2014-10-04 18:39:09 UTC (rev 6842)
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.104 2014/06/10 22:17:09 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.105 2014/10/03 12:32:48 tg Exp $");
 
 #if HAVE_KILLPG
 #define mksh_killpg		killpg
@@ -1339,7 +1339,7 @@
 	do {
 #ifndef MKSH_NOPROSPECTOFWORK
 		pid = waitpid(-1, &status, (WNOHANG |
-#ifdef WCONTINUED
+#if defined(WCONTINUED) && defined(WIFCONTINUED)
 		    WCONTINUED |
 #endif
 		    WUNTRACED));
@@ -1381,7 +1381,7 @@
 		if (WIFSTOPPED(status))
 			p->state = PSTOPPED;
 		else
-#ifdef WIFCONTINUED
+#if defined(WCONTINUED) && defined(WIFCONTINUED)
 		  if (WIFCONTINUED(status)) {
 			p->state = j->state = PRUNNING;
 			/* skip check_job(), no-op in this case */

Modified: stable/0.5/contrib/mksh/main.c
===================================================================
--- stable/0.5/contrib/mksh/main.c	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/main.c	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,6 +1,6 @@
 /*	$OpenBSD: main.c,v 1.54 2013/11/28 10:33:37 sobrado Exp $	*/
-/*	$OpenBSD: tty.c,v 1.9 2006/03/14 22:08:01 deraadt Exp $	*/
-/*	$OpenBSD: io.c,v 1.23 2013/12/17 16:37:06 deraadt Exp $	*/
+/*	$OpenBSD: tty.c,v 1.10 2014/08/10 02:44:26 guenther Exp $	*/
+/*	$OpenBSD: io.c,v 1.25 2014/08/11 20:28:47 guenther Exp $	*/
 /*	$OpenBSD: table.c,v 1.15 2012/02/19 07:52:30 otto Exp $	*/
 
 /*-
@@ -34,7 +34,7 @@
 #include <locale.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/main.c,v 1.280 2014/06/09 12:28:17 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/main.c,v 1.284 2014/10/03 17:19:27 tg Exp $");
 
 extern char **environ;
 
@@ -63,7 +63,7 @@
 
 static const char *initcoms[] = {
 	Ttypeset, "-r", initvsn, NULL,
-	Ttypeset, "-x", "HOME", "PATH", "RANDOM", "SHELL", NULL,
+	Ttypeset, "-x", "HOME", "PATH", "SHELL", NULL,
 	Ttypeset, "-i10", "COLUMNS", "LINES", "SECONDS", "TMOUT", NULL,
 	Talias,
 	"integer=typeset -i",
@@ -184,7 +184,7 @@
 	int argi, i;
 	Source *s = NULL;
 	struct block *l;
-	unsigned char restricted, errexit, utf_flag;
+	unsigned char restricted_shell, errexit, utf_flag;
 	char *cp;
 	const char *ccp, **wp;
 	struct tbl *vp;
@@ -407,7 +407,11 @@
 	setint_n((vp_pipest = global("PIPESTATUS")), 0, 10);
 
 	/* Set this before parsing arguments */
-	Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0;
+	Flag(FPRIVILEGED) = (
+#if HAVE_ISSETUGID
+	    issetugid() ||
+#endif
+	    kshuid != ksheuid || kshgid != kshegid) ? 2 : 0;
 
 	/* this to note if monitor is set on command line (see below) */
 #ifndef MKSH_UNEMPLOYED
@@ -573,7 +577,7 @@
 	}
 
 	/* Disable during .profile/ENV reading */
-	restricted = Flag(FRESTRICTED);
+	restricted_shell = Flag(FRESTRICTED);
 	Flag(FRESTRICTED) = 0;
 	errexit = Flag(FERREXIT);
 	Flag(FERREXIT) = 0;
@@ -603,7 +607,7 @@
 			change_flag(FPRIVILEGED, OF_INTERNAL, false);
 	}
 
-	if (restricted) {
+	if (restricted_shell) {
 		shcomexec(restr_com);
 		/* After typeset command... */
 		Flag(FRESTRICTED) = 1;

Modified: stable/0.5/contrib/mksh/mirhash.h
===================================================================
--- stable/0.5/contrib/mksh/mirhash.h	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/mirhash.h	2014-10-04 18:39:09 UTC (rev 6842)
@@ -30,6 +30,12 @@
  * for speed reasons, specified for the regular stable hash, but very
  * much recommended if the actual output value may differ across runs
  * (so is using a random value instead of 0 for the IV).
+ *-
+ * Little quote gem:
+ *	We are looking into it. Changing the core
+ *	hash function in PHP isn't a trivial change
+ *	and will take us some time.
+ * -- Rasmus Lerdorf
  */
 
 #ifndef SYSKERN_MIRHASH_H
@@ -38,7 +44,7 @@
 
 #include <sys/types.h>
 
-__RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.2 2014/06/29 11:48:05 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.3 2014/10/02 19:34:06 tg Exp $");
 
 /*-
  * BAFH itself is defined by the following primitives:

Modified: stable/0.5/contrib/mksh/mksh.1
===================================================================
--- stable/0.5/contrib/mksh/mksh.1	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/mksh.1	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,5 +1,5 @@
-.\" $MirOS: src/bin/mksh/mksh.1,v 1.336 2014/06/24 20:47:44 tg Exp $
-.\" $OpenBSD: ksh.1,v 1.152 2014/02/12 16:28:13 schwarze Exp $
+.\" $MirOS: src/bin/mksh/mksh.1,v 1.343 2014/10/03 12:35:38 tg Exp $
+.\" $OpenBSD: ksh.1,v 1.153 2014/08/17 07:15:41 jmc Exp $
 .\"-
 .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
 .\"		2010, 2011, 2012, 2013, 2014
@@ -74,7 +74,7 @@
 .\" with -mandoc, it might implement .Mx itself, but we want to
 .\" use our own definition. And .Dd must come *first*, always.
 .\"
-.Dd $Mdocdate: June 24 2014 $
+.Dd $Mdocdate: October 3 2014 $
 .\"
 .\" Check which macro package we use, and do other -mdoc setup.
 .\"
@@ -208,7 +208,7 @@
 .Ar string .
 .It Fl i
 Interactive shell.
-A shell is
+A shell that reads commands from standard input is
 .Dq interactive
 if this
 option is used or if both standard input and standard error are attached
@@ -1232,10 +1232,8 @@
 whitespace octets, delimit a field.
 As a special case, leading and trailing
 .Ev IFS
-whitespace and trailing
-.Ev IFS
-non-whitespace are stripped (i.e. no leading or trailing empty field
-is created by it); leading
+whitespace is stripped (i.e. no leading or trailing empty field
+is created by it); leading or trailing
 .Pf non- Ev IFS
 whitespace does create an empty field.
 .Pp
@@ -1877,6 +1875,9 @@
 .It Ev HISTSIZE
 The number of commands normally stored for history.
 The default is 2047.
+Do not set this value to insanely high values such as 1000000000 because
+.Nm
+can then not allocate enough memory for the history and will not start.
 .It Ev HOME
 The default directory for the
 .Ic cd
@@ -2697,7 +2698,7 @@
 Less than; the result is 1 if the left argument is less than the right, 0 if
 not.
 .It \*(Lt= \*(Gt \*(Gt=
-Less than or equal, greater than or equal, greater than.
+Less than or equal, greater than, greater than or equal.
 See
 .Ic \*(Lt .
 .It \*(Lt\*(Lt\*(Lt \*(Gt\*(Gt\*(Gt
@@ -2711,8 +2712,15 @@
 .It + \- * /
 Addition, subtraction, multiplication, and division.
 .It %
-Remainder; the result is the remainder of the division of the left argument by
-the right.
+Remainder; the result is the symmetric remainder of the division of the left
+argument by the right.
+To get the mathematical modulus of
+.Dq a Ic mod No b ,
+use the formula
+.Do
+.Pq a % b + b
+.No % b
+.Dc .
 .It Xo
 .Sm off
 .Aq Ar arg1 ?
@@ -6436,8 +6444,8 @@
 .Pp
 .Nm mksh
 provides a consistent set of 32-bit integer arithmetics, both signed
-and unsigned, with defined wraparound and sign of the result of a modulo
-operation, even (defying POSIX) on 64-bit systems.
+and unsigned, with defined wraparound and sign of the result of a
+remainder operation, even (defying POSIX) on 64-bit systems.
 If you require 64-bit integer arithmetics, use
 .Nm lksh Pq legacy mksh
 instead, but be aware that, in POSIX, it's legal for the OS to make

Deleted: stable/0.5/contrib/mksh/setmode.c
===================================================================
--- stable/0.5/contrib/mksh/setmode.c	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/setmode.c	2014-10-04 18:39:09 UTC (rev 6842)
@@ -1,473 +0,0 @@
-/*	$OpenBSD: setmode.c,v 1.17 2005/08/08 08:05:34 espie Exp $	*/
-/*	$NetBSD: setmode.c,v 1.15 1997/02/07 22:21:06 christos Exp $	*/
-
-/*
- * Copyright (c) 1989, 1993, 1994
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Dave Borman at Cray Research, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(HAVE_CONFIG_H) && (HAVE_CONFIG_H != 0)
-/* usually when packaged with third-party software */
-#ifdef CONFIG_H_FILENAME
-#include CONFIG_H_FILENAME
-#else
-#include "config.h"
-#endif
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#ifdef SETMODE_DEBUG
-#include <stdio.h>
-#endif
-
-__SCCSID("@(#)setmode.c	8.2 (Berkeley) 3/25/94");
-__RCSID("$MirOS: src/bin/mksh/setmode.c,v 1.14 2009/06/10 18:12:48 tg Rel $");
-__RCSID("$miros: src/lib/libc/gen/setmode.c,v 1.12 2009/06/10 18:12:42 tg Exp $");
-
-/* for mksh */
-#ifdef ksh_isdigit
-#undef isdigit
-#define isdigit		ksh_isdigit
-#endif
-
-#ifndef S_ISTXT
-#define S_ISTXT		0001000
-#endif
-
-#define	SET_LEN		6	/* initial # of bitcmd struct to malloc */
-#define	SET_LEN_INCR	4	/* # of bitcmd structs to add as needed */
-
-typedef struct bitcmd {
-	mode_t	bits;
-	char	cmd;
-	char	cmd2;
-} BITCMD;
-
-#define	CMD2_CLR	0x01
-#define	CMD2_SET	0x02
-#define	CMD2_GBITS	0x04
-#define	CMD2_OBITS	0x08
-#define	CMD2_UBITS	0x10
-
-static BITCMD	*addcmd(BITCMD *, int, int, int, unsigned int);
-static void	 compress_mode(BITCMD *);
-#ifdef SETMODE_DEBUG
-static void	 dumpmode(BITCMD *);
-#endif
-
-/*
- * Given the old mode and an array of bitcmd structures, apply the operations
- * described in the bitcmd structures to the old mode, and return the new mode.
- * Note that there is no '=' command; a strict assignment is just a '-' (clear
- * bits) followed by a '+' (set bits).
- */
-mode_t
-getmode(const void *bbox, mode_t omode)
-{
-	const BITCMD *set;
-	mode_t clrval, newmode, value;
-
-	set = (const BITCMD *)bbox;
-	newmode = omode;
-	for (value = 0;; set++)
-		switch(set->cmd) {
-		/*
-		 * When copying the user, group or other bits around, we "know"
-		 * where the bits are in the mode so that we can do shifts to
-		 * copy them around. If we don't use shifts, it gets real
-		 * grundgy with lots of single bit checks and bit sets.
-		 */
-		case 'u':
-			value = (newmode & S_IRWXU) >> 6;
-			goto common;
-
-		case 'g':
-			value = (newmode & S_IRWXG) >> 3;
-			goto common;
-
-		case 'o':
-			value = newmode & S_IRWXO;
- common:
-			if (set->cmd2 & CMD2_CLR) {
-				clrval =
-				    (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
-				if (set->cmd2 & CMD2_UBITS)
-					newmode &= ~((clrval<<6) & set->bits);
-				if (set->cmd2 & CMD2_GBITS)
-					newmode &= ~((clrval<<3) & set->bits);
-				if (set->cmd2 & CMD2_OBITS)
-					newmode &= ~(clrval & set->bits);
-			}
-			if (set->cmd2 & CMD2_SET) {
-				if (set->cmd2 & CMD2_UBITS)
-					newmode |= (value<<6) & set->bits;
-				if (set->cmd2 & CMD2_GBITS)
-					newmode |= (value<<3) & set->bits;
-				if (set->cmd2 & CMD2_OBITS)
-					newmode |= value & set->bits;
-			}
-			break;
-
-		case '+':
-			newmode |= set->bits;
-			break;
-
-		case '-':
-			newmode &= ~set->bits;
-			break;
-
-		case 'X':
-			if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
-				newmode |= set->bits;
-			break;
-
-		case '\0':
-		default:
-#ifdef SETMODE_DEBUG
-			(void)printf("getmode:%04o -> %04o\n", omode, newmode);
-#endif
-			return (newmode);
-		}
-}
-
-#define	ADDCMD(a, b, c, d)						\
-	if (set >= endset) {						\
-		BITCMD *newset;						\
-		setlen += SET_LEN_INCR;					\
-		newset = realloc(saveset, sizeof(BITCMD) * setlen);	\
-		if (newset == NULL) {					\
-			free(saveset);					\
-			return (NULL);					\
-		}							\
-		set = newset + (set - saveset);				\
-		saveset = newset;					\
-		endset = newset + (setlen - 2);				\
-	}								\
-	set = addcmd(set, (a), (b), (c), (d))
-
-#define	STANDARD_BITS	(S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
-
-void *
-setmode(const char *p)
-{
-	int perm, who;
-	char op, *ep;
-	BITCMD *set, *saveset, *endset;
-	sigset_t signset, sigoset;
-	mode_t mask;
-	int equalopdone = 0, permXbits, setlen;
-	unsigned long perml;
-
-	if (!*p)
-		return (NULL);
-
-	/*
-	 * Get a copy of the mask for the permissions that are mask relative.
-	 * Flip the bits, we want what's not set. Since it's possible that
-	 * the caller is opening files inside a signal handler, protect them
-	 * as best we can.
-	 */
-	sigfillset(&signset);
-	(void)sigprocmask(SIG_BLOCK, &signset, &sigoset);
-	(void)umask(mask = umask(0));
-	mask = ~mask;
-	(void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
-
-	setlen = SET_LEN + 2;
-
-	if ((set = calloc(sizeof(BITCMD), setlen)) == NULL)
-		return (NULL);
-	saveset = set;
-	endset = set + (setlen - 2);
-
-	/*
-	 * If an absolute number, get it and return; disallow non-octal digits
-	 * or illegal bits.
-	 */
-	if (isdigit((unsigned char)*p)) {
-		perml = strtoul(p, &ep, 8);
-		/* The test on perml will also catch overflow. */
-		if (*ep != '\0' || (perml & ~(STANDARD_BITS|S_ISTXT))) {
-			free(saveset);
-			errno = ERANGE;
-			return (NULL);
-		}
-		perm = (mode_t)perml;
-		ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
-		set->cmd = 0;
-		return (saveset);
-	}
-
-	/*
-	 * Build list of structures to set/clear/copy bits as described by
-	 * each clause of the symbolic mode.
-	 */
-	for (;;) {
-		/* First, find out which bits might be modified. */
-		for (who = 0;; ++p) {
-			switch (*p) {
-			case 'a':
-				who |= STANDARD_BITS;
-				break;
-			case 'u':
-				who |= S_ISUID|S_IRWXU;
-				break;
-			case 'g':
-				who |= S_ISGID|S_IRWXG;
-				break;
-			case 'o':
-				who |= S_IRWXO;
-				break;
-			default:
-				goto getop;
-			}
-		}
-
- getop:
-		if ((op = *p++) != '+' && op != '-' && op != '=') {
-			free(saveset);
-			return (NULL);
-		}
-		if (op == '=')
-			equalopdone = 0;
-
-		who &= ~S_ISTXT;
-		for (perm = 0, permXbits = 0;; ++p) {
-			switch (*p) {
-			case 'r':
-				perm |= S_IRUSR|S_IRGRP|S_IROTH;
-				break;
-			case 's':
-				/*
-				 * If specific bits where requested and
-				 * only "other" bits ignore set-id.
-				 */
-				if (who == 0 || (who & ~S_IRWXO))
-					perm |= S_ISUID|S_ISGID;
-				break;
-			case 't':
-				/*
-				 * If specific bits where requested and
-				 * only "other" bits ignore sticky.
-				 */
-				if (who == 0 || (who & ~S_IRWXO)) {
-					who |= S_ISTXT;
-					perm |= S_ISTXT;
-				}
-				break;
-			case 'w':
-				perm |= S_IWUSR|S_IWGRP|S_IWOTH;
-				break;
-			case 'X':
-				permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
-				break;
-			case 'x':
-				perm |= S_IXUSR|S_IXGRP|S_IXOTH;
-				break;
-			case 'u':
-			case 'g':
-			case 'o':
-				/*
-				 * When ever we hit 'u', 'g', or 'o', we have
-				 * to flush out any partial mode that we have,
-				 * and then do the copying of the mode bits.
-				 */
-				if (perm) {
-					ADDCMD(op, who, perm, mask);
-					perm = 0;
-				}
-				if (op == '=')
-					equalopdone = 1;
-				if (op == '+' && permXbits) {
-					ADDCMD('X', who, permXbits, mask);
-					permXbits = 0;
-				}
-				ADDCMD(*p, who, op, mask);
-				break;
-
-			default:
-				/*
-				 * Add any permissions that we haven't already
-				 * done.
-				 */
-				if (perm || (op == '=' && !equalopdone)) {
-					if (op == '=')
-						equalopdone = 1;
-					ADDCMD(op, who, perm, mask);
-					perm = 0;
-				}
-				if (permXbits) {
-					ADDCMD('X', who, permXbits, mask);
-					permXbits = 0;
-				}
-				goto apply;
-			}
-		}
-
- apply:
-		if (!*p)
-			break;
-		if (*p != ',')
-			goto getop;
-		++p;
-	}
-	set->cmd = 0;
-#ifdef SETMODE_DEBUG
-	(void)printf("Before compress_mode()\n");
-	dumpmode(saveset);
-#endif
-	compress_mode(saveset);
-#ifdef SETMODE_DEBUG
-	(void)printf("After compress_mode()\n");
-	dumpmode(saveset);
-#endif
-	return (saveset);
-}
-
-static BITCMD *
-addcmd(BITCMD *set, int op, int who, int oparg, unsigned int mask)
-{
-	switch (op) {
-	case '=':
-		set->cmd = '-';
-		set->bits = who ? who : STANDARD_BITS;
-		set++;
-
-		op = '+';
-		/* FALLTHROUGH */
-	case '+':
-	case '-':
-	case 'X':
-		set->cmd = op;
-		set->bits = (who ? who : (int)mask) & oparg;
-		break;
-
-	case 'u':
-	case 'g':
-	case 'o':
-		set->cmd = op;
-		if (who) {
-			set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
-				    ((who & S_IRGRP) ? CMD2_GBITS : 0) |
-				    ((who & S_IROTH) ? CMD2_OBITS : 0);
-			set->bits = (mode_t)~0;
-		} else {
-			set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
-			set->bits = mask;
-		}
-
-		if (oparg == '+')
-			set->cmd2 |= CMD2_SET;
-		else if (oparg == '-')
-			set->cmd2 |= CMD2_CLR;
-		else if (oparg == '=')
-			set->cmd2 |= CMD2_SET|CMD2_CLR;
-		break;
-	}
-	return (set + 1);
-}
-
-#ifdef SETMODE_DEBUG
-static void
-dumpmode(BITCMD *set)
-{
-	for (; set->cmd; ++set)
-		(void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
-		    set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
-		    set->cmd2 & CMD2_CLR ? " CLR" : "",
-		    set->cmd2 & CMD2_SET ? " SET" : "",
-		    set->cmd2 & CMD2_UBITS ? " UBITS" : "",
-		    set->cmd2 & CMD2_GBITS ? " GBITS" : "",
-		    set->cmd2 & CMD2_OBITS ? " OBITS" : "");
-}
-#endif
-
-/*
- * Given an array of bitcmd structures, compress by compacting consecutive
- * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
- * 'g' and 'o' commands continue to be separate. They could probably be
- * compacted, but it's not worth the effort.
- */
-static void
-compress_mode(BITCMD *set)
-{
-	BITCMD *nset;
-	int setbits, clrbits, Xbits, op;
-
-	for (nset = set;;) {
-		/* Copy over any 'u', 'g' and 'o' commands. */
-		while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
-			*set++ = *nset++;
-			if (!op)
-				return;
-		}
-
-		for (setbits = clrbits = Xbits = 0;; nset++) {
-			if ((op = nset->cmd) == '-') {
-				clrbits |= nset->bits;
-				setbits &= ~nset->bits;
-				Xbits &= ~nset->bits;
-			} else if (op == '+') {
-				setbits |= nset->bits;
-				clrbits &= ~nset->bits;
-				Xbits &= ~nset->bits;
-			} else if (op == 'X')
-				Xbits |= nset->bits & ~setbits;
-			else
-				break;
-		}
-		if (clrbits) {
-			set->cmd = '-';
-			set->cmd2 = 0;
-			set->bits = clrbits;
-			set++;
-		}
-		if (setbits) {
-			set->cmd = '+';
-			set->cmd2 = 0;
-			set->bits = setbits;
-			set++;
-		}
-		if (Xbits) {
-			set->cmd = 'X';
-			set->cmd2 = 0;
-			set->bits = Xbits;
-			set++;
-		}
-	}
-}

Modified: stable/0.5/contrib/mksh/sh.h
===================================================================
--- stable/0.5/contrib/mksh/sh.h	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/sh.h	2014-10-04 18:39:09 UTC (rev 6842)
@@ -169,9 +169,9 @@
 #endif
 
 #ifdef EXTERN
-__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.691 2014/06/29 11:28:28 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.695 2014/10/03 17:32:12 tg Exp $");
 #endif
-#define MKSH_VERSION "R50 2014/06/29"
+#define MKSH_VERSION "R50 2014/10/03"
 
 /* arithmetic types: C implementation */
 #if !HAVE_CAN_INTTYPES
@@ -533,7 +533,7 @@
 #define mkssert(e)	do { } while (/* CONSTCOND */ 0)
 #endif
 
-#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 501)
+#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 503)
 #error Must run Build.sh to compile this.
 extern void thiswillneverbedefinedIhope(void);
 int
@@ -1396,6 +1396,7 @@
 #define DOVACHECK BIT(9)	/* var assign check (for typeset, set, etc) */
 #define DOMARKDIRS BIT(10)	/* force markdirs behaviour */
 #define DOTCOMEXEC BIT(11)	/* not an eval flag, used by sh -c hack */
+#define DOASNFIELD BIT(12)	/* is assignment, change field handling */
 
 #define X_EXTRA	20	/* this many extra bytes in X string */
 

Modified: stable/0.5/contrib/mksh/var.c
===================================================================
--- stable/0.5/contrib/mksh/var.c	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/contrib/mksh/var.c	2014-10-04 18:39:09 UTC (rev 6842)
@@ -28,7 +28,7 @@
 #include <sys/sysctl.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/var.c,v 1.180 2014/06/26 20:36:02 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/var.c,v 1.182 2014/10/03 17:20:03 tg Exp $");
 
 /*-
  * Variables
@@ -751,19 +751,19 @@
 		}
 		val += len;
 	}
-	if (val[0] == '=' || (val[0] == '+' && val[1] == '=')) {
+	if (val[0] == '=') {
 		strndupx(tvar, var, val - var, ATEMP);
-		if (*val++ == '+') {
-			++val;
-			vappend = true;
-		}
-	} else if ((val[0] != '\0') || (set & IMPORT)) {
-		/*
-		 * must have a = when setting a variable by importing
-		 * the original environment, otherwise be empty; we
-		 * also end up here when a variable name was invalid
-		 */
+		++val;
+	} else if (set & IMPORT) {
+		/* environment invalid variable name or no assignment */
 		return (NULL);
+	} else if (val[0] == '+' && val[1] == '=') {
+		strndupx(tvar, var, val - var, ATEMP);
+		val += 2;
+		vappend = true;
+	} else if (val[0] != '\0') {
+		/* other invalid variable names (not from environment) */
+		return (NULL);
 	} else {
 		/* just varname with no value part nor equals sign */
 		strdupx(tvar, var, ATEMP);
@@ -789,8 +789,22 @@
 		}
 		/* check target value for being a valid variable name */
 		ccp = skip_varname(qval, false);
-		if (ccp == qval)
+		if (ccp == qval) {
+			if (ksh_isdigit(qval[0])) {
+				int c;
+
+				if (getn(qval, &c))
+					goto nameref_rhs_checked;
+			} else if (qval[1] == '\0') switch (qval[0]) {
+			case '$':
+			case '!':
+			case '?':
+			case '#':
+			case '-':
+				goto nameref_rhs_checked;
+			}
 			errorf("%s: %s", var, "empty nameref target");
+		}
 		len = (*ccp == '[') ? array_ref_len(ccp) : 0;
 		if (ccp[len]) {
 			/*
@@ -801,6 +815,7 @@
 			errorf("%s: %s", qval,
 			    "nameref target not a valid parameter name");
 		}
+ nameref_rhs_checked:
 		/* prevent nameref loops */
 		while (qval) {
 			if (!strcmp(qval, tvar))

Modified: stable/0.5/sys/conf/newvers.sh
===================================================================
--- stable/0.5/sys/conf/newvers.sh	2014-10-04 14:23:36 UTC (rev 6841)
+++ stable/0.5/sys/conf/newvers.sh	2014-10-04 18:39:09 UTC (rev 6842)
@@ -32,7 +32,7 @@
 # $MidnightBSD: src/sys/conf/newvers.sh,v 1.9 2012/10/07 14:18:18 laffer1 Exp $
 
 TYPE="MidnightBSD"
-REVISION="0.5"
+REVISION="0.5.1"
 BRANCH="RELEASE"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}



More information about the Midnightbsd-cvs mailing list