Henri Verbeet : usp10: Double the scripts array size when growing it in GPOS_expand_script_cache ().

Alexandre Julliard julliard at winehq.org
Tue Mar 28 15:38:41 CDT 2017


Module: wine
Branch: master
Commit: 218be443b66518b265f266c02d2e89d6e2fad092
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=218be443b66518b265f266c02d2e89d6e2fad092

Author: Henri Verbeet <hverbeet at 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 at codeweavers.com>
Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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,




More information about the wine-cvs mailing list