Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ This documents significant changes in the dev branch of ksh 93u+m.
For full details, see the git log at: https://github.com/ksh93/ksh
Uppercase BUG_* IDs are shell bug IDs as used by the Modernish shell library.

2025-06-16:

- Fixed a possible out of bounds crash that could occur when running
a POSIX function (aka a function of the form 'name() {').

2025-06-14:

- Fixed a bug occurring on systems with posix_spawn(3), spawnve(2), and
Expand Down
87 changes: 41 additions & 46 deletions src/cmd/ksh93/bltins/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@
#include <times.h>
#endif

#define DOTMAX MAXDEPTH /* maximum level of . nesting */

/*
* Handler function for nv_scan() that unsets a variable's export attribute
*/
Expand Down Expand Up @@ -232,16 +230,15 @@ int b_eval(int argc,char *argv[], Shbltin_t *context)
#endif
int b_dot_cmd(int n,char *argv[],Shbltin_t *context)
{
char *script;
Namval_t *np;
int jmpval;
struct sh_scoped savst, *prevscope = sh.st.self;
char *filename=0, *buffer=0, *tofree;
int fd;
struct dolnod *saveargfor;
volatile struct dolnod *argsave=0;
struct checkpt buff;
Sfio_t *iop=0;
char *script;
Namval_t *np;
int jmpval, fd;
struct sh_scoped savst, *prevscope = sh.st.self;
char *filename=0, *buffer=0, *tofree;
struct dolnod *saveargfor;
volatile struct dolnod *argsave=0;
struct checkpt buff;
Sfio_t *iop=0;
while (n = optget(argv,sh_optdot)) switch (n)
{
case ':':
Expand All @@ -259,61 +256,55 @@ int b_dot_cmd(int n,char *argv[],Shbltin_t *context)
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NULL));
UNREACHABLE();
}
if(sh.dot_depth >= DOTMAX)
if(sh.dot_depth >= MAXDEPTH)
{
errormsg(SH_DICT,ERROR_exit(1),e_toodeep,script);
UNREACHABLE();
}
if(!(np=sh.posix_fun))
/* check for KornShell style function first */
np = nv_search(script,sh.fun_tree,0);
if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX) && !(sh_isoption(SH_POSIX) && context->bnode==SYSDOT))
{
/* check for KornShell style function first */
np = nv_search(script,sh.fun_tree,0);
if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX) && !(sh_isoption(SH_POSIX) && context->bnode==SYSDOT))
if(!np->nvalue)
{
if(!np->nvalue)
path_search(script,NULL,0);
if(np->nvalue)
{
path_search(script,NULL,0);
if(np->nvalue)
{
if(nv_isattr(np,NV_FPOSIX))
np = 0;
}
else
{
errormsg(SH_DICT,ERROR_exit(1),e_found,script);
UNREACHABLE();
}
if(nv_isattr(np,NV_FPOSIX))
np = 0;
}
}
else
np = 0;
if(!np)
{
if((fd=path_open(script,path_get(script))) < 0)
else
{
errormsg(SH_DICT,ERROR_system(1),e_open,script);
errormsg(SH_DICT,ERROR_exit(1),e_found,script);
UNREACHABLE();
}
filename = path_fullname(stkptr(sh.stk,PATH_OFFSET));
}
}
else
np = 0;
if(!np)
{
/* open the dot script */
if((fd=path_open(script,path_get(script))) < 0)
{
errormsg(SH_DICT,ERROR_system(1),e_open,script);
UNREACHABLE();
}
filename = path_fullname(stkptr(sh.stk,PATH_OFFSET));
}
*prevscope = sh.st;
sh.st.lineno = np?((struct functnod*)nv_funtree(np))->functline:1;
sh.st.lineno = np ? ((struct functnod*)nv_funtree(np))->functline : 1;
sh.st.save_tree = sh.var_tree;
if(filename)
{
sh.st.filename = filename;
sh.st.lineno = 1;
}
sh.st.prevst = prevscope;
sh.st.self = &savst;
sh.topscope = (Shscope_t*)sh.st.self;
prevscope->save_tree = sh.var_tree;
tofree = sh.st.filename;
if(np)
sh.st.filename = ((struct Ufunction*)np->nvalue)->fname;
nv_putval(SH_PATHNAMENOD, sh.st.filename ,NV_NOFREE);
sh.posix_fun = 0;
nv_putval(SH_PATHNAMENOD,sh.st.filename,NV_NOFREE);
if(np || argv[1])
argsave = sh_argnew(argv,&saveargfor);
sh_pushcontext(&buff,SH_JMPDOT);
Expand All @@ -325,9 +316,13 @@ int b_dot_cmd(int n,char *argv[],Shbltin_t *context)
sh.dot_depth++;
update_sh_level();
if(np)
{
/* execute the function as though it were a dot script */
sh_exec((Shnode_t*)(nv_funtree(np)),sh_isstate(SH_ERREXIT));
}
else
{
/* run the dot script */
buffer = sh_malloc(IOBSIZE+1);
iop = sfnew(NULL,buffer,IOBSIZE,fd,SFIO_READ);
sh_offstate(SH_NOFORK);
Expand All @@ -348,12 +343,12 @@ int b_dot_cmd(int n,char *argv[],Shbltin_t *context)
prevscope->dolc = sh.st.dolc;
prevscope->dolv = sh.st.dolv;
}
if (sh.st.self != &savst)
if(sh.st.self != &savst)
*sh.st.self = sh.st;
/* only restore the top Shscope_t portion for POSIX functions */
/* only restore the top Shscope_t portion for functions */
memcpy(&sh.st, prevscope, sizeof(Shscope_t));
sh.topscope = (Shscope_t*)prevscope;
nv_putval(SH_PATHNAMENOD, sh.st.filename ,NV_NOFREE);
nv_putval(SH_PATHNAMENOD,sh.st.filename,NV_NOFREE);
if(jmpval && jmpval!=SH_JMPFUN)
siglongjmp(*sh.jmplist,jmpval);
return sh.exitval;
Expand Down
Loading