summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Dürr <hdu@apache.org>2014-03-27 16:07:37 +0000
committerHerbert Dürr <hdu@apache.org>2014-03-27 16:07:37 +0000
commit913f1fc4b1362f6e91595af5ae10c4cba79fd355 (patch)
tree98904fe10882a0a0daf0b3671683317072d35293
parenta5df560f6a44de04a66da1dd05960ff2ee6bd2ba (diff)
#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.
Notes
-rw-r--r--vcl/win/source/gdi/winlayout.cxx17
1 files changed, 12 insertions, 5 deletions
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index 7fab9292f41b..51db718e72e2 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -415,12 +415,19 @@ bool SimpleWinLayout::LayoutText( ImplLayoutArgs& rArgs )
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( ImplLayoutArgs& rArgs )
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;