Crash in CGContextShowGlyphsWithAdvances when passing kCGFontIndexInvalid
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 31 Mar 2015 18:53:25 +0000 (18:53 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 31 Mar 2015 18:53:25 +0000 (18:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=143114

This is a workaround for <rdar://problem/20230073>. Please remove when it is no longer necessary.

Reviewed by Alexey Proskuryakov.

Covered by:
compositing/regions/floated-region-with-transformed-child.html
compositing/regions/floated-region-with-transformed-child-expected.html
fast/regions/counters/extract-ordered-lists-in-regions-explicit-counters-005.html
fast/regions/counters/extract-ordered-lists-in-regions-explicit-counters-005-expected.html
fast/regions/overflow/overflow-content-transform-rotate.html
fast/regions/overflow/overflow-content-transform-rotate-expected.html

* platform/graphics/GlyphBuffer.h:
(WebCore::GlyphBuffer::shrink): Performing shaping may remove glyphs, so we need to shrink the GlyphBuffer.
* platform/graphics/WidthIterator.cpp:
(WebCore::applyFontTransforms): Filter out kCGFontIndexInvalid.
(WebCore::WidthIterator::advanceInternal): Moved code into applyFontTransforms, and trigger the
shrink of the GlyphBuffer.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182192 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/GlyphBuffer.h
Source/WebCore/platform/graphics/WidthIterator.cpp

index d571404ae2b824ff2e04ced669e9696614c76533..5da32a386b8f858c86d0918ab9ba2c581e30226f 100644 (file)
@@ -1,3 +1,27 @@
+2015-03-31  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Crash in CGContextShowGlyphsWithAdvances when passing kCGFontIndexInvalid
+        https://bugs.webkit.org/show_bug.cgi?id=143114
+
+        This is a workaround for <rdar://problem/20230073>. Please remove when it is no longer necessary.
+
+        Reviewed by Alexey Proskuryakov.
+
+        Covered by:
+        compositing/regions/floated-region-with-transformed-child.html
+        compositing/regions/floated-region-with-transformed-child-expected.html
+        fast/regions/counters/extract-ordered-lists-in-regions-explicit-counters-005.html
+        fast/regions/counters/extract-ordered-lists-in-regions-explicit-counters-005-expected.html
+        fast/regions/overflow/overflow-content-transform-rotate.html
+        fast/regions/overflow/overflow-content-transform-rotate-expected.html
+
+        * platform/graphics/GlyphBuffer.h:
+        (WebCore::GlyphBuffer::shrink): Performing shaping may remove glyphs, so we need to shrink the GlyphBuffer.
+        * platform/graphics/WidthIterator.cpp:
+        (WebCore::applyFontTransforms): Filter out kCGFontIndexInvalid.
+        (WebCore::WidthIterator::advanceInternal): Moved code into applyFontTransforms, and trigger the
+        shrink of the GlyphBuffer.
+
 2015-03-31  Beth Dakin  <bdakin@apple.com>
 
         REGRESSION (r173484): Reducing content of scrollable region does not reset scroll 
index 946e245637a8fd502fc2762580871a8177246cb7..283bc3fe82600d8225fc418b634f4b2d308ec384 100644 (file)
@@ -202,6 +202,18 @@ public:
         return (*m_offsetsInString)[index];
     }
 
+    void shrink(int truncationPoint)
+    {
+        m_font.shrink(truncationPoint);
+        m_glyphs.shrink(truncationPoint);
+        m_advances.shrink(truncationPoint);
+        if (m_offsetsInString)
+            m_offsetsInString->shrink(truncationPoint);
+#if PLATFORM(WIN)
+        m_offsets.shrink(truncationPoint);
+#endif
+    }
+
 private:
     void swap(int index1, int index2)
     {
index fcf634d6ede91abaa42bf2bef9ae363c5411603b..b22d29d2fe802cc5f6f9f90dc02822d1fb26c687 100644 (file)
@@ -108,8 +108,10 @@ static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int&
         return 0;
 
     int glyphBufferSize = glyphBuffer->size();
-    if (glyphBuffer->size() <= lastGlyphCount + 1)
+    if (glyphBuffer->size() <= lastGlyphCount + 1) {
+        lastGlyphCount = glyphBufferSize;
         return 0;
+    }
 
     GlyphBufferAdvance* advances = glyphBuffer->advances(0);
     float widthDifference = 0;
@@ -146,6 +148,19 @@ static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int&
     }
     charactersTreatedAsSpace.clear();
 
+#if PLATFORM(MAC) || PLATFORM(IOS)
+    // Workaround for <rdar://problem/20230073> FIXME: Please remove this when no longer needed.
+    GlyphBufferGlyph* glyphs = glyphBuffer->glyphs(0);
+    int filteredIndex = lastGlyphCount;
+    for (int i = lastGlyphCount; i < glyphBufferSize; ++i) {
+        glyphs[filteredIndex] = glyphs[i];
+        advances[filteredIndex] = advances[i];
+        if (glyphs[filteredIndex] != kCGFontIndexInvalid)
+            ++filteredIndex;
+    }
+    glyphBufferSize = filteredIndex;
+#endif
+
     for (int i = lastGlyphCount; i < glyphBufferSize; ++i)
         widthDifference += advances[i].width();
 
@@ -207,7 +222,8 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
         if (font != lastFontData && width) {
             if (shouldApplyFontTransforms()) {
                 m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, *this, m_typesettingFeatures, charactersTreatedAsSpace);
-                lastGlyphCount = glyphBuffer->size(); // applyFontTransforms doesn't update when there had been only one glyph.
+                if (glyphBuffer)
+                    glyphBuffer->shrink(lastGlyphCount);
             }
 
             lastFontData = font;
@@ -325,8 +341,11 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
         }
     }
 
-    if (shouldApplyFontTransforms())
+    if (shouldApplyFontTransforms()) {
         m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, *this, m_typesettingFeatures, charactersTreatedAsSpace);
+        if (glyphBuffer)
+            glyphBuffer->shrink(lastGlyphCount);
+    }
 
     unsigned consumedCharacters = textIterator.currentCharacter() - m_currentCharacter;
     m_currentCharacter = textIterator.currentCharacter();