From 4a17a2ca49f317e6b333d071a353bd5b965a26c7 Mon Sep 17 00:00:00 2001 From: Josh Davies Date: Wed, 9 Jul 2025 16:42:44 +0100 Subject: [PATCH] fix: memory leak in par=2 EndSort If a par=2 EndSort ends in the PObuffer, don't allocate and copy out of it twice. --- check/fixes.frm | 11 +++++++++++ sources/sort.c | 22 +++------------------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/check/fixes.frm b/check/fixes.frm index 7c3179ea..9c3ef044 100644 --- a/check/fixes.frm +++ b/check/fixes.frm @@ -3905,3 +3905,14 @@ Print; assert succeeded? assert result("test") =~ expr("1") *--#] PullReq652 : +*--#[ PullReq691 : +#- +#: SubTermsInSmall 112 +#: SubLargePatches 10 +* A par=2 EndSort, which ends in the PObuffer. +* This tests a repaired memory leak. +Symbol x; +#$dol = +...+; +.end +assert succeeded? +*--#] PullReq691 : diff --git a/sources/sort.c b/sources/sort.c index 605c9be4..ca28c1a0 100644 --- a/sources/sort.c +++ b/sources/sort.c @@ -735,7 +735,7 @@ LONG EndSort(PHEAD WORD *buffer, int par) GETBIDENTITY SORTING *S = AT.SS; WORD j, **ss, *to, *t; - LONG sSpace, over, tover, spare, retval = 0, jj; + LONG sSpace, over, tover, spare, retval = 0; POSITION position, pp; off_t lSpace; FILEHANDLE *fout = 0, *oldoutfile = 0, *newout = 0; @@ -1012,24 +1012,8 @@ LONG EndSort(PHEAD WORD *buffer, int par) } else { t = newout->PObuffer; - if ( par == 2 ) { - jj = newout->POfill - t; - if ( AN.tryterm > 0 && ( (jj+2)*sizeof(WORD) < (size_t)(AM.MaxTer) ) ) { - to = TermMalloc("$-sort space"); - } - else { - LONG allocsp = jj+2; - if ( allocsp < MINALLOC ) allocsp = MINALLOC; - allocsp = ((allocsp+7)/8)*8; - to = (WORD *)Malloc1(allocsp*sizeof(WORD),"$-sort space"); - if ( AN.tryterm > 0 ) AN.tryterm = 0; - } - *((WORD **)buffer) = to; - NCOPY(to,t,jj); - /* we should not set retval here in this par==2 case, it being 0 has meaning - after RetRetval, and it is set properly there. */ - } - else { + // We deal with the par == 2 case after RetRetval. + if ( par != 2 ) { j = newout->POfill - t; to = buffer; if ( to >= AT.WorkSpace && to < AT.WorkTop && to+j > AT.WorkTop )