You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by hd...@apache.org on 2014/03/27 17:07:37 UTC

svn commit: r1582374 - /openoffice/trunk/main/vcl/win/source/gdi/winlayout.cxx

Author: hdu
Date: Thu Mar 27 16:07:37 2014
New Revision: 1582374

URL: http://svn.apache.org/r1582374
Log:
#i124516# handle bad surrogate pairs gracefully on Windows

When running into invalid Unicode surrogate pairs the text layout code on
Windows ran into massive problems like crashes. This change detects the
situation of an invalid surrogate pair and falls back to treat it as
a simple character instead of requesting a complex glyph fallback.

Modified:
    openoffice/trunk/main/vcl/win/source/gdi/winlayout.cxx

Modified: openoffice/trunk/main/vcl/win/source/gdi/winlayout.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/win/source/gdi/winlayout.cxx?rev=1582374&r1=1582373&r2=1582374&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/win/source/gdi/winlayout.cxx (original)
+++ openoffice/trunk/main/vcl/win/source/gdi/winlayout.cxx Thu Mar 27 16:07:37 2014
@@ -415,12 +415,19 @@ bool SimpleWinLayout::LayoutText( ImplLa
         bool bSurrogate = ((nCharCode >= 0xD800) && (nCharCode <= 0xDFFF));
         if( bSurrogate )
         {
-            if( nCharCode >= 0xDC00 ) // this part of a surrogate pair was already processed
+            // ignore high surrogates, they were already processed with their low surrogates
+            if( nCharCode >= 0xDC00 )
                 continue;
-            nCharCode = 0x10000 + ((pCodes[0] - 0xD800) << 10) + (pCodes[1] - 0xDC00);
-	}
+            // check the second half of the surrogate pair
+            bSurrogate &= (0xDC00 <= pCodes[1]) && (pCodes[1] <= 0xDFFF);
+            // calculate the UTF-32 code of valid surrogate pairs
+            if( bSurrogate )
+                nCharCode = 0x10000 + ((pCodes[0] - 0xD800) << 10) + (pCodes[1] - 0xDC00);
+            else // or fall back to a replacement character
+                nCharCode = '?';
+        }
 
-        // get the advance width for the current UCS-4 code point
+        // get the advance width for the current UTF-32 code point
         int nGlyphWidth = mrWinFontEntry.GetCachedGlyphWidth( nCharCode );
         if( nGlyphWidth == -1 )
         {
@@ -438,7 +445,7 @@ bool SimpleWinLayout::LayoutText( ImplLa
         mpGlyphAdvances[ i ] = nGlyphWidth;
         mnWidth += nGlyphWidth;
 
-        // remaining codes of surrogate pair get a zero width
+        // the second half of surrogate pair gets a zero width
         if( bSurrogate && ((i+1) < mnGlyphCount) )
             mpGlyphAdvances[ i+1 ] = 0;