From: समीर सिंह Sameer Singh <lumarzeli30@gmail.com> --- dlls/gdi32/uniscribe/usp10.c | 91 +++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 22 deletions(-) diff --git a/dlls/gdi32/uniscribe/usp10.c b/dlls/gdi32/uniscribe/usp10.c index 43afbaac125..8afc79ba85c 100644 --- a/dlls/gdi32/uniscribe/usp10.c +++ b/dlls/gdi32/uniscribe/usp10.c @@ -32,6 +32,7 @@ #include "winbase.h" #include "ntgdi.h" #include "ntuser.h" +#include "winerror.h" #include "winuser.h" #include "winnls.h" #include "winreg.h" @@ -1904,7 +1905,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, SCRIPT_CONTROL sControl; SCRIPT_STATE sState; int i, num_items = cString + 1; - BYTE *BidiLevel; + BYTE *BidiLevel = NULL; WCHAR *iString = NULL; SCRIPT_ITEM *items; @@ -1985,21 +1986,19 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, int tab_x = 0; if (!(analysis->glyphs = calloc(analysis->numItems, sizeof(*analysis->glyphs)))) - { - free(BidiLevel); goto error; - } for (i = 0; i < analysis->numItems; i++) { SCRIPT_CACHE *sc = (SCRIPT_CACHE*)&analysis->glyphs[i].sc; int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos; - int numGlyphs = 1.5 * cChar + 16; - WORD *glyphs = calloc(numGlyphs, sizeof(*glyphs)); + int multiplier = 2; + int numGlyphs; + WORD *glyphs = NULL; WORD *pwLogClust = calloc(cChar, sizeof(*pwLogClust)); - int *piAdvance = calloc(numGlyphs, sizeof(*piAdvance)); - SCRIPT_VISATTR *psva = calloc(numGlyphs, sizeof(*psva)); - GOFFSET *pGoffset = calloc(numGlyphs, sizeof(*pGoffset)); + int *piAdvance = NULL; + SCRIPT_VISATTR *psva = NULL; + GOFFSET *pGoffset = NULL; int numGlyphsReturned; HFONT originalFont = 0x0; @@ -2007,16 +2006,10 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, const WCHAR* pStr = (const WCHAR*)pString; analysis->glyphs[i].fallbackFont = NULL; - if (!glyphs || !pwLogClust || !piAdvance || !psva || !pGoffset) + if (!pwLogClust) { - free(BidiLevel); - free(glyphs); - free(pwLogClust); - free(piAdvance); - free(psva); - free(pGoffset); hr = E_OUTOFMEMORY; - goto error; + goto cleanup_iter; } if ((dwFlags & SSA_FALLBACK) && requires_fallback(hdc, sc, &analysis->pItem[i].a, &pStr[analysis->pItem[i].iCharPos], cChar)) @@ -2044,10 +2037,47 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && !scriptInformation[analysis->pItem[i].a.eScript].props.fComplex && !analysis->pItem[i].a.fRTL) analysis->pItem[i].a.fNoGlyphIndex = TRUE; - ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos], cChar, numGlyphs, - &analysis->pItem[i].a, glyphs, pwLogClust, psva, &numGlyphsReturned); - hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a, - piAdvance, pGoffset, &analysis->glyphs[i].abc); + while (TRUE) + { + if (multiplier > 8) + { + hr = E_OUTOFMEMORY; + goto cleanup_iter; + } + + free(glyphs); + free(piAdvance); + free(psva); + free(pGoffset); + + numGlyphs = multiplier * cChar + 16; + glyphs = calloc(numGlyphs, sizeof(*glyphs)); + piAdvance = calloc(numGlyphs, sizeof(*piAdvance)); + psva = calloc(numGlyphs, sizeof(*psva)); + pGoffset = calloc(numGlyphs, sizeof(*pGoffset)); + + if (!glyphs || !piAdvance || !psva || !pGoffset) + { + hr = E_OUTOFMEMORY; + goto cleanup_iter; + } + + hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos], cChar, numGlyphs, + &analysis->pItem[i].a, glyphs, pwLogClust, psva, &numGlyphsReturned); + if (hr == E_OUTOFMEMORY) + { + multiplier *= 2; + continue; + } + + hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a, + piAdvance, pGoffset, &analysis->glyphs[i].abc); + if (FAILED(hr)) + goto cleanup_iter; + + break; + } + if (originalFont) SelectObject(hdc,originalFont); @@ -2071,6 +2101,17 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, analysis->glyphs[i].iMaxPosX= -1; BidiLevel[i] = analysis->pItem[i].a.s.uBidiLevel; + continue; + + cleanup_iter: + if (originalFont) + SelectObject(hdc, originalFont); + free(glyphs); + free(pwLogClust); + free(piAdvance); + free(psva); + free(pGoffset); + goto error; } } else @@ -2088,6 +2129,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, error: free(iString); + free(BidiLevel); free(analysis->glyphs); free(analysis->logattrs); free(analysis->pItem); @@ -3148,7 +3190,12 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc, } *pcGlyphs = g; - SHAPE_ContextualShaping(hdc, (ScriptCache *)*psc, psa, rChars, cChars, pwOutGlyphs, pcGlyphs, cMaxGlyphs, pwLogClust); + hr = SHAPE_ContextualShaping(hdc, (ScriptCache *)*psc, psa, rChars, cChars, pwOutGlyphs, pcGlyphs, cMaxGlyphs, pwLogClust); + if (FAILED(hr)) + { + free(rChars); + return hr; + } SHAPE_ApplyDefaultOpentypeFeatures(hdc, (ScriptCache *)*psc, psa, pwOutGlyphs, pcGlyphs, cMaxGlyphs, cChars, pwLogClust); SHAPE_CharGlyphProp(hdc, (ScriptCache *)*psc, psa, pwcChars, cChars, pwOutGlyphs, *pcGlyphs, pwLogClust, pCharProps, pOutGlyphProps); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10612