• fix ${12345678901234567890} segfault (OOB access / integer overflow)

‣ not like oksh did, but using mksh’s built-in features
• handle suggested __pure additions
• revert cid 1004F7F096867C83CF0
  ‣ always use our wcwidth code
  ‣ only use our strlcpy code if none found
• fix a couple of gcc-snapshot and clang/scan-build warnings
• mksh R49~rc1
This commit is contained in:
tg 2014-01-05 21:57:29 +00:00
parent 2f6fa6fb3d
commit 89e774fd7e
13 changed files with 149 additions and 126 deletions

View File

@ -1,8 +1,8 @@
#!/bin/sh
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.654 2013/12/02 19:47:33 tg Exp $'
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.655 2014/01/05 21:57:21 tg Exp $'
#-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013
# 2011, 2012, 2013, 2014
# Thorsten Glaser <tg@mirbsd.org>
#
# Provided that these terms and disclaimer and all copyright notices
@ -340,8 +340,9 @@ ac_testn() {
ac_ifcpp() {
expr=$1; shift
ac_testn "$@" <<-EOF
#include <unistd.h>
extern int thiswillneverbedefinedIhope(void);
int main(void) { return (
int main(void) { return (isatty(0) +
#$expr
0
#else
@ -398,7 +399,8 @@ ac_flags() {
else
ac_testn can_$vn '' "$ft" <<-'EOF'
/* evil apo'stroph in comment test */
int main(void) { return (0); }
#include <unistd.h>
int main(void) { return (isatty(0)); }
EOF
fi
eval fv=\$HAVE_CAN_`upper $vn`
@ -438,19 +440,14 @@ ac_header() {
esac
done
echo "#include <$hf>" >>x
echo 'int main(void) { return (0); }' >>x
echo '#include <unistd.h>' >>x
echo 'int main(void) { return (isatty(0)); }' >>x
ac_testn "$hv" "" "<$hf>" <x
rmf x
test 1 = $na || ac_cppflags
}
addsrcs() {
addsrcs_s=0
if test x"$1" = x"-s"; then
# optstatic
addsrcs_s=1
shift
fi
if test x"$1" = x"!"; then
fr=0
shift
@ -458,13 +455,6 @@ addsrcs() {
fr=1
fi
eval i=\$$1
if test $addsrcs_s = 1; then
if test -f "$2" || test -f "$srcdir/$2"; then
# always add $2, since it exists
fr=1
i=1
fi
fi
test $fr = "$i" && case " $SRCS " in
*\ $2\ *) ;;
*) SRCS="$SRCS $2" ;;
@ -1069,7 +1059,10 @@ vv ']' "$CPP $CFLAGS $CPPFLAGS $NOWARN conftest.c | \
sed 's/^/[ /' x
eval `cat x`
rmf x vv.out
echo 'int main(void) { return (0); }' >conftest.c
cat >conftest.c <<'EOF'
#include <unistd.h>
int main(void) { return (isatty(0)); }
EOF
case $ct in
ack)
# work around "the famous ACK const bug"
@ -1255,13 +1248,15 @@ if ac_ifcpp 'if 0' compiler_fails '' \
dec)
CFLAGS="$CFLAGS ${ccpl}-non_shared"
ac_testn can_delexe compiler_fails 0 'for the -non_shared linker option' <<-EOF
int main(void) { return (0); }
#include <unistd.h>
int main(void) { return (isatty(0)); }
EOF
;;
dmc)
CFLAGS="$CFLAGS ${ccpl}/DELEXECUTABLE"
ac_testn can_delexe compiler_fails 0 'for the /DELEXECUTABLE linker option' <<-EOF
int main(void) { return (0); }
#include <unistd.h>
int main(void) { return (isatty(0)); }
EOF
;;
*)
@ -1357,7 +1352,8 @@ kencc|tcc|tendra)
;;
sunpro)
cat >x <<-'EOF'
int main(void) { return (0); }
#include <unistd.h>
int main(void) { return (isatty(0)); }
#define __IDSTRING_CONCAT(l,p) __LINTED__ ## l ## _ ## p
#define __IDSTRING_EXPAND(l,p) __IDSTRING_CONCAT(l,p)
#define pad void __IDSTRING_EXPAND(__LINE__,x)(void) { }
@ -1560,14 +1556,29 @@ ac_test attribute_noreturn '' 'for __attribute__((__noreturn__))' <<-'EOF'
void fnord(void) { exit(0); }
#endif
EOF
ac_test attribute_pure '' 'for __attribute__((__pure__))' <<-'EOF'
#if defined(__TenDRA__) || (defined(__GNUC__) && (__GNUC__ < 2))
extern int thiswillneverbedefinedIhope(void);
/* force a failure: TenDRA and gcc 1.42 have false positive here */
int main(void) { return (thiswillneverbedefinedIhope()); }
#else
#include <unistd.h>
#undef __attribute__
int foo(const char *) __attribute__((__pure__));
int main(int ac, char **av) { return (foo(av[ac - 1]) + isatty(0)); }
int foo(const char *s) { return ((int)s[0]); }
#endif
EOF
ac_test attribute_unused '' 'for __attribute__((__unused__))' <<-'EOF'
#if defined(__TenDRA__) || (defined(__GNUC__) && (__GNUC__ < 2))
extern int thiswillneverbedefinedIhope(void);
/* force a failure: TenDRA and gcc 1.42 have false positive here */
int main(void) { return (thiswillneverbedefinedIhope()); }
#else
#include <unistd.h>
#undef __attribute__
int main(int ac __attribute__((__unused__)), char **av
__attribute__((__unused__))) { return (0); }
__attribute__((__unused__))) { return (isatty(0)); }
#endif
EOF
ac_test attribute_used '' 'for __attribute__((__used__))' <<-'EOF'
@ -1576,8 +1587,10 @@ ac_test attribute_used '' 'for __attribute__((__used__))' <<-'EOF'
/* force a failure: TenDRA and gcc 1.42 have false positive here */
int main(void) { return (thiswillneverbedefinedIhope()); }
#else
#include <unistd.h>
#undef __attribute__
static const char fnord[] __attribute__((__used__)) = "42";
int main(void) { return (0); }
int main(void) { return (isatty(0)); }
#endif
EOF
@ -1629,7 +1642,8 @@ ac_test both_time_h '' 'whether <sys/time.h> and <time.h> can both be included'
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
int main(void) { struct tm tm; return ((int)sizeof(tm)); }
#include <unistd.h>
int main(void) { struct tm tm; return ((int)sizeof(tm) + isatty(0)); }
EOF
ac_header sys/bsdtypes.h
ac_header sys/file.h sys/types.h
@ -1655,11 +1669,12 @@ ac_header values.h
# Environment: definitions
#
echo '#include <sys/types.h>
#include <unistd.h>
/* check that off_t can represent 2^63-1 correctly, thx FSF */
#define LARGE_OFF_T (((off_t)1 << 62) - 1 + ((off_t)1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 &&
LARGE_OFF_T % 2147483647 == 1) ? 1 : -1];
int main(void) { return (0); }' >lft.c
int main(void) { return (isatty(0)); }' >lft.c
ac_testn can_lfs '' "for large file support" <lft.c
save_CPPFLAGS=$CPPFLAGS
add_cppflags -D_FILE_OFFSET_BITS=64
@ -1710,7 +1725,7 @@ ac_test rlim_t <<-'EOF'
#include <sys/resource.h>
#endif
#include <unistd.h>
int main(void) { return ((int)(rlim_t)0); }
int main(void) { return (((int)(rlim_t)0) + isatty(0)); }
EOF
# only testn: added later below
@ -1762,8 +1777,8 @@ else
#define EXTERN
#define MKSH_INCLUDES_ONLY
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.654 2013/12/02 19:47:33 tg Exp $");
int main(void) { printf("Hello, World!\n"); return (0); }
__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.655 2014/01/05 21:57:21 tg Exp $");
int main(void) { printf("Hello, World!\n"); return (isatty(0)); }
EOF
case $cm in
llvm)
@ -1802,12 +1817,14 @@ test x"NetBSD" = x"$TARGET_OS" && $e Ignore the compatibility warning.
ac_testn sys_errlist '' "the sys_errlist[] array and sys_nerr" <<-'EOF'
extern const int sys_nerr;
extern const char * const sys_errlist[];
int main(void) { return (*sys_errlist[sys_nerr - 1]); }
extern int isatty(int);
int main(void) { return (*sys_errlist[sys_nerr - 1] + isatty(0)); }
EOF
ac_testn _sys_errlist '!' sys_errlist 0 "the _sys_errlist[] array and _sys_nerr" <<-'EOF'
extern const int _sys_nerr;
extern const char * const _sys_errlist[];
int main(void) { return (*_sys_errlist[_sys_nerr - 1]); }
extern int isatty(int);
int main(void) { return (*_sys_errlist[_sys_nerr - 1] + isatty(0)); }
EOF
if test 1 = "$HAVE__SYS_ERRLIST"; then
add_cppflags -Dsys_nerr=_sys_nerr
@ -1820,11 +1837,13 @@ for what in name list; do
uwhat=`upper $what`
ac_testn sys_sig$what '' "the sys_sig${what}[] array" <<-EOF
extern const char * const sys_sig${what}[];
int main(void) { return (sys_sig${what}[0][0]); }
extern int isatty(int);
int main(void) { return (sys_sig${what}[0][0] + isatty(0)); }
EOF
ac_testn _sys_sig$what '!' sys_sig$what 0 "the _sys_sig${what}[] array" <<-EOF
extern const char * const _sys_sig${what}[];
int main(void) { return (_sys_sig${what}[0][0]); }
extern int isatty(int);
int main(void) { return (_sys_sig${what}[0][0] + isatty(0)); }
EOF
eval uwhat_v=\$HAVE__SYS_SIG$uwhat
if test 1 = "$uwhat_v"; then
@ -1891,7 +1910,7 @@ ac_test memmove <<-'EOF'
#include <strings.h>
#endif
int main(int ac, char *av[]) {
return (*(int *)(void *)memmove(av[0], av[1], ac));
return (*(int *)(void *)memmove(av[0], av[1], (size_t)ac));
}
EOF
@ -2063,12 +2082,12 @@ EOF
ac_test sys_errlist_decl sys_errlist 0 "for declaration of sys_errlist[] and sys_nerr" <<-'EOF'
#define MKSH_INCLUDES_ONLY
#include "sh.h"
int main(void) { return (*sys_errlist[sys_nerr - 1]); }
int main(void) { return (*sys_errlist[sys_nerr - 1] + isatty(0)); }
EOF
ac_test sys_siglist_decl sys_siglist 0 'for declaration of sys_siglist[]' <<-'EOF'
#define MKSH_INCLUDES_ONLY
#include "sh.h"
int main(void) { return (sys_siglist[0][0]); }
int main(void) { return (sys_siglist[0][0] + isatty(0)); }
EOF
#
@ -2139,7 +2158,7 @@ cta(ptr_fits_in_long, sizeof(ptrdiff_t) <= sizeof(long));
char padding[64 - NUM];
};
char ctasserts_dblcheck[sizeof(struct ctasserts) == 64 ? 1 : -1];
int main(void) { return (sizeof(ctasserts_dblcheck)); }
int main(void) { return (sizeof(ctasserts_dblcheck) + isatty(0)); }
EOF
CFLAGS=$save_CFLAGS
eval test 1 = \$HAVE_COMPILE_TIME_ASSERTS_$$ || exit 1
@ -2277,12 +2296,11 @@ mksh_cfg= NSIG
$e done.
fi
addsrcs -s '!' HAVE_STRLCPY strlcpy.c
addsrcs '!' HAVE_STRLCPY strlcpy.c
addsrcs USE_PRINTF_BUILTIN printf.c
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
test -n "$LDSTATIC" && add_cppflags -DMKSH_OPTSTATIC
add_cppflags -DMKSH_BUILD_R=489
add_cppflags -DMKSH_BUILD_R=491
$e $bi$me: Finished configuration testing, now producing output.$ao

View File

@ -1,7 +1,7 @@
# $MirOS: src/bin/mksh/Makefile,v 1.130 2013/11/30 17:41:32 tg Exp $
# $MirOS: src/bin/mksh/Makefile,v 1.131 2014/01/05 21:57:22 tg Exp $
#-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013
# 2011, 2012, 2013, 2014
# Thorsten Glaser <tg@mirbsd.org>
#
# Provided that these terms and disclaimer and all copyright notices
@ -34,10 +34,11 @@ SRCS= edit.c eval.c exec.c expr.c funcs.c histrap.c jobs.c \
.if !make(test-build)
CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
-DHAVE_ATTRIBUTE_BOUNDED=1 -DHAVE_ATTRIBUTE_FORMAT=1 \
-DHAVE_ATTRIBUTE_NORETURN=1 -DHAVE_ATTRIBUTE_UNUSED=1 \
-DHAVE_ATTRIBUTE_USED=1 -DHAVE_SYS_TIME_H=1 -DHAVE_TIME_H=1 \
-DHAVE_BOTH_TIME_H=1 -DHAVE_SYS_BSDTYPES_H=0 \
-DHAVE_SYS_FILE_H=1 -DHAVE_SYS_MKDEV_H=0 -DHAVE_SYS_MMAN_H=1 \
-DHAVE_ATTRIBUTE_NORETURN=1 -DHAVE_ATTRIBUTE_PURE=1 \
-DHAVE_ATTRIBUTE_UNUSED=1 -DHAVE_ATTRIBUTE_USED=1 \
-DHAVE_SYS_TIME_H=1 -DHAVE_TIME_H=1 -DHAVE_BOTH_TIME_H=1 \
-DHAVE_SYS_BSDTYPES_H=0 -DHAVE_SYS_FILE_H=1 \
-DHAVE_SYS_MKDEV_H=0 -DHAVE_SYS_MMAN_H=1 \
-DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_RESOURCE_H=1 \
-DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_SYSMACROS_H=0 \
-DHAVE_BSTRING_H=0 -DHAVE_GRP_H=1 -DHAVE_LIBGEN_H=1 \
@ -54,7 +55,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
-DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \
-DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
-DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=489
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=491
CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U}
CPPFLAGS+= -I.
COPTS+= -std=c99 -Wall

16
check.t
View File

@ -1,8 +1,8 @@
# $MirOS: src/bin/mksh/check.t,v 1.638 2013/12/15 15:45:31 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.639 2014/01/05 21:57:22 tg Exp $
# OpenBSD src/regress/bin/ksh updated: 2013/12/02 20:39:44
#-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013
# 2011, 2012, 2013, 2014
# Thorsten Glaser <tg@mirbsd.org>
#
# Provided that these terms and disclaimer and all copyright notices
@ -27,7 +27,7 @@
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout:
@(#)MIRBSD KSH R48 2013/11/30
@(#)MIRBSD KSH R49 2014/01/05
description:
Check version of shell.
stdin:
@ -36,7 +36,7 @@ name: KSH_VERSION
category: shell:legacy-no
---
expected-stdout:
@(#)LEGACY KSH R48 2013/11/30
@(#)LEGACY KSH R49 2014/01/05
description:
Check version of legacy shell.
stdin:
@ -1636,6 +1636,14 @@ expected-stdout:
1=02.
2=02.
---
name: expand-number-1
description:
Check that positional arguments do not overflow
stdin:
echo "1 ${12345678901234567890} ."
expected-stdout:
1 .
---
name: eglob-bad-1
description:
Check that globbing isn't done when glob has syntax error

19
edit.c
View File

@ -5,7 +5,7 @@
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013
* 2011, 2012, 2013, 2014
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -28,7 +28,7 @@
#ifndef MKSH_NO_CMDLINE_EDITING
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.274 2014/01/05 19:11:43 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.275 2014/01/05 21:57:24 tg Exp $");
/*
* in later versions we might use libtermcap for this, but since external
@ -961,7 +961,7 @@ static void x_delete(size_t, bool);
static size_t x_bword(void);
static size_t x_fword(bool);
static void x_goto(char *);
static char *x_bs0(char *, char *);
static char *x_bs0(char *, char *) MKSH_A_PURE;
static void x_bs3(char **);
static int x_size_str(char *);
static int x_size2(char *, char **);
@ -990,7 +990,7 @@ static int x_fold_case(int);
#endif
static char *x_lastcp(void);
static void do_complete(int, Comp_type);
static size_t x_nb2nc(size_t);
static size_t x_nb2nc(size_t) MKSH_A_PURE;
static int unget_char = -1;
@ -3353,7 +3353,7 @@ static void save_cbuf(void);
static void restore_cbuf(void);
static int putbuf(const char *, ssize_t, bool);
static void del_range(int, int);
static int findch(int, int, bool, bool);
static int findch(int, int, bool, bool) MKSH_A_PURE;
static int forwword(int);
static int backword(int);
static int endword(int);
@ -3763,10 +3763,10 @@ vi_hook(int ch)
refresh(0);
return (0);
} else if (ch == edchars.werase) {
int i, n = srchlen;
unsigned int i, n;
struct edstate new_es, *save_es;
new_es.cursor = n;
new_es.cursor = srchlen;
new_es.cbuf = locpat;
save_es = es;
@ -3774,9 +3774,10 @@ vi_hook(int ch)
n = backword(1);
es = save_es;
for (i = srchlen; --i >= n; )
i = (unsigned)srchlen;
while (--i >= n)
es->linelen -= char_len(locpat[i]);
srchlen = n;
srchlen = (int)n;
es->cursor = es->linelen;
refresh(0);
return (0);

6
eval.c
View File

@ -2,7 +2,7 @@
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013
* 2011, 2012, 2013, 2014
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.145 2013/11/30 00:20:47 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.146 2014/01/05 21:57:25 tg Exp $");
/*
* string expansion
@ -74,7 +74,7 @@ static const char *maybe_expand_tilde(const char *, XString *, char **, int);
static char *homedir(char *);
#endif
static void alt_expand(XPtrV *, char *, char *, char *, int);
static int utflen(const char *);
static int utflen(const char *) MKSH_A_PURE;
static void utfincptr(const char *, mksh_ari_t *);
/* UTFMODE functions */

8
exec.c
View File

@ -2,7 +2,7 @@
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013
* 2011, 2012, 2013, 2014
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.127 2013/10/09 11:59:27 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.128 2014/01/05 21:57:25 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@ -884,14 +884,14 @@ scriptexec(struct op *tp, const char **ap)
fd = (char *)cp - buf; /* either 0 or (if BOM) 3 */
/* scan for newline (or CR) or NUL _before_ end of buffer */
while ((char *)cp < (buf + sizeof(buf)))
while ((size_t)((char *)cp - buf) < sizeof(buf))
if (*cp == '\0' || *cp == '\n' || *cp == '\r') {
*cp = '\0';
break;
} else
++cp;
/* if the shebang line is longer than MAXINTERP, bail out */
if ((char *)cp >= (buf + sizeof(buf)))
if ((size_t)((char *)cp - buf) >= sizeof(buf))
goto noshebang;
/* restore begin of shebang position (buf+0 or buf+3) */

8
expr.c
View File

@ -2,7 +2,7 @@
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013
* 2011, 2012, 2013, 2014
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.74 2014/01/05 19:11:44 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.75 2014/01/05 21:57:26 tg Exp $");
/* the order of these enums is constrained by the order of opinfo[] */
enum token {
@ -916,7 +916,6 @@ ksh_access(const char *fn, int mode)
return (rv);
}
#ifndef MKSH_mirbsd_wcwidth
/* From: X11/xc/programs/xterm/wcwidth.c,v 1.7 2013/11/30 23:20:03 tg Exp $ */
struct mb_ucsrange {
@ -925,7 +924,7 @@ struct mb_ucsrange {
};
static int mb_ucsbsearch(const struct mb_ucsrange arr[], size_t elems,
unsigned int val);
unsigned int val) MKSH_A_PURE;
/*
* Generated by MirOS: contrib/code/Snippets/eawparse,v 1.2 2013/11/30 13:45:17 tg Exp $
@ -1190,4 +1189,3 @@ utf_wcwidth(unsigned int wc)
return (2);
return (1);
}
#endif

9
main.c
View File

@ -5,7 +5,7 @@
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013
* 2011, 2012, 2013, 2014
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -34,7 +34,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.274 2014/01/05 19:11:45 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.275 2014/01/05 21:57:26 tg Exp $");
extern char **environ;
@ -48,7 +48,6 @@ extern char **environ;
static uint8_t isuc(const char *);
static int main_init(int, const char *[], Source **, struct block **);
uint32_t chvt_rndsetup(const void *, size_t);
void chvt_reinit(void);
static void reclaim(void);
static void remove_temps(struct temp *);
@ -542,11 +541,13 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
#ifndef MKSH_ASSUME_UTF8
/* auto-detect from locale or environment */
utf_flag = 4;
#elif MKSH_ASSUME_UTF8
#else /* this may not be an #elif */
#if MKSH_ASSUME_UTF8
utf_flag = 1;
#else
/* always disable UTF-8 (for interactive) */
utf_flag = 0;
#endif
#endif
}
#ifndef MKSH_NO_CMDLINE_EDITING

12
misc.c
View File

@ -3,7 +3,7 @@
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013
* 2011, 2012, 2013, 2014
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -30,7 +30,7 @@
#include <grp.h>
#endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.218 2013/11/30 17:33:50 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.219 2014/01/05 21:57:27 tg Exp $");
#define KSH_CHVT_FLAG
#ifdef MKSH_SMALL
@ -49,10 +49,11 @@ __RCSID("$MirOS: src/bin/mksh/misc.c,v 1.218 2013/11/30 17:33:50 tg Exp $");
unsigned char chtypes[UCHAR_MAX + 1];
static const unsigned char *pat_scan(const unsigned char *,
const unsigned char *, bool);
const unsigned char *, bool) MKSH_A_PURE;
static int do_gmatch(const unsigned char *, const unsigned char *,
const unsigned char *, const unsigned char *);
static const unsigned char *cclass(const unsigned char *, unsigned char);
const unsigned char *, const unsigned char *) MKSH_A_PURE;
static const unsigned char *cclass(const unsigned char *, unsigned char)
MKSH_A_PURE;
#ifdef KSH_CHVT_CODE
static void chvt(const Getopt *);
#endif
@ -1952,7 +1953,6 @@ c_cd(const char **wp)
#ifdef KSH_CHVT_CODE
extern uint32_t chvt_rndsetup(const void *, size_t);
extern void chvt_reinit(void);
static void

10
mksh.1
View File

@ -1,8 +1,8 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.327 2014/01/05 19:14:16 tg Exp $
.\" $MirOS: src/bin/mksh/mksh.1,v 1.328 2014/01/05 21:57:27 tg Exp $
.\" $OpenBSD: ksh.1,v 1.149 2013/12/18 13:53:11 millert Exp $
.\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
.\" 2010, 2011, 2012, 2013
.\" 2010, 2011, 2012, 2013, 2014
.\" Thorsten Glaser <tg@mirbsd.org>
.\"
.\" Provided that these terms and disclaimer and all copyright notices
@ -371,7 +371,9 @@ The suid profile probably should run
.Ic set +p
unless the shell was explicitly started with
.Fl p .
This isn't easily implemented but a stopgap measure for:
This isn't easily implemented but
.Pq just always run Ic set +p
a stopgap measure for:
.Pa http://blog.cmpxchg8b.com/2013/08/security\-debianisms.html
.Ss Command syntax
The shell begins parsing its input by removing any backslash-newline
@ -6447,7 +6449,7 @@ $ /bin/sleep 666 && echo fubar
.Ed
.Pp
This document attempts to describe
.Nm mksh\ R48+CVS
.Nm mksh\ R49
and up,
compiled without any options impacting functionality, such as
.Dv MKSH_SMALL ,

60
sh.h
View File

@ -10,7 +10,7 @@
/*-
* Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013
* 2011, 2012, 2013, 2014
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -122,6 +122,11 @@
#else
#define MKSH_A_NORETURN /* nothing */
#endif
#if HAVE_ATTRIBUTE_PURE
#define MKSH_A_PURE __attribute__((__pure__))
#else
#define MKSH_A_PURE /* nothing */
#endif
#if HAVE_ATTRIBUTE_UNUSED
#define MKSH_A_UNUSED __attribute__((__unused__))
#else
@ -164,9 +169,9 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.681 2014/01/05 19:14:17 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.682 2014/01/05 21:57:28 tg Exp $");
#endif
#define MKSH_VERSION "R48 2013/11/30"
#define MKSH_VERSION "R49 2014/01/05"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -298,7 +303,7 @@ struct rusage {
#define ksh_isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
#define ksh_tolower(c) (((c) >= 'A') && ((c) <= 'Z') ? (c) - 'A' + 'a' : (c))
#define ksh_toupper(c) (((c) >= 'a') && ((c) <= 'z') ? (c) - 'a' + 'A' : (c))
#define ksh_isdash(s) (((s) != NULL) && ((s)[0] == '-') && ((s)[1] == '\0'))
#define ksh_isdash(s) (((s)[0] == '-') && ((s)[1] == '\0'))
#define ksh_isspace(c) ((((c) >= 0x09) && ((c) <= 0x0D)) || ((c) == 0x20))
#define ksh_min(x,y) ((x) < (y) ? (x) : (y))
#define ksh_max(x,y) ((x) > (y) ? (x) : (y))
@ -422,14 +427,6 @@ extern int __cdecl setegid(gid_t);
#define ISTRIP 0
#endif
/* remove redundancies */
#if defined(MirBSD) && (MirBSD >= 0x0AB5) && !defined(MKSH_OPTSTATIC)
#define MKSH_mirbsd_wcwidth
#define utf_wcwidth(i) wcwidth((__WCHAR_TYPE__)i)
extern int wcwidth(__WCHAR_TYPE__);
#endif
/* some useful #defines */
#ifdef EXTERN
@ -526,7 +523,7 @@ char *ucstrstr(char *, const char *);
#define mkssert(e) do { } while (/* CONSTCOND */ 0)
#endif
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 489)
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 491)
#error Must run Build.sh to compile this.
extern void thiswillneverbedefinedIhope(void);
int
@ -1434,7 +1431,7 @@ typedef char *XStringP;
#define XcheckN(xs, xp, n) do { \
ssize_t more = ((xp) + (n)) - (xs).end; \
if (more > 0) \
(xp) = Xcheck_grow(&(xs), (xp), more); \
(xp) = Xcheck_grow(&(xs), (xp), (size_t)more); \
} while (/* CONSTCOND */ 0)
/* check for overflow, expand string */
@ -1715,12 +1712,10 @@ int v_evaluate(struct tbl *, const char *, volatile int, bool);
size_t utf_mbtowc(unsigned int *, const char *);
size_t utf_wctomb(char *, unsigned int);
int utf_widthadj(const char *, const char **);
size_t utf_mbswidth(const char *);
const char *utf_skipcols(const char *, int);
size_t utf_ptradj(const char *);
#ifndef MKSH_mirbsd_wcwidth
int utf_wcwidth(unsigned int);
#endif
size_t utf_mbswidth(const char *) MKSH_A_PURE;
const char *utf_skipcols(const char *, int) MKSH_A_PURE;
size_t utf_ptradj(const char *) MKSH_A_PURE;
int utf_wcwidth(unsigned int) MKSH_A_PURE;
int ksh_access(const char *, int);
struct tbl *tempvar(void);
/* funcs.c */
@ -1788,10 +1783,10 @@ void sethistsize(mksh_ari_t);
void sethistfile(const char *);
#endif
#if !defined(MKSH_NO_CMDLINE_EDITING) && !MKSH_S_NOVI
char **histpos(void);
char **histpos(void) MKSH_A_PURE;
int histnum(int);
#endif
int findhist(int, int, const char *, bool);
int findhist(int, int, const char *, bool) MKSH_A_PURE;
char **hist_get_newest(bool);
void inittraps(void);
void alarm_init(void);
@ -1904,18 +1899,19 @@ struct tbl **ktsort(struct table *);
void DF(const char *, ...)
MKSH_A_FORMAT(__printf__, 1, 2);
#endif
uint32_t chvt_rndsetup(const void *, size_t) MKSH_A_PURE;
/* misc.c */
void setctypes(const char *, int);
void initctypes(void);
size_t option(const char *);
size_t option(const char *) MKSH_A_PURE;
char *getoptions(void);
void change_flag(enum sh_flag, int, bool);
void change_xtrace(unsigned char, bool);
int parse_args(const char **, int, bool *);
int getn(const char *, int *);
int gmatchx(const char *, const char *, bool);
int has_globbing(const char *, const char *);
int xstrcmp(const void *, const void *);
int has_globbing(const char *, const char *) MKSH_A_PURE;
int xstrcmp(const void *, const void *) MKSH_A_PURE;
void ksh_getopt_reset(Getopt *, int);
int ksh_getopt(const char **, Getopt *, const char *);
void print_value_quoted(struct shf *, const char *);
@ -2007,17 +2003,17 @@ void setint(struct tbl *, mksh_ari_t);
void setint_n(struct tbl *, mksh_ari_t, int);
struct tbl *typeset(const char *, uint32_t, uint32_t, int, int);
void unset(struct tbl *, int);
const char *skip_varname(const char *, int);
const char *skip_wdvarname(const char *, bool);
int is_wdvarname(const char *, bool);
int is_wdvarassign(const char *);
const char *skip_varname(const char *, int) MKSH_A_PURE;
const char *skip_wdvarname(const char *, bool) MKSH_A_PURE;
int is_wdvarname(const char *, bool) MKSH_A_PURE;
int is_wdvarassign(const char *) MKSH_A_PURE;
struct tbl *arraysearch(struct tbl *, uint32_t);
char **makenv(void);
void change_winsz(void);
size_t array_ref_len(const char *);
size_t array_ref_len(const char *) MKSH_A_PURE;
char *arrayname(const char *);
mksh_uari_t set_array(const char *, bool, const char **);
uint32_t hash(const void *);
uint32_t hash(const void *) MKSH_A_PURE;
mksh_ari_t rndget(void);
void rndset(unsigned long);
@ -2070,7 +2066,7 @@ typedef struct test_env {
extern const char * const dbtest_tokens[];
Test_op test_isop(Test_meta, const char *);
Test_op test_isop(Test_meta, const char *) MKSH_A_PURE;
int test_eval(Test_env *, Test_op, const char *, const char *, bool);
int test_parse(Test_env *);

6
syn.c
View File

@ -2,7 +2,7 @@
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009,
* 2011, 2012, 2013
* 2011, 2012, 2013, 2014
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.93 2013/09/10 16:30:50 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.94 2014/01/05 21:57:29 tg Exp $");
struct nesting_state {
int start_token; /* token than began nesting (eg, FOR) */
@ -59,7 +59,7 @@ static void syntaxerr(const char *) MKSH_A_NORETURN;
static void nesting_push(struct nesting_state *, int);
static void nesting_pop(struct nesting_state *);
static int assign_command(const char *);
static int inalias(struct source *);
static int inalias(struct source *) MKSH_A_PURE;
static Test_op dbtestp_isa(Test_env *, Test_meta);
static const char *dbtestp_getopnd(Test_env *, Test_op, bool);
static int dbtestp_eval(Test_env *, Test_op, const char *,

8
var.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: var.c,v 1.37 2013/12/18 13:53:12 millert Exp $ */
/* $OpenBSD: var.c,v 1.38 2013/12/20 17:53:09 zhuk Exp $ */
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -27,7 +27,7 @@
#include <sys/sysctl.h>
#endif
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.175 2014/01/05 19:14:18 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.176 2014/01/05 21:57:29 tg Exp $");
/*-
* Variables
@ -238,9 +238,7 @@ global(const char *n)
vp->areap = ATEMP;
*vp->name = c;
if (ksh_isdigit(c)) {
for (c = 0; ksh_isdigit(*n); n++)
c = (c * 10) + (*n - '0');
if (c <= l->argc)
if (getn(n, &c) && (c <= l->argc))
/* setstr can't fail here */
setstr(vp, l->argv[c], KSH_RETURN_ERROR);
vp->flag |= RDONLY;