[PATCH 2/5] usp10: Double the scripts array size when growing it in GPOS_expand_script_cache().

Aric Stewart aric at codeweavers.com
Tue Mar 28 07:17:28 CDT 2017


Signed-off-by: Aric Stewart <aric at codeweavers.com>

On 3/27/17 3:57 PM, Henri Verbeet wrote:
> Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
> ---
>  dlls/usp10/opentype.c       | 13 +++++++++----
>  dlls/usp10/usp10.c          | 30 ++++++++++++++++++++++++++++++
>  dlls/usp10/usp10_internal.h |  4 +++-
>  3 files changed, 42 insertions(+), 5 deletions(-)
> 
> diff --git a/dlls/usp10/opentype.c b/dlls/usp10/opentype.c
> index b58731a..aa3d654 100644
> --- a/dlls/usp10/opentype.c
> +++ b/dlls/usp10/opentype.c
> @@ -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..7df3856 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..22e4aad 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-patches mailing list