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,7 +1298,18 @@ 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