[ros-diffs] [tfaber] 56210: [USP10] - Apply fixes from Wine 1.4. Fixes invalid free in notepad and other edit control users See issue #6966 for more details.

tfaber at svn.reactos.org tfaber at svn.reactos.org
Wed Mar 21 20:39:42 UTC 2012


Author: tfaber
Date: Wed Mar 21 20:39:41 2012
New Revision: 56210

URL: http://svn.reactos.org/svn/reactos?rev=56210&view=rev
Log:
[USP10]
- Apply fixes from Wine 1.4. Fixes invalid free in notepad and other edit control users
See issue #6966 for more details.

Modified:
    trunk/reactos/dll/win32/usp10/opentype.c
    trunk/reactos/dll/win32/usp10/shape.c
    trunk/reactos/dll/win32/usp10/usp10.c
    trunk/reactos/dll/win32/usp10/usp10_internal.h
    trunk/reactos/dll/win32/usp10/usp10_ros.diff
    trunk/reactos/media/doc/README.WINE

Modified: trunk/reactos/dll/win32/usp10/opentype.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/opentype.c?rev=56210&r1=56209&r2=56210&view=diff
==============================================================================
--- trunk/reactos/dll/win32/usp10/opentype.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/usp10/opentype.c [iso-8859-1] Wed Mar 21 20:39:41 2012
@@ -438,9 +438,12 @@
         int char_count = 0;
         int k;
 
-        for (k = 0; k < cChars; k++)
-            if (pwLogClust[k] == i)
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k >= 0)
+        {
+            for (; k < cChars && pwLogClust[k] == i; k++)
                 char_count++;
+        }
 
         class = GDEF_get_glyph_class(psc->GDEF_Table, pwGlyphs[i]);
 
@@ -868,12 +871,15 @@
         script = (const GSUB_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);
-        psc->scripts = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LoadedScript) * psc->script_count);
-        for (i = 0; i < psc->script_count; i++)
-        {
-            int offset = GET_BE_WORD(script->ScriptRecord[i].Script);
-            psc->scripts[i].tag = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]);
-            psc->scripts[i].table = ((const BYTE*)script + offset);
+        if (psc->script_count)
+        {
+            psc->scripts = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LoadedScript) * psc->script_count);
+            for (i = 0; i < psc->script_count; i++)
+            {
+                int offset = GET_BE_WORD(script->ScriptRecord[i].Script);
+                psc->scripts[i].tag = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]);
+                psc->scripts[i].table = ((const BYTE*)script + offset);
+            }
         }
     }
 }
@@ -923,15 +929,18 @@
         script->default_language.tag = MS_MAKE_TAG('d','f','l','t');
         script->default_language.table = (const BYTE*)table + GET_BE_WORD(table->DefaultLangSys);
 
-        TRACE("Deflang %p, LangCount %i\n",script->default_language.table, script->language_count);
-
-        script->languages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LoadedLanguage) * script->language_count);
-
-        for (i = 0; i < script->language_count; i++)
-        {
-            int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys);
-            script->languages[i].tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]);
-            script->languages[i].table = ((const BYTE*)table + offset);
+        if (script->language_count)
+        {
+            TRACE("Deflang %p, LangCount %i\n",script->default_language.table, script->language_count);
+
+            script->languages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LoadedLanguage) * script->language_count);
+
+            for (i = 0; i < script->language_count; i++)
+            {
+                int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys);
+                script->languages[i].tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]);
+                script->languages[i].table = ((const BYTE*)table + offset);
+            }
         }
     }
 }
@@ -1016,23 +1025,26 @@
         language->feature_count = GET_BE_WORD(lang->FeatureCount);
         TRACE("%i features\n",language->feature_count);
 
-        language->features = HeapAlloc(GetProcessHeap(),0,sizeof(LoadedFeature)*language->feature_count);
-
-        feature_list = (const GSUB_FeatureList*)((const BYTE*)header + GET_BE_WORD(header->FeatureList));
-
-        for (i = 0; i < language->feature_count; i++)
-        {
-            const GSUB_Feature *feature;
-            int j;
-            int index = GET_BE_WORD(lang->FeatureIndex[i]);
-
-            language->features[i].tag = MS_MAKE_TAG(feature_list->FeatureRecord[index].FeatureTag[0], feature_list->FeatureRecord[index].FeatureTag[1], feature_list->FeatureRecord[index].FeatureTag[2], feature_list->FeatureRecord[index].FeatureTag[3]);
-            language->features[i].feature = ((const BYTE*)feature_list + GET_BE_WORD(feature_list->FeatureRecord[index].Feature));
-            feature = (const GSUB_Feature*)language->features[i].feature;
-            language->features[i].lookup_count = GET_BE_WORD(feature->LookupCount);
-            language->features[i].lookups = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * language->features[i].lookup_count);
-            for (j = 0; j < language->features[i].lookup_count; j++)
-                language->features[i].lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
+        if (language->feature_count)
+        {
+            language->features = HeapAlloc(GetProcessHeap(),0,sizeof(LoadedFeature)*language->feature_count);
+
+            feature_list = (const GSUB_FeatureList*)((const BYTE*)header + GET_BE_WORD(header->FeatureList));
+
+            for (i = 0; i < language->feature_count; i++)
+            {
+                const GSUB_Feature *feature;
+                int j;
+                int index = GET_BE_WORD(lang->FeatureIndex[i]);
+
+                language->features[i].tag = MS_MAKE_TAG(feature_list->FeatureRecord[index].FeatureTag[0], feature_list->FeatureRecord[index].FeatureTag[1], feature_list->FeatureRecord[index].FeatureTag[2], feature_list->FeatureRecord[index].FeatureTag[3]);
+                language->features[i].feature = ((const BYTE*)feature_list + GET_BE_WORD(feature_list->FeatureRecord[index].Feature));
+                feature = (const GSUB_Feature*)language->features[i].feature;
+                language->features[i].lookup_count = GET_BE_WORD(feature->LookupCount);
+                language->features[i].lookups = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * language->features[i].lookup_count);
+                for (j = 0; j < language->features[i].lookup_count; j++)
+                    language->features[i].lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
+            }
         }
     }
 }

Modified: trunk/reactos/dll/win32/usp10/shape.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/shape.c?rev=56210&r1=56209&r2=56210&view=diff
==============================================================================
--- trunk/reactos/dll/win32/usp10/shape.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/usp10/shape.c [iso-8859-1] Wed Mar 21 20:39:41 2012
@@ -2359,13 +2359,11 @@
         int char_index[20];
         int char_count = 0;
 
-        for (k = 0; k < cChars; k++)
-        {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
+        {
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         if (char_count == 0)
@@ -2425,13 +2423,11 @@
         int char_count = 0;
         BOOL isInit, isFinal;
 
-        for (k = 0; k < cChars; k++)
-        {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
+        {
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         isInit = (i == initGlyph || (i+dirR > 0 && i+dirR < cGlyphs && spaces[i+dirR]));
@@ -2534,13 +2530,11 @@
         int char_index[20];
         int char_count = 0;
 
-        for (k = 0; k < cChars; k++)
-        {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
+        {
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         if (char_count == 0)
@@ -2581,13 +2575,11 @@
         int char_index[20];
         int char_count = 0;
 
-        for (k = 0; k < cChars; k++)
-        {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
+        {
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         if (char_count == 0)
@@ -2614,13 +2606,11 @@
         int char_index[20];
         int char_count = 0;
 
-        for (k = 0; k < cChars; k++)
-        {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
+        {
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         if (char_count == 0)
@@ -2658,13 +2648,11 @@
         int char_index[20];
         int char_count = 0;
 
-        for (k = 0; k < cChars; k++)
-        {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
+        {
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         if (override_gsub)

Modified: trunk/reactos/dll/win32/usp10/usp10.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/usp10.c?rev=56210&r1=56209&r2=56210&view=diff
==============================================================================
--- trunk/reactos/dll/win32/usp10/usp10.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/usp10/usp10.c [iso-8859-1] Wed Mar 21 20:39:41 2012
@@ -25,6 +25,7 @@
  */
 
 #include <stdarg.h>
+#include <stdlib.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -703,6 +704,11 @@
     int* logical2visual;
 } StringAnalysis;
 
+typedef struct {
+    BOOL ascending;
+    WORD target;
+} FindGlyph_struct;
+
 static inline void *heap_alloc(SIZE_T size)
 {
     return HeapAlloc(GetProcessHeap(), 0, size);
@@ -879,6 +885,46 @@
     } while (1);
 
     return SCRIPT_UNDEFINED;
+}
+
+static int compare_FindGlyph(const void *a, const void* b)
+{
+    const FindGlyph_struct *find = (FindGlyph_struct*)a;
+    const WORD *idx= (WORD*)b;
+    int rc = 0;
+
+    if ( find->target > *idx)
+        rc = 1;
+    else if (find->target < *idx)
+        rc = -1;
+
+    if (!find->ascending)
+        rc *= -1;
+    return rc;
+}
+
+int USP10_FindGlyphInLogClust(const WORD* pwLogClust, int cChars, WORD target)
+{
+    FindGlyph_struct fgs;
+    WORD *ptr;
+    INT k;
+
+    if (pwLogClust[0] < pwLogClust[cChars-1])
+        fgs.ascending = TRUE;
+    else
+        fgs.ascending = FALSE;
+
+    fgs.target = target;
+    ptr = bsearch(&fgs, pwLogClust, cChars, sizeof(WORD), compare_FindGlyph);
+
+    if (!ptr)
+        return -1;
+
+    for (k = (ptr - pwLogClust)-1; k >= 0 && pwLogClust[k] == target; k--)
+    ;
+    k++;
+
+    return k;
 }
 
 /***********************************************************************
@@ -1726,19 +1772,12 @@
     hr = ScriptItemize(pString, cString, num_items, &sControl, &sState, analysis->pItem,
                        &analysis->numItems);
 
-    while (hr == E_OUTOFMEMORY)
-    {
-        SCRIPT_ITEM *tmp;
-
-        num_items *= 2;
-        if (!(tmp = heap_realloc_zero(analysis->pItem, num_items * sizeof(SCRIPT_ITEM) + 1)))
-            goto error;
-
-        analysis->pItem = tmp;
-        hr = ScriptItemize(pString, cString, num_items, psControl, psState, analysis->pItem,
-                           &analysis->numItems);
-    }
-    if (hr != S_OK) goto error;
+    if FAILED(hr)
+    {
+        if (hr == E_OUTOFMEMORY)
+            hr = E_INVALIDARG;
+        goto error;
+    }
 
     /* set back to out of memory for default goto error behaviour */
     hr = E_OUTOFMEMORY;
@@ -1817,6 +1856,13 @@
                 }
             }
 
+            /* FIXME: When we properly shape Hangul remove this check */
+            if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && analysis->pItem[i].a.eScript == Script_Hangul)
+                analysis->pItem[i].a.fNoGlyphIndex = TRUE;
+
+            if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && !scriptInformation[analysis->pItem[i].a.eScript].props.fComplex)
+                analysis->pItem[i].a.fNoGlyphIndex = TRUE;
+
             hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos],
                              cChar, numGlyphs, &analysis->pItem[i].a,
                              glyphs, pwLogClust, psva, &numGlyphsReturned);
@@ -1873,13 +1919,9 @@
 
 static inline BOOL does_glyph_start_cluster(const SCRIPT_VISATTR *pva, const WORD *pwLogClust, int cChars, int glyph, int direction)
 {
-    int i;
-
     if (pva[glyph].fClusterStart)
         return TRUE;
-    for (i = 0; i < cChars; i++)
-        if (pwLogClust[i] == glyph) break;
-    if (i != cChars)
+    if (USP10_FindGlyphInLogClust(pwLogClust, cChars, glyph) >= 0)
         return TRUE;
 
     return FALSE;
@@ -2309,16 +2351,14 @@
 static inline int get_glyph_cluster_advance(const int* piAdvance, const SCRIPT_VISATTR *pva, const WORD *pwLogClust, int cGlyphs, int cChars, int glyph, int direction)
 {
     int advance;
-    int log_clust_max = 0;
-    int i;
+    int log_clust_max;
 
     advance = piAdvance[glyph];
 
-    for (i = 0; i < cChars; i++)
-    {
-        if (pwLogClust[i] > log_clust_max)
-            log_clust_max = pwLogClust[i];
-    }
+    if (pwLogClust[0] > pwLogClust[cChars-1])
+        log_clust_max = pwLogClust[0];
+    else
+        log_clust_max = pwLogClust[cChars-1];
 
     if (glyph > log_clust_max)
         return advance;

Modified: trunk/reactos/dll/win32/usp10/usp10_internal.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/usp10_internal.h?rev=56210&r1=56209&r2=56210&view=diff
==============================================================================
--- trunk/reactos/dll/win32/usp10/usp10_internal.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/usp10/usp10_internal.h [iso-8859-1] Wed Mar 21 20:39:41 2012
@@ -204,6 +204,8 @@
 #define BIDI_WEAK    2
 #define BIDI_NEUTRAL 0
 
+int USP10_FindGlyphInLogClust(const WORD* pwLogClust, int cChars, WORD target) DECLSPEC_HIDDEN;
+
 BOOL BIDI_DetermineLevels( LPCWSTR lpString, INT uCount, const SCRIPT_STATE *s,
                 const SCRIPT_CONTROL *c, WORD *lpOutLevels ) DECLSPEC_HIDDEN;
 BOOL BIDI_GetStrengths(LPCWSTR lpString, INT uCount, const SCRIPT_CONTROL *c,

Modified: trunk/reactos/dll/win32/usp10/usp10_ros.diff
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/usp10/usp10_ros.diff?rev=56210&r1=56209&r2=56210&view=diff
==============================================================================
--- trunk/reactos/dll/win32/usp10/usp10_ros.diff [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/usp10/usp10_ros.diff [iso-8859-1] Wed Mar 21 20:39:41 2012
@@ -2,9 +2,9 @@
 ===================================================================
 --- usp10.c     (revision 54504)
 +++ usp10.c     (working copy)
-@@ -1989,3 +3159,9 @@
-     for (i = 0; i < num_glyphs; i++) justify[i] = advance[i];
-     return S_OK;
+@@ -3621,3 +3621,9 @@
+ 
+     return SHAPE_GetFontFeatureTags(hdc, (ScriptCache *)*psc, psa, tagScript, tagLangSys, cMaxTags, pFeatureTags, pcTags);
  }
 +
 +BOOL gbLpkPresent = FALSE;

Modified: trunk/reactos/media/doc/README.WINE
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=56210&r1=56209&r2=56210&view=diff
==============================================================================
--- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original)
+++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Wed Mar 21 20:39:41 2012
@@ -168,7 +168,7 @@
 reactos/dll/win32/updspapi        # Synced to Wine-1.3.37
 reactos/dll/win32/url             # Autosync
 reactos/dll/win32/urlmon          # Autosync
-reactos/dll/win32/usp10           # Synced to Wine-1.3.37
+reactos/dll/win32/usp10           # Synced to Wine-1.4
 reactos/dll/win32/uxtheme         # Forked
 reactos/dll/win32/version         # Autosync
 reactos/dll/win32/wer             # Autosync




More information about the Ros-diffs mailing list