gdi32: Fix some leaks on error paths.

Signed-off-by: Sven Baars <sbaars@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Sven Baars 2021-04-18 14:30:26 +02:00 committed by Alexandre Julliard
parent bdfc865014
commit 842b0d7338
1 changed files with 36 additions and 52 deletions

View File

@ -336,17 +336,17 @@ BOOL BIDI_Reorder(
INT *cGlyphs /* [out] number of glyphs generated */ INT *cGlyphs /* [out] number of glyphs generated */
) )
{ {
WORD *chartype; WORD *chartype = NULL;
BYTE *levels; BYTE *levels = NULL;
INT i, done; INT i, done;
unsigned glyph_i; unsigned glyph_i;
BOOL is_complex; BOOL is_complex, ret = FALSE;
int maxItems; int maxItems;
int nItems; int nItems;
SCRIPT_CONTROL Control; SCRIPT_CONTROL Control;
SCRIPT_STATE State; SCRIPT_STATE State;
SCRIPT_ITEM *pItems; SCRIPT_ITEM *pItems = NULL;
HRESULT res; HRESULT res;
SCRIPT_CACHE psc = NULL; SCRIPT_CACHE psc = NULL;
WORD *run_glyphs = NULL; WORD *run_glyphs = NULL;
@ -429,8 +429,7 @@ BOOL BIDI_Reorder(
if (!levels) if (!levels)
{ {
WARN("Out of memory\n"); WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype); goto cleanup;
return FALSE;
} }
maxItems = 5; maxItems = 5;
@ -438,9 +437,7 @@ BOOL BIDI_Reorder(
if (!pItems) if (!pItems)
{ {
WARN("Out of memory\n"); WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype); goto cleanup;
HeapFree(GetProcessHeap(), 0, levels);
return FALSE;
} }
if (lpGlyphs) if (lpGlyphs)
@ -450,31 +447,19 @@ BOOL BIDI_Reorder(
if (!run_glyphs) if (!run_glyphs)
{ {
WARN("Out of memory\n"); WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype); goto cleanup;
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems);
return FALSE;
} }
pwLogClust = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * uCount); pwLogClust = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * uCount);
if (!pwLogClust) if (!pwLogClust)
{ {
WARN("Out of memory\n"); WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype); goto cleanup;
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems);
HeapFree(GetProcessHeap(), 0, run_glyphs);
return FALSE;
} }
psva = HeapAlloc(GetProcessHeap(),0,sizeof(SCRIPT_VISATTR) * uCount); psva = HeapAlloc(GetProcessHeap(),0,sizeof(SCRIPT_VISATTR) * uCount);
if (!psva) if (!psva)
{ {
WARN("Out of memory\n"); WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype); goto cleanup;
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems);
HeapFree(GetProcessHeap(), 0, run_glyphs);
HeapFree(GetProcessHeap(), 0, pwLogClust);
return FALSE;
} }
} }
@ -519,18 +504,14 @@ BOOL BIDI_Reorder(
res = ScriptItemize(lpString + done, i, maxItems, &Control, &State, pItems, &nItems); res = ScriptItemize(lpString + done, i, maxItems, &Control, &State, pItems, &nItems);
while (res == E_OUTOFMEMORY) while (res == E_OUTOFMEMORY)
{ {
maxItems = maxItems * 2; SCRIPT_ITEM *new_pItems = HeapReAlloc(GetProcessHeap(), 0, pItems, sizeof(*pItems) * maxItems * 2);
pItems = HeapReAlloc(GetProcessHeap(), 0, pItems, sizeof(SCRIPT_ITEM) * maxItems); if (!new_pItems)
if (!pItems)
{ {
WARN("Out of memory\n"); WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, chartype); goto cleanup;
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, run_glyphs);
HeapFree(GetProcessHeap(), 0, pwLogClust);
HeapFree(GetProcessHeap(), 0, psva);
return FALSE;
} }
pItems = new_pItems;
maxItems *= 2;
res = ScriptItemize(lpString + done, i, maxItems, &Control, &State, pItems, &nItems); res = ScriptItemize(lpString + done, i, maxItems, &Control, &State, pItems, &nItems);
} }
@ -587,12 +568,7 @@ BOOL BIDI_Reorder(
WARN("Out of memory\n"); WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, runOrder); HeapFree(GetProcessHeap(), 0, runOrder);
HeapFree(GetProcessHeap(), 0, visOrder); HeapFree(GetProcessHeap(), 0, visOrder);
HeapFree(GetProcessHeap(), 0, chartype); goto cleanup;
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems);
HeapFree(GetProcessHeap(), 0, psva);
HeapFree(GetProcessHeap(), 0, pwLogClust);
return FALSE;
} }
for (j = 0; j < nItems; j++) for (j = 0; j < nItems; j++)
@ -611,23 +587,18 @@ BOOL BIDI_Reorder(
res = ScriptShape(hDC, &psc, lpString + done + curItem->iCharPos, cChars, cMaxGlyphs, &curItem->a, run_glyphs, pwLogClust, psva, &cOutGlyphs); res = ScriptShape(hDC, &psc, lpString + done + curItem->iCharPos, cChars, cMaxGlyphs, &curItem->a, run_glyphs, pwLogClust, psva, &cOutGlyphs);
while (res == E_OUTOFMEMORY) while (res == E_OUTOFMEMORY)
{ {
cMaxGlyphs *= 2; WORD *new_run_glyphs = HeapReAlloc(GetProcessHeap(), 0, run_glyphs, sizeof(*run_glyphs) * cMaxGlyphs * 2);
run_glyphs = HeapReAlloc(GetProcessHeap(), 0, run_glyphs, sizeof(WORD) * cMaxGlyphs); if (!new_run_glyphs)
if (!run_glyphs)
{ {
WARN("Out of memory\n"); WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, runOrder); HeapFree(GetProcessHeap(), 0, runOrder);
HeapFree(GetProcessHeap(), 0, visOrder); HeapFree(GetProcessHeap(), 0, visOrder);
HeapFree(GetProcessHeap(), 0, chartype);
HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems);
HeapFree(GetProcessHeap(), 0, psva);
HeapFree(GetProcessHeap(), 0, pwLogClust);
HeapFree(GetProcessHeap(), 0, *lpGlyphs); HeapFree(GetProcessHeap(), 0, *lpGlyphs);
ScriptFreeCache(&psc);
*lpGlyphs = NULL; *lpGlyphs = NULL;
return FALSE; goto cleanup;
} }
run_glyphs = new_run_glyphs;
cMaxGlyphs *= 2;
res = ScriptShape(hDC, &psc, lpString + done + curItem->iCharPos, cChars, cMaxGlyphs, &curItem->a, run_glyphs, pwLogClust, psva, &cOutGlyphs); res = ScriptShape(hDC, &psc, lpString + done + curItem->iCharPos, cChars, cMaxGlyphs, &curItem->a, run_glyphs, pwLogClust, psva, &cOutGlyphs);
} }
if (res) if (res)
@ -643,10 +614,21 @@ BOOL BIDI_Reorder(
} }
else else
{ {
WORD *new_glyphs;
if (*lpGlyphs) if (*lpGlyphs)
*lpGlyphs = HeapReAlloc(GetProcessHeap(), 0, *lpGlyphs, sizeof(WORD) * (glyph_i + cOutGlyphs)); new_glyphs = HeapReAlloc(GetProcessHeap(), 0, *lpGlyphs, sizeof(**lpGlyphs) * (glyph_i + cOutGlyphs));
else else
*lpGlyphs = HeapAlloc(GetProcessHeap(), 0, sizeof(WORD) * (glyph_i + cOutGlyphs)); new_glyphs = HeapAlloc(GetProcessHeap(), 0, sizeof(**lpGlyphs) * (glyph_i + cOutGlyphs));
if (!new_glyphs)
{
WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, runOrder);
HeapFree(GetProcessHeap(), 0, visOrder);
HeapFree(GetProcessHeap(), 0, *lpGlyphs);
*lpGlyphs = NULL;
goto cleanup;
}
*lpGlyphs = new_glyphs;
for (k = 0; k < cOutGlyphs; k++) for (k = 0; k < cOutGlyphs; k++)
(*lpGlyphs)[glyph_i+k] = run_glyphs[k]; (*lpGlyphs)[glyph_i+k] = run_glyphs[k];
glyph_i += cOutGlyphs; glyph_i += cOutGlyphs;
@ -661,6 +643,8 @@ BOOL BIDI_Reorder(
if (cGlyphs) if (cGlyphs)
*cGlyphs = glyph_i; *cGlyphs = glyph_i;
ret = TRUE;
cleanup:
HeapFree(GetProcessHeap(), 0, chartype); HeapFree(GetProcessHeap(), 0, chartype);
HeapFree(GetProcessHeap(), 0, levels); HeapFree(GetProcessHeap(), 0, levels);
HeapFree(GetProcessHeap(), 0, pItems); HeapFree(GetProcessHeap(), 0, pItems);
@ -668,5 +652,5 @@ BOOL BIDI_Reorder(
HeapFree(GetProcessHeap(), 0, pwLogClust); HeapFree(GetProcessHeap(), 0, pwLogClust);
HeapFree(GetProcessHeap(), 0, psva); HeapFree(GetProcessHeap(), 0, psva);
ScriptFreeCache(&psc); ScriptFreeCache(&psc);
return TRUE; return ret;
} }