[SVG -> OTF Converter] Crashes when SVG font is invalid
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Jan 2015 22:51:47 +0000 (22:51 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Jan 2015 22:51:47 +0000 (22:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140378

Reviewed by Antti Koivisto.

Because CachedSVGFonts are cached, they have to be able to be used
in subsequent documents regardless how the first document left it.

Tests: fast/css/font-face-svg-decoding-error.html
       svg/custom/svg-fonts-in-html.html
       svg/text/text-overflow-ellipsis-svgfont-kerning-ligatures.html

* loader/cache/CachedFont.cpp:
(WebCore::CachedFont::ensureCustomFontData):
* loader/cache/CachedFont.h:
* loader/cache/CachedSVGFont.cpp:
(WebCore::CachedSVGFont::getFontData):
(WebCore::CachedSVGFont::ensureCustomFontData):
(WebCore::CachedSVGFont::maybeInitializeExternalSVGFontElement):
* loader/cache/CachedSVGFont.h:

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

Source/WebCore/ChangeLog
Source/WebCore/loader/cache/CachedFont.cpp
Source/WebCore/loader/cache/CachedFont.h
Source/WebCore/loader/cache/CachedSVGFont.cpp
Source/WebCore/loader/cache/CachedSVGFont.h

index aac63dfa96187b4fed20547fe595c7f69b5ca892..8b632f0341df1991da7cc34197343dd7f756c2d5 100644 (file)
@@ -1,3 +1,26 @@
+2015-01-17  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [SVG -> OTF Converter] Crashes when SVG font is invalid
+        https://bugs.webkit.org/show_bug.cgi?id=140378
+
+        Reviewed by Antti Koivisto.
+
+        Because CachedSVGFonts are cached, they have to be able to be used
+        in subsequent documents regardless how the first document left it.
+
+        Tests: fast/css/font-face-svg-decoding-error.html
+               svg/custom/svg-fonts-in-html.html
+               svg/text/text-overflow-ellipsis-svgfont-kerning-ligatures.html
+
+        * loader/cache/CachedFont.cpp:
+        (WebCore::CachedFont::ensureCustomFontData):
+        * loader/cache/CachedFont.h:
+        * loader/cache/CachedSVGFont.cpp:
+        (WebCore::CachedSVGFont::getFontData):
+        (WebCore::CachedSVGFont::ensureCustomFontData):
+        (WebCore::CachedSVGFont::maybeInitializeExternalSVGFontElement):
+        * loader/cache/CachedSVGFont.h:
+
 2015-01-17  Chris Dumez  <cdumez@apple.com>
 
         Converting time, angle and frequency units in CSS calc() function
index 2c6716245f4027ae40de4446b0ec6b25725d12dc..2be4ecd375c13350bffd042aab56e18adaeaa949 100644 (file)
@@ -94,13 +94,13 @@ void CachedFont::beginLoadIfNeeded(CachedResourceLoader* dl)
 
 bool CachedFont::ensureCustomFontData(bool, const AtomicString&)
 {
-    return ensureCustomFontData(m_data.copyRef());
+    return ensureCustomFontData(m_data.get());
 }
 
-bool CachedFont::ensureCustomFontData(RefPtr<SharedBuffer>&& data)
+bool CachedFont::ensureCustomFontData(SharedBuffer* data)
 {
     if (!m_fontData && !errorOccurred() && !isLoading() && data) {
-        RefPtr<SharedBuffer> buffer = data;
+        RefPtr<SharedBuffer> buffer(data);
 
 #if (!PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED <= 1090) && (!PLATFORM(IOS) || __IPHONE_OS_VERSION_MIN_REQUIRED < 80000)
         if (isWOFF(buffer.get())) {
index c2c606685d8999c2f008e6577d71cd8a1e8d7a49..5b6f4184e082899a8060a1cb5f61508cedcb86e7 100644 (file)
@@ -57,7 +57,7 @@ public:
 protected:
     FontPlatformData platformDataFromCustomData(float size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
 
-    bool ensureCustomFontData(RefPtr<SharedBuffer>&& data);
+    bool ensureCustomFontData(SharedBuffer* data);
 
 private:
     virtual void checkNotify() override;
index ed24eaf868a72274b1cb630af554247094cbc3cb..91248e69fcde5cfc5fa58162526da323062028cd 100644 (file)
@@ -53,13 +53,16 @@ CachedSVGFont::CachedSVGFont(const ResourceRequest& resourceRequest, SessionID s
 
 PassRefPtr<SimpleFontData> CachedSVGFont::getFontData(const FontDescription& fontDescription, const AtomicString& remoteURI, bool syntheticBold, bool syntheticItalic, bool externalSVG)
 {
-#if !ENABLE(SVG_OTF_CONVERTER)
+#if ENABLE(SVG_OTF_CONVERTER)
+    if (!externalSVG || firstFontFace(remoteURI))
+        return CachedFont::getFontData(fontDescription, remoteURI, syntheticBold, syntheticItalic, externalSVG);
+#else
     if (!externalSVG)
-#endif
         return CachedFont::getFontData(fontDescription, remoteURI, syntheticBold, syntheticItalic, externalSVG);
 
     if (SVGFontFaceElement* firstFontFace = this->firstFontFace(remoteURI))
         return SimpleFontData::create(std::make_unique<SVGFontData>(firstFontFace), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic);
+#endif
     return nullptr;
 }
 
@@ -79,21 +82,31 @@ bool CachedSVGFont::ensureCustomFontData(bool externalSVG, const AtomicString& r
         m_externalSVGDocument = SVGDocument::create(nullptr, URL());
         RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
         m_externalSVGDocument->setContent(decoder->decodeAndFlush(m_data->data(), m_data->size()));
+#if !ENABLE(SVG_OTF_CONVERTER)
         if (decoder->sawError())
             m_externalSVGDocument = nullptr;
-#if ENABLE(SVG_OTF_CONVERTER)
-        firstFontFace(remoteURI); // Sets m_externalSVGFontElement
-        if (m_externalSVGFontElement) {
-            Vector<char> convertedFont = convertSVGToOTFFont(*m_externalSVGFontElement);
-            return CachedFont::ensureCustomFontData(SharedBuffer::adoptVector(convertedFont));
-        }
+#else
+        if (decoder->sawError())
+            m_externalSVGDocument = nullptr;
+        else
+            maybeInitializeExternalSVGFontElement(remoteURI);
+        if (!m_externalSVGFontElement)
+            return false;
+        Vector<char> convertedFont = convertSVGToOTFFont(*m_externalSVGFontElement);
+        m_convertedFont = SharedBuffer::adoptVector(convertedFont);
 #endif
     }
+
+#if !ENABLE(SVG_OTF_CONVERTER)
     return m_externalSVGDocument;
+#else
+    return m_externalSVGDocument && CachedFont::ensureCustomFontData(m_convertedFont.get());
+#endif
 }
 
 SVGFontElement* CachedSVGFont::getSVGFontById(const String& fontName) const
 {
+    ASSERT(m_externalSVGDocument);
     auto elements = descendantsOfType<SVGFontElement>(*m_externalSVGDocument);
 
     if (fontName.isEmpty())
@@ -106,17 +119,21 @@ SVGFontElement* CachedSVGFont::getSVGFontById(const String& fontName) const
     return nullptr;
 }
 
-SVGFontFaceElement* CachedSVGFont::firstFontFace(const AtomicString& remoteURI)
+SVGFontElement* CachedSVGFont::maybeInitializeExternalSVGFontElement(const AtomicString& remoteURI)
 {
-    if (!m_externalSVGFontElement) {
-        String fragmentIdentifier;
-        size_t start = remoteURI.find('#');
-        if (start != notFound)
-            fragmentIdentifier = remoteURI.string().substring(start + 1);
-        m_externalSVGFontElement = getSVGFontById(fragmentIdentifier);
-    }
+    if (m_externalSVGFontElement)
+        return m_externalSVGFontElement;
+    String fragmentIdentifier;
+    size_t start = remoteURI.find('#');
+    if (start != notFound)
+        fragmentIdentifier = remoteURI.string().substring(start + 1);
+    m_externalSVGFontElement = getSVGFontById(fragmentIdentifier);
+    return m_externalSVGFontElement;
+}
 
-    if (!m_externalSVGFontElement)
+SVGFontFaceElement* CachedSVGFont::firstFontFace(const AtomicString& remoteURI)
+{
+    if (!maybeInitializeExternalSVGFontElement(remoteURI))
         return nullptr;
 
     if (auto* firstFontFace = childrenOfType<SVGFontFaceElement>(*m_externalSVGFontElement).first())
index a83af37ecba86cf9566dd8d1f07d7e09202c9376..7bc3aa2b9fda0872a400b10faf3f12f2b3ae2a7c 100644 (file)
@@ -47,8 +47,12 @@ private:
 
     SVGFontElement* getSVGFontById(const String&) const;
 
+    SVGFontElement* maybeInitializeExternalSVGFontElement(const AtomicString& remoteURI);
     SVGFontFaceElement* firstFontFace(const AtomicString& remoteURI);
 
+#if ENABLE(SVG_OTF_CONVERTER)
+    RefPtr<SharedBuffer> m_convertedFont;
+#endif
     RefPtr<SVGDocument> m_externalSVGDocument;
     SVGFontElement* m_externalSVGFontElement;
 };