Module: wine Branch: master Commit: 218be443b66518b265f266c02d2e89d6e2fad092 URL: http://source.winehq.org/git/wine.git/?a=commit;h=218be443b66518b265f266c02d...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Mon Mar 27 22:57:01 2017 +0200
usp10: Double the scripts array size when growing it in GPOS_expand_script_cache().
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Aric Stewart aric@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/usp10/opentype.c | 17 +++++++++++------ dlls/usp10/usp10.c | 30 ++++++++++++++++++++++++++++++ dlls/usp10/usp10_internal.h | 4 +++- 3 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/dlls/usp10/opentype.c b/dlls/usp10/opentype.c index b58731a..3786473 100644 --- a/dlls/usp10/opentype.c +++ b/dlls/usp10/opentype.c @@ -2504,7 +2504,7 @@ static void GSUB_initialize_script_cache(ScriptCache *psc) const GSUB_Header* header = (const GSUB_Header*)psc->GSUB_Table; script = (const OT_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList)); psc->script_count = GET_BE_WORD(script->ScriptCount); - TRACE("initializing %i scripts in this font\n",psc->script_count); + TRACE("initializing %li scripts in this font\n",psc->script_count); if (psc->script_count) { psc->scripts = heap_alloc_zero(psc->script_count * sizeof(*psc->scripts)); @@ -2537,7 +2537,7 @@ static void GPOS_expand_script_cache(ScriptCache *psc) if (!psc->script_count) { psc->script_count = count; - TRACE("initializing %i scripts in this font\n",psc->script_count); + TRACE("initializing %li scripts in this font\n",psc->script_count); if (psc->script_count) { psc->scripts = heap_alloc_zero(psc->script_count * sizeof(*psc->scripts)); @@ -2558,10 +2558,15 @@ static void GPOS_expand_script_cache(ScriptCache *psc)
if (!(loaded_script = usp10_script_cache_get_script(psc, tag))) { - psc->script_count++; - psc->scripts = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - psc->scripts, psc->script_count * sizeof(*psc->scripts)); - loaded_script = &psc->scripts[psc->script_count - 1]; + if (!usp10_array_reserve((void **)&psc->scripts, &psc->scripts_size, + psc->script_count + 1, sizeof(*psc->scripts))) + { + ERR("Failed grow scripts array.\n"); + return; + } + + loaded_script = &psc->scripts[psc->script_count]; + ++psc->script_count; loaded_script->tag = tag; } loaded_script->gpos_table = (const BYTE *)script + offset; diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index d7b7d9a..2df27be 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -708,6 +708,36 @@ typedef struct { WORD target; } FindGlyph_struct;
+BOOL usp10_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) +{ + SIZE_T max_capacity, new_capacity; + void *new_elements; + + if (count <= *capacity) + return TRUE; + + max_capacity = ~(SIZE_T)0 / size; + if (count > max_capacity) + return FALSE; + + new_capacity = max(1, *capacity); + while (new_capacity < count && new_capacity <= max_capacity / 2) + new_capacity *= 2; + if (new_capacity < count) + new_capacity = count; + + if (!*elements) + new_elements = heap_alloc_zero(new_capacity * size); + else + new_elements = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *elements, new_capacity * size); + if (!new_elements) + return FALSE; + + *elements = new_elements; + *capacity = new_capacity; + return TRUE; +} + /* TODO Fix font properties on Arabic locale */ static inline BOOL set_cache_font_properties(const HDC hdc, ScriptCache *sc) { diff --git a/dlls/usp10/usp10_internal.h b/dlls/usp10/usp10_internal.h index f906885..9a8b5131 100644 --- a/dlls/usp10/usp10_internal.h +++ b/dlls/usp10/usp10_internal.h @@ -186,8 +186,9 @@ typedef struct { void *CMAP_format12_Table; void *GPOS_Table; BOOL scripts_initialized; - INT script_count; LoadedScript *scripts; + SIZE_T scripts_size; + SIZE_T script_count;
OPENTYPE_TAG userScript; OPENTYPE_TAG userLang; @@ -245,6 +246,7 @@ typedef void (*reorder_function)(WCHAR *chars, IndicSyllable *syllable, lexical_ #define BIDI_WEAK 2 #define BIDI_NEUTRAL 0
+BOOL usp10_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) DECLSPEC_HIDDEN; int USP10_FindGlyphInLogClust(const WORD* pwLogClust, int cChars, WORD target) DECLSPEC_HIDDEN;
BOOL BIDI_DetermineLevels(const WCHAR *string, unsigned int count, const SCRIPT_STATE *s,