- Revision
- 194839
- Author
- mmaxfi...@apple.com
- Date
- 2016-01-10 21:55:14 -0800 (Sun, 10 Jan 2016)
Log Message
[SVG -> OTF Converter] Parsing failures cause use of incomplete fonts
https://bugs.webkit.org/show_bug.cgi?id=152772
<rdar://problem/24043104>
Reviewed by Simon Fraser.
Source/WebCore:
Originally, if we fail to parse a glyph, we would simply skip the glyph. However, this means that
we will create an incomplete font without all the necessary glyphs. This causes very distressing
text where all the occurances of a particular letter are missing. Instead, we should treat the
entire font as invalid.
Test: fast/text/svg-font-invalid-glyph-path-failure.html
* css/CSSFontFaceSource.cpp:
(WebCore::CSSFontFaceSource::font):
* loader/cache/CachedSVGFont.cpp:
(WebCore::CachedSVGFont::ensureCustomFontData):
* svg/SVGToOTFFontConversion.cpp:
(WebCore::SVGToOTFFontConverter::error):
(WebCore::SVGToOTFFontConverter::transcodeGlyphPaths):
(WebCore::SVGToOTFFontConverter::processGlyphElement):
(WebCore::convertSVGToOTFFont):
* svg/SVGToOTFFontConversion.h:
LayoutTests:
Make sure the font renders as if its invalid.
* fast/text/resources/bustedfont.svg: Added.
* fast/text/svg-font-invalid-glyph-path-failure-expected.html: Added.
* fast/text/svg-font-invalid-glyph-path-failure.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (194838 => 194839)
--- trunk/LayoutTests/ChangeLog 2016-01-11 05:54:03 UTC (rev 194838)
+++ trunk/LayoutTests/ChangeLog 2016-01-11 05:55:14 UTC (rev 194839)
@@ -1,3 +1,17 @@
+2016-01-10 Myles C. Maxfield <mmaxfi...@apple.com>
+
+ [SVG -> OTF Converter] Parsing failures cause use of incomplete fonts
+ https://bugs.webkit.org/show_bug.cgi?id=152772
+ <rdar://problem/24043104>
+
+ Reviewed by Simon Fraser.
+
+ Make sure the font renders as if its invalid.
+
+ * fast/text/resources/bustedfont.svg: Added.
+ * fast/text/svg-font-invalid-glyph-path-failure-expected.html: Added.
+ * fast/text/svg-font-invalid-glyph-path-failure.html: Added.
+
2016-01-10 Yusuke Suzuki <utatane....@gmail.com>
[JSC] Iterating over a Set/Map is too slow
Added: trunk/LayoutTests/fast/text/resources/bustedfont.svg (0 => 194839)
--- trunk/LayoutTests/fast/text/resources/bustedfont.svg (rev 0)
+++ trunk/LayoutTests/fast/text/resources/bustedfont.svg 2016-01-11 05:55:14 UTC (rev 194839)
@@ -0,0 +1,15 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="Litherum" horiz-adv-x="1024">
+<font-face units-per-em="14" ascent="14" descent="0"/>
+<glyph unicode="a" horiz-adv-x="14" d="M0 0v14h14v-14z"/>
+<glyph unicode="e" horiz-adv-x="14" d="M0 0v14D14v-14z"/>
+<glyph unicode="i" horiz-adv-x="14" d="M0 0v14h14v-14z"/>
+<glyph unicode="o" horiz-adv-x="14" d="M0 0v14h14v-14z"/>
+<glyph unicode="u" horiz-adv-x="14" d="M0 0v14h14v-14z"/>
+</font>
+</defs>
+</svg>
Added: trunk/LayoutTests/fast/text/svg-font-invalid-glyph-path-failure-expected.html (0 => 194839)
--- trunk/LayoutTests/fast/text/svg-font-invalid-glyph-path-failure-expected.html (rev 0)
+++ trunk/LayoutTests/fast/text/svg-font-invalid-glyph-path-failure-expected.html 2016-01-11 05:55:14 UTC (rev 194839)
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure that a path parsing failure of (a single glyph of) an SVG font is treated as an invalid font. There should be text below (instead of a big black box).
+<div style="font: 50px Avenir">aeiou</div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/fast/text/svg-font-invalid-glyph-path-failure.html (0 => 194839)
--- trunk/LayoutTests/fast/text/svg-font-invalid-glyph-path-failure.html (rev 0)
+++ trunk/LayoutTests/fast/text/svg-font-invalid-glyph-path-failure.html 2016-01-11 05:55:14 UTC (rev 194839)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: "bustedfont";
+ src: url("resources/bustedfont.svg") format("svg");
+}
+</style>
+</head>
+<body>
+This test makes sure that a path parsing failure of (a single glyph of) an SVG font is treated as an invalid font. There should be text below (instead of a big black box).
+<div style="font: 50px bustedfont, Avenir">aeiou</div>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (194838 => 194839)
--- trunk/Source/WebCore/ChangeLog 2016-01-11 05:54:03 UTC (rev 194838)
+++ trunk/Source/WebCore/ChangeLog 2016-01-11 05:55:14 UTC (rev 194839)
@@ -1,3 +1,29 @@
+2016-01-10 Myles C. Maxfield <mmaxfi...@apple.com>
+
+ [SVG -> OTF Converter] Parsing failures cause use of incomplete fonts
+ https://bugs.webkit.org/show_bug.cgi?id=152772
+ <rdar://problem/24043104>
+
+ Reviewed by Simon Fraser.
+
+ Originally, if we fail to parse a glyph, we would simply skip the glyph. However, this means that
+ we will create an incomplete font without all the necessary glyphs. This causes very distressing
+ text where all the occurances of a particular letter are missing. Instead, we should treat the
+ entire font as invalid.
+
+ Test: fast/text/svg-font-invalid-glyph-path-failure.html
+
+ * css/CSSFontFaceSource.cpp:
+ (WebCore::CSSFontFaceSource::font):
+ * loader/cache/CachedSVGFont.cpp:
+ (WebCore::CachedSVGFont::ensureCustomFontData):
+ * svg/SVGToOTFFontConversion.cpp:
+ (WebCore::SVGToOTFFontConverter::error):
+ (WebCore::SVGToOTFFontConverter::transcodeGlyphPaths):
+ (WebCore::SVGToOTFFontConverter::processGlyphElement):
+ (WebCore::convertSVGToOTFFont):
+ * svg/SVGToOTFFontConversion.h:
+
2016-01-10 Andreas Kling <akl...@apple.com>
Use NeverDestroyed instead of DEPRECATED_DEFINE_STATIC_LOCAL cont'd
Modified: trunk/Source/WebCore/css/CSSFontFaceSource.cpp (194838 => 194839)
--- trunk/Source/WebCore/css/CSSFontFaceSource.cpp 2016-01-11 05:54:03 UTC (rev 194838)
+++ trunk/Source/WebCore/css/CSSFontFaceSource.cpp 2016-01-11 05:55:14 UTC (rev 194839)
@@ -144,8 +144,8 @@
SVGFontElement& fontElement = downcast<SVGFontElement>(*m_svgFontFaceElement->parentNode());
// FIXME: Re-run this when script modifies the element or any of its descendents
// FIXME: We might have already converted this font. Make existing conversions discoverable.
- Vector<char> otfFont = convertSVGToOTFFont(fontElement);
- m_generatedOTFBuffer = SharedBuffer::adoptVector(otfFont);
+ if (auto otfFont = convertSVGToOTFFont(fontElement))
+ m_generatedOTFBuffer = SharedBuffer::adoptVector(otfFont.value());
if (!m_generatedOTFBuffer)
return nullptr;
auto customPlatformData = createFontCustomPlatformData(*m_generatedOTFBuffer);
Modified: trunk/Source/WebCore/loader/cache/CachedSVGFont.cpp (194838 => 194839)
--- trunk/Source/WebCore/loader/cache/CachedSVGFont.cpp 2016-01-11 05:54:03 UTC (rev 194838)
+++ trunk/Source/WebCore/loader/cache/CachedSVGFont.cpp 2016-01-11 05:55:14 UTC (rev 194839)
@@ -92,8 +92,12 @@
maybeInitializeExternalSVGFontElement(remoteURI);
if (!m_externalSVGFontElement)
return false;
- Vector<char> convertedFont = convertSVGToOTFFont(*m_externalSVGFontElement);
- m_convertedFont = SharedBuffer::adoptVector(convertedFont);
+ if (auto convertedFont = convertSVGToOTFFont(*m_externalSVGFontElement))
+ m_convertedFont = SharedBuffer::adoptVector(convertedFont.value());
+ else {
+ m_externalSVGDocument = nullptr;
+ return false;
+ }
#endif
}
Modified: trunk/Source/WebCore/svg/SVGToOTFFontConversion.cpp (194838 => 194839)
--- trunk/Source/WebCore/svg/SVGToOTFFontConversion.cpp 2016-01-11 05:54:03 UTC (rev 194838)
+++ trunk/Source/WebCore/svg/SVGToOTFFontConversion.cpp 2016-01-11 05:55:14 UTC (rev 194839)
@@ -51,13 +51,18 @@
class SVGToOTFFontConverter {
public:
SVGToOTFFontConverter(const SVGFontElement&);
- void convertSVGToOTFFont();
+ bool convertSVGToOTFFont();
Vector<char> releaseResult()
{
return WTFMove(m_result);
}
+ bool error() const
+ {
+ return m_error;
+ }
+
private:
struct GlyphData {
GlyphData(Vector<char>&& charString, const SVGGlyphElement* glyphElement, float horizontalAdvance, float verticalAdvance, FloatRect boundingBox, const String& codepoints)
@@ -257,6 +262,7 @@
unsigned m_tablesAppendedCount;
char m_weight;
bool m_italic;
+ bool m_error { false };
};
static uint16_t roundDownToPowerOfTwo(uint16_t x)
@@ -1269,7 +1275,7 @@
ok = SVGPathParser::parse(source, builder);
if (!ok)
- result.clear();
+ return { };
boundingBox = builder.boundingBox();
@@ -1291,6 +1297,10 @@
Optional<FloatRect> glyphBoundingBox;
auto path = transcodeGlyphPaths(horizontalAdvance, glyphOrMissingGlyphElement, glyphBoundingBox);
+ if (!path.size()) {
+ // It's better to use a fallback font rather than use a font without all its glyphs.
+ m_error = true;
+ }
if (!boundingBox)
boundingBox = glyphBoundingBox;
else if (glyphBoundingBox)
@@ -1521,10 +1531,10 @@
++m_tablesAppendedCount;
}
-void SVGToOTFFontConverter::convertSVGToOTFFont()
+bool SVGToOTFFontConverter::convertSVGToOTFFont()
{
if (m_glyphs.isEmpty())
- return;
+ return false;
uint16_t numTables = 14;
uint16_t roundedNumTables = roundDownToPowerOfTwo(numTables);
@@ -1566,12 +1576,16 @@
// checksumAdjustment: "To compute: set it to 0, calculate the checksum for the 'head' table and put it in the table directory,
// sum the entire font as uint32, then store B1B0AFBA - sum. The checksum for the 'head' table will now be wrong. That is OK."
overwrite32(headTableOffset + 8, 0xB1B0AFBAU - calculateChecksum(0, m_result.size()));
+ return true;
}
-Vector<char> convertSVGToOTFFont(const SVGFontElement& element)
+Optional<Vector<char>> convertSVGToOTFFont(const SVGFontElement& element)
{
SVGToOTFFontConverter converter(element);
- converter.convertSVGToOTFFont();
+ if (converter.error())
+ return Nullopt;
+ if (!converter.convertSVGToOTFFont())
+ return Nullopt;
return converter.releaseResult();
}
Modified: trunk/Source/WebCore/svg/SVGToOTFFontConversion.h (194838 => 194839)
--- trunk/Source/WebCore/svg/SVGToOTFFontConversion.h 2016-01-11 05:54:03 UTC (rev 194838)
+++ trunk/Source/WebCore/svg/SVGToOTFFontConversion.h 2016-01-11 05:55:14 UTC (rev 194839)
@@ -26,13 +26,14 @@
#ifndef SVGToOTFFontConversion_h
#define SVGToOTFFontConversion_h
+#include <wtf/Optional.h>
#include <wtf/Vector.h>
namespace WebCore {
class SVGFontElement;
-Vector<char> convertSVGToOTFFont(const SVGFontElement&);
+Optional<Vector<char>> convertSVGToOTFFont(const SVGFontElement&);
}