mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
autoload: Add loop detection
It was trivial to crash ksh by making an autoloaded function
definition file autoload itself, causing a stack overflow due to
infinite recursion. This commit adds loop detection that stops a
function that is being autoloaded from autoloading itself either
directly or indirectly, without removing the ability of autoloaded
function definition files to autoload other functions.
src/cmd/ksh93/sh/path.c: funload():
- Detect loops by checking if the path of a function to be
autoloaded was already added to a new internal static tree,
and if not, adding it while the function is being loaded.
src/cmd/ksh93/tests/path.sh:
- Add regression test.
- Tweak a couple of others to be freeze- and crash-proof.
NEWS:
- Add this fix + a forgotten entry for the previous fix (6f3b23e6).
Fixes: https://github.com/ksh93/ksh/issues/136
This commit is contained in:
parent
6f3b23e6f4
commit
a410bc480f
2 changed files with 55 additions and 5 deletions
|
|
@ -577,7 +577,8 @@ char *path_fullname(Shell_t *shp,const char *name)
|
|||
static void funload(Shell_t *shp,int fno, const char *name)
|
||||
{
|
||||
char *pname,*oldname=shp->st.filename, buff[IOBSIZE+1];
|
||||
Namval_t *np;
|
||||
Namval_t *np, *np_loopdetect;
|
||||
static Dt_t *loopdetect_tree;
|
||||
struct Ufunction *rp,*rpfirst;
|
||||
int savestates = sh_getstate(), oldload=shp->funload, savelineno = shp->inlineno;
|
||||
pname = path_fullname(shp,stakptr(PATH_OFFSET));
|
||||
|
|
@ -607,6 +608,11 @@ static void funload(Shell_t *shp,int fno, const char *name)
|
|||
free((void*)pname);
|
||||
return;
|
||||
}
|
||||
if(!loopdetect_tree)
|
||||
loopdetect_tree = dtopen(&_Nvdisc,Dtoset);
|
||||
else if(nv_search(pname,loopdetect_tree,0))
|
||||
errormsg(SH_DICT,ERROR_exit(ERROR_NOEXEC),"autoload loop: %s in %s",name,pname);
|
||||
np_loopdetect = nv_search(pname,loopdetect_tree,NV_ADD);
|
||||
sh_onstate(SH_NOALIAS);
|
||||
shp->readscript = (char*)name;
|
||||
shp->st.filename = pname;
|
||||
|
|
@ -631,6 +637,7 @@ static void funload(Shell_t *shp,int fno, const char *name)
|
|||
shp->inlineno = savelineno;
|
||||
shp->st.filename = oldname;
|
||||
sh_setstate(savestates);
|
||||
nv_delete(np_loopdetect,loopdetect_tree,0);
|
||||
if(pname)
|
||||
errormsg(SH_DICT,ERROR_exit(ERROR_NOEXEC),e_funload,name,pname);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue