Skip to content

Commit

Permalink
Merge branch 'dev' into fix-tmout-overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
McDutchie authored Feb 23, 2024
2 parents 968b133 + 6d00caf commit dc11338
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 28 deletions.
5 changes: 5 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ Uppercase BUG_* IDs are shell bug IDs as used by the Modernish shell library.
- Fixed a crash that occurred when starting ksh with no TERM variable in the
environment (e.g., in single user mode on NetBSD and DragonFlyBSD).

- Fixed a regression of 'return' within traps, reintroduced on 2023-12-25
after being fixed on 2020-09-09. The regression caused a 'return' or
'exit' with no arguments to assume the before-trap exit status instead of
that of the last-run command. This broke the shipped 'autocd' function.

- Fixed some integer overflows that could occur when using TMOUT.

2024-02-17:
Expand Down
7 changes: 5 additions & 2 deletions src/cmd/ksh93/bltins/cflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ int b_return(int n, char *argv[],Shbltin_t *context)
int r;
intmax_t l = strtoll(*argv, NULL, 10);
if(do_exit)
{
n = (int)(l & SH_EXITMASK); /* exit: apply bitmask before conversion to avoid undefined int overflow */
if (sh.intrap)
sh.intrap_exit_n = 1;
}
else if(r = (int)l, l != (intmax_t)r) /* return: convert to int and check for overflow (should be safe enough) */
{
errormsg(SH_DICT,ERROR_warn(0),"%s: out of range",*argv);
Expand All @@ -79,8 +83,7 @@ int b_return(int n, char *argv[],Shbltin_t *context)
}
else
{
/* no argument: pass down $? (but in a trap action, pass down the pre-trap $?) */
n = sh.intrap ? sh.oldexit : sh.savexit;
n = sh.savexit; /* no argument: pass down $? */
if(do_exit)
n &= SH_EXITMASK;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,6 @@ struct Shell_s
char *comdiv; /* points to sh -c argument */
char *prefix; /* prefix for compound assignment */
sigjmp_buf *jmplist; /* longjmp return stack */
int oldexit; /* saves pre-trap exit status for 'exit' default in trap actions */
pid_t bckpid; /* background process id */
pid_t cpid;
pid_t spid; /* subshell process id */
Expand All @@ -312,6 +311,7 @@ struct Shell_s
int savesig;
unsigned char *sigflag; /* pointer to signal states */
char intrap; /* set while executing a trap action */
char intrap_exit_n; /* set if 'exit n' within trap */
uint32_t srand_upper_bound;
char forked;
char binscript;
Expand Down
11 changes: 4 additions & 7 deletions src/cmd/ksh93/sh/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,11 +528,7 @@ int sh_trap(const char *trap, int mode)
if(jmpval==SH_JMPSCRIPT)
indone=0;
else
{
if(jmpval==SH_JMPEXIT)
savxit = sh.exitval;
jmpval=SH_JMPTRAP;
}
}
sh_popcontext(&buff);
/* re-allow last-command exec optimisation unless the command we executed set a trap */
Expand All @@ -541,8 +537,10 @@ int sh_trap(const char *trap, int mode)
sh.intrap--;
sfsync(sh.outpool);
savxit_return = sh.exitval;
if(jmpval!=SH_JMPEXIT && jmpval!=SH_JMPFUN)
sh.exitval=savxit;
if(sh.intrap_exit_n)
sh.intrap_exit_n = 0;
else
sh.exitval = savxit;
stkset(sh.stk,savptr,staktop);
fcrestore(&savefc);
if(was_history)
Expand Down Expand Up @@ -666,7 +664,6 @@ noreturn void sh_done(int sig)
if(t=sh.st.trapcom[0])
{
sh.st.trapcom[0]=0; /* should free but not long */
sh.oldexit = savxit;
sh_trap(t,0);
savxit = sh.exitval;
}
Expand Down
1 change: 0 additions & 1 deletion src/cmd/ksh93/sh/subshell.c
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,6 @@ Sfio_t *sh_subshell(Shnode_t *t, volatile int flags, int comsub)
/* trap on EXIT not handled by child */
char *trap=sh.st.trapcom[0];
sh.st.trapcom[0] = 0; /* prevent recursion */
sh.oldexit = sh.exitval;
sh_trap(trap,0);
free(trap);
}
Expand Down
2 changes: 0 additions & 2 deletions src/cmd/ksh93/sh/xec.c
Original file line number Diff line number Diff line change
Expand Up @@ -896,8 +896,6 @@ int sh_exec(const Shnode_t *t, int flags)
sh_offstate(SH_DEFPATH);
if(!(flags & sh_state(SH_ERREXIT)))
sh_offstate(SH_ERREXIT);
if(!sh.intrap)
sh.oldexit = sh.exitval;
sh.exitval=0;
sh.lastsig = 0;
sh.chldexitsig = 0;
Expand Down
15 changes: 0 additions & 15 deletions src/cmd/ksh93/tests/pty.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1322,20 +1322,5 @@ c \Ek
r ^:prompt: "\$SHELL" -o vi -c 'read -s "foo\?:prompt: "'$
!

((multiline && (SHOPT_VSH || SHOPT_ESH))) && TERM=vt100 tst $LINENO <<"!"
L crash when TERM is undefined
# https://github.com/ksh93/ksh/issues/722
d 40
p :test-1:
w unset TERM
p :test-2:
w "$SHELL"
p :test-3:
w print Exit status $?
r print
r ^Exit status 0\r\n$
!

# ======
exit $((Errors<125?Errors:125))
10 changes: 10 additions & 0 deletions src/cmd/ksh93/tests/return.sh
Original file line number Diff line number Diff line change
Expand Up @@ -269,5 +269,15 @@ then max=$(getconf INT_MAX) min=$(getconf INT_MIN) err=$tmp/stderr
"(expected status 128 and '', got status $e and $(printf %q "$(<$err)"))"
fi

# ======
# old AT&T bug reintroduced in v1.0.8 (commit aea99158)
f() { true; return; }
trap 'f; echo $? >out' USR1
(exit 13)
kill -s USR1 ${.sh.pid}
trap - USR1
unset -f f
[[ $(<out) == 0 ]] || err_exit "default return status in traps is broken (expected 0, got $(<out))"

# ======
exit $((Errors<125?Errors:125))

0 comments on commit dc11338

Please sign in to comment.