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?... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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_inter... ============================================================================== --- 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.d... ============================================================================== --- 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=5... ============================================================================== --- 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