diff --git "a/dll/win32/usp10/usp10.c" "b/dll/win32/usp10/usp10.c" index c53f3e97d1e..e367ff03c33 100644 --- "a/dll/win32/usp10/usp10.c" +++ "b/dll/win32/usp10/usp10.c" @@ -1993,9 +1993,10 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, StringAnalysis *analysis = NULL; SCRIPT_CONTROL sControl; SCRIPT_STATE sState; - int i, num_items = 255; + int i, num_items = cString + 1; BYTE *BidiLevel; WCHAR *iString = NULL; + SCRIPT_ITEM *items; TRACE("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p)\n", hdc, pString, cString, cGlyphs, iCharset, dwFlags, iReqWidth, @@ -2011,7 +2012,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, if (!(analysis = heap_alloc_zero(sizeof(*analysis)))) return E_OUTOFMEMORY; - if (!(analysis->pItem = heap_calloc(num_items + 1, sizeof(*analysis->pItem)))) + if (!(analysis->pItem = heap_calloc(num_items, sizeof(*analysis->pItem)))) goto error; /* FIXME: handle clipping */ @@ -2043,13 +2044,13 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, hr = ScriptItemize(pString, cString, num_items, &sControl, &sState, analysis->pItem, &analysis->numItems); - if (FAILED(hr)) - { - if (hr == E_OUTOFMEMORY) - hr = E_INVALIDARG; + goto error; - } + + /* Having as many items as codepoints is the worst case scenario, try to reclaim some memory. */ + if ((items = heap_realloc(analysis->pItem, (analysis->numItems + 1) * sizeof(*analysis->pItem)))) + analysis->pItem = items; /* set back to out of memory for default goto error behaviour */ hr = E_OUTOFMEMORY;