mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix memory leak on unset of associative array (#64)
Associative arrays weren't being properly freed from memory, which was causing a memory leak. This commit incorporates a patch and reproducer/regress test from: https://www.mail-archive.com/ast-users@lists.research.att.com/msg01016.html src/cmd/ksh93/sh/name.c: - Properly free associative arrays from memory in nv_delete(). src/cmd/ksh93/tests/leaks.sh: - Add regression test.
This commit is contained in:
parent
bf79131f40
commit
e70925ce10
3 changed files with 34 additions and 0 deletions
2
NEWS
2
NEWS
|
@ -8,6 +8,8 @@ Any uppercase BUG_* names are modernish shell bug IDs.
|
||||||
- 'notty' is now written to the ksh auditing file instead of '(null)' if
|
- 'notty' is now written to the ksh auditing file instead of '(null)' if
|
||||||
the user's tty could not be determined.
|
the user's tty could not be determined.
|
||||||
|
|
||||||
|
- Unsetting an associative array no longer causes a memory leak to occur.
|
||||||
|
|
||||||
2020-07-05:
|
2020-07-05:
|
||||||
|
|
||||||
- In UTF-8 locales, fix corruption of the shell's internal string quoting
|
- In UTF-8 locales, fix corruption of the shell's internal string quoting
|
||||||
|
|
|
@ -1298,8 +1298,19 @@ void nv_delete(Namval_t* np, Dt_t *root, int flags)
|
||||||
if(dtdelete(root,np))
|
if(dtdelete(root,np))
|
||||||
{
|
{
|
||||||
if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np)))
|
if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np)))
|
||||||
|
{
|
||||||
|
Namarr_t *ap;
|
||||||
|
if(nv_isarray(np) && np->nvfun && (ap=nv_arrayptr(np)) && array_assoc(ap))
|
||||||
|
{
|
||||||
|
/* free associative array from memory */
|
||||||
|
while(nv_associative(np,0,NV_ANEXT))
|
||||||
|
nv_associative(np,0,NV_ADELETE);
|
||||||
|
nv_associative(np,0,NV_AFREE);
|
||||||
|
free((void*)np->nvfun);
|
||||||
|
}
|
||||||
free((void*)np);
|
free((void*)np);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,4 +101,25 @@ done
|
||||||
after=$(getmem)
|
after=$(getmem)
|
||||||
(( after > before )) && err_exit "memory leak with read -C when using <<< (leaked $((after - before)) $unit)"
|
(( after > before )) && err_exit "memory leak with read -C when using <<< (leaked $((after - before)) $unit)"
|
||||||
|
|
||||||
|
# ======
|
||||||
|
# Unsetting an associative array shouldn't cause a memory leak
|
||||||
|
# See https://www.mail-archive.com/ast-users@lists.research.att.com/msg01016.html
|
||||||
|
typeset -A stuff
|
||||||
|
before=$(getmem)
|
||||||
|
for (( i=0; i<1000; i++ ))
|
||||||
|
do
|
||||||
|
unset stuff[xyz]
|
||||||
|
typeset -A stuff[xyz]
|
||||||
|
stuff[xyz][elem0]="data0"
|
||||||
|
stuff[xyz][elem1]="data1"
|
||||||
|
stuff[xyz][elem2]="data2"
|
||||||
|
stuff[xyz][elem3]="data3"
|
||||||
|
stuff[xyz][elem4]="data4"
|
||||||
|
done
|
||||||
|
unset stuff
|
||||||
|
after=$(getmem)
|
||||||
|
(( after > before )) && err_exit 'unset of associative array causes memory leak' \
|
||||||
|
"(leaked $((after - before)) $unit)"
|
||||||
|
|
||||||
|
# ======
|
||||||
exit $((Errors<125?Errors:125))
|
exit $((Errors<125?Errors:125))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue