Bug 1412090 - patch 2.1 - Work around FcNameParse bug in fontconfig versions around 2.11.0, by escaping any leading space in the encoded charset element. r=lsalzman
authorJonathan Kew <jkew@mozilla.com>
Sun, 12 Nov 2017 21:35:25 +0000
changeset 391473 c32418d902300ac0a8720a087900cae6daa28de9
parent 391472 e549fef3f2a283d70c04ec6d66121ccc94ef115b
child 391474 3a0e53eec16a4df3e36a2cbbf44a3ff0d25e8c50
push id32888
push usernbeleuzu@mozilla.com
push dateMon, 13 Nov 2017 09:54:04 +0000
treeherdermozilla-central@fc194660762d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1412090
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1412090 - patch 2.1 - Work around FcNameParse bug in fontconfig versions around 2.11.0, by escaping any leading space in the encoded charset element. r=lsalzman
gfx/thebes/gfxFcPlatformFontList.cpp
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -1430,22 +1430,50 @@ gfxFcPlatformFontList::InitFontListForPl
         FcChar8* lastFamilyName = (FcChar8*)"";
         RefPtr<gfxFontconfigFontFamily> fontFamily;
         nsAutoString familyName;
 
         // Get font list that was passed during XPCOM startup
         // or in an UpdateFontList message.
         auto& fontList = dom::ContentChild::GetSingleton()->SystemFontList();
 
+        // For fontconfig versions between 2.10.94 and 2.11.1 inclusive,
+        // we need to escape any leading space in the charset element,
+        // otherwise FcNameParse will fail. :(
+        //
+        // The bug was introduced on 2013-05-24 by
+        //   https://cgit.freedesktop.org/fontconfig/commit/?id=cd9b1033a68816a7acfbba1718ba0aa5888f6ec7
+        //   "Bug 64906 - FcNameParse() should ignore leading whitespace in parameters"
+        // because ignoring a leading space in the encoded value of charset
+        // causes erroneous decoding of the whole element.
+        // This first shipped in version 2.10.94, and was eventually fixed as
+        // a side-effect of switching to the "human-readable" representation of
+        // charsets on 2014-07-03 in
+        //   https://cgit.freedesktop.org/fontconfig/commit/?id=e708e97c351d3bc9f7030ef22ac2f007d5114730
+        //   "Change charset parse/unparse format to be human readable"
+        // (with a followup fix next day) which means a leading space is no
+        // longer significant. This fix landed after 2.11.1 had been shipped,
+        // so the first version tag without the bug is 2.11.91.
+        int fcVersion = FcGetVersion();
+        bool fcCharsetParseBug = fcVersion >= 21094 && fcVersion <= 21101;
+
         for (SystemFontListEntry& fle : fontList) {
             MOZ_ASSERT(fle.type() ==
                        SystemFontListEntry::Type::TFontPatternListEntry);
             FontPatternListEntry& fpe(fle);
+            nsCString& patternStr = fpe.pattern();
+            if (fcCharsetParseBug) {
+                int32_t index = patternStr.Find(":charset= ");
+                if (index != kNotFound) {
+                    // insert backslash after the =, before the space
+                    patternStr.Insert('\\', index + 9);
+                }
+            }
             FcPattern* pattern =
-                FcNameParse((const FcChar8*)fpe.pattern().get());
+                FcNameParse((const FcChar8*)patternStr.get());
             AddPatternToFontList(pattern, lastFamilyName, familyName,
                                  fontFamily, fpe.appFontFamily());
             FcPatternDestroy(pattern);
         }
 
         LOG_FONTLIST(("got font list from chrome process: "
                       "%u faces in %u families",
                       (unsigned)fontList.Length(), mFontFamilies.Count()));