Title: [117788] trunk/Source/WebCore
Revision
117788
Author
[email protected]
Date
2012-05-21 09:06:50 -0700 (Mon, 21 May 2012)

Log Message

SVGTextRunRenderingContext can return null font, calling code asserts not null
https://bugs.webkit.org/show_bug.cgi?id=86738

Reviewed by Nikolas Zimmermann.

SVGTextRunRenderingContext::glyphDataForCharacter was returning a glyph with
null font data for numerous code paths. It seems that it was doing so
whenever it detected null fontData, rather than try to continue.
Calling code would then immediately assert on this null fontData.

This patch refactors SVGTextRunRenderingContext::glyphDataForCharacter
so that it never returns null font data, adding an assertion to that
effect. In particular, when the font data is null the code will reach
the fallback glyph calculations.

Refactoring covered by existing tests. A previously crashing test, svg/custom/acid3-test-77.html, no longer crashes.

* rendering/svg/SVGTextRunRenderingContext.cpp:
(WebCore::SVGTextRunRenderingContext::glyphDataForCharacter):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (117787 => 117788)


--- trunk/Source/WebCore/ChangeLog	2012-05-21 16:06:42 UTC (rev 117787)
+++ trunk/Source/WebCore/ChangeLog	2012-05-21 16:06:50 UTC (rev 117788)
@@ -1,3 +1,25 @@
+2012-05-21  Stephen Chenney  <[email protected]>
+
+        SVGTextRunRenderingContext can return null font, calling code asserts not null
+        https://bugs.webkit.org/show_bug.cgi?id=86738
+
+        Reviewed by Nikolas Zimmermann.
+
+        SVGTextRunRenderingContext::glyphDataForCharacter was returning a glyph with
+        null font data for numerous code paths. It seems that it was doing so
+        whenever it detected null fontData, rather than try to continue.
+        Calling code would then immediately assert on this null fontData.
+
+        This patch refactors SVGTextRunRenderingContext::glyphDataForCharacter
+        so that it never returns null font data, adding an assertion to that
+        effect. In particular, when the font data is null the code will reach
+        the fallback glyph calculations.
+
+        Refactoring covered by existing tests. A previously crashing test, svg/custom/acid3-test-77.html, no longer crashes.
+
+        * rendering/svg/SVGTextRunRenderingContext.cpp:
+        (WebCore::SVGTextRunRenderingContext::glyphDataForCharacter):
+
 2012-05-21  Ilya Tikhonovsky  <[email protected]>
 
         Web Inspector: switch buildDominatedNodes function to front-end calculated _dominatorsTree

Modified: trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp (117787 => 117788)


--- trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp	2012-05-21 16:06:42 UTC (rev 117787)
+++ trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp	2012-05-21 16:06:50 UTC (rev 117788)
@@ -179,15 +179,16 @@
 
     pair<GlyphData, GlyphPage*> pair = font.glyphDataAndPageForCharacter(character, mirror);
     GlyphData glyphData = pair.first;
-    if (!glyphData.fontData)
-        return glyphData;
 
+    // Check if we have the missing glyph data, in which case we can just return.
     GlyphData missingGlyphData = primaryFont->missingGlyphData();
-    if (glyphData.glyph == missingGlyphData.glyph && glyphData.fontData == missingGlyphData.fontData)
+    if (glyphData.glyph == missingGlyphData.glyph && glyphData.fontData == missingGlyphData.fontData) {
+        ASSERT(glyphData.fontData);
         return glyphData;
+    }
 
     // Characters enclosed by an <altGlyph> element, may not be registered in the GlyphPage.
-    if (!glyphData.fontData->isSVGFont()) {
+    if (glyphData.fontData && !glyphData.fontData->isSVGFont()) {
         if (TextRun::RenderingContext* renderingContext = run.renderingContext()) {
             RenderObject* renderObject = static_cast<SVGTextRunRenderingContext*>(renderingContext)->renderer();
             RenderObject* parentRenderObject = renderObject->isText() ? renderObject->parent() : renderObject;
@@ -199,24 +200,25 @@
         }
     }
 
-    if (!glyphData.fontData || !glyphData.fontData->isSVGFont())
-        return glyphData;
-
     const SimpleFontData* fontData = glyphData.fontData;
+    if (fontData) {
+        if (!fontData->isSVGFont())
+            return glyphData;
 
-    SVGFontElement* fontElement = 0;
-    SVGFontFaceElement* fontFaceElement = 0;
+        SVGFontElement* fontElement = 0;
+        SVGFontFaceElement* fontFaceElement = 0;
 
-    const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
-    if (!fontElement || !fontFaceElement)
-        return glyphData;
+        const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
+        if (!fontElement || !fontFaceElement)
+            return glyphData;
 
-    // If we got here, we're dealing with a glyph defined in a SVG Font.
-    // The returned glyph by glyphDataAndPageForCharacter() is a glyph stored in the SVG Font glyph table.
-    // This doesn't necessarily mean the glyph is suitable for rendering/measuring in this context, its
-    // arabic-form/orientation/... may not match, we have to apply SVG Glyph selection to discover that.
-    if (svgFontData->applySVGGlyphSelection(iterator, glyphData, mirror, currentCharacter, advanceLength))
-        return glyphData;
+        // If we got here, we're dealing with a glyph defined in a SVG Font.
+        // The returned glyph by glyphDataAndPageForCharacter() is a glyph stored in the SVG Font glyph table.
+        // This doesn't necessarily mean the glyph is suitable for rendering/measuring in this context, its
+        // arabic-form/orientation/... may not match, we have to apply SVG Glyph selection to discover that.
+        if (svgFontData->applySVGGlyphSelection(iterator, glyphData, mirror, currentCharacter, advanceLength))
+            return glyphData;
+    }
 
     GlyphPage* page = pair.second;
     ASSERT(page);
@@ -240,6 +242,7 @@
     page->setGlyphDataForCharacter(character, glyphData.glyph, fontData);
     fontList->setGlyphPageZero(originalGlyphPageZero);
     fontList->setGlyphPages(originalGlyphPages);
+    ASSERT(fallbackGlyphData.fontData);
     return fallbackGlyphData;
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to