Browser OTS rejections for WOFF2 but not WOFF

I've been seeing Chrome and Firefox rejecting a lot of WOFF2 files lately, for OTS (OpenType Sanitiser) failures. But this is confusing, because the browser will fall back to the WOFF generated from the same source font, which sails through without a problem.

I have a test page using Bungee Shade from Google Fonts if you want to see this in action. In the case of Bungee, the sanitiser is removing one of the cmap subformat tables. Open Sans also fails this test for having a too-big kern table. Note that in both of these cases, OTS still reports the fonts as "passing" since the fonts are still valid after the modifications.

If I run the TTFs through OTS before generating the WOFFs, then everything works fine.

The original WOFF2 works fine in Edge on Windows 10, which doesn't use OTS.

Firefox shows these errors:
downloadable font: Failed to convert WOFF 2.0 font to SFNT (font-family: "TestWoff2" style:normal weight:normal stretch:normal src index:0) source: http://test.chrislewis.codes/woff2/bungee-web/BungeeShade-Regular.woff2 woff2:12:24

downloadable font: rejected by sanitizer (font-family: "TestWoff2" style:normal weight:normal stretch:normal src index:0) source: http://test.chrislewis.codes/woff2/bungee-web/BungeeShade-Regular.woff2 woff2:12:24
Anybody here know why WOFF2 gets this strict treatment but the same font in WOFF format works?

Comments

  • There is WOFF2-decoding bug in the version of OTS currently used by web browsers that causes it to be unable to decode WOFF2 fonts that report decompressed data size or total font size that is smaller than the actual decoded size. Latest revisions of the spec relaxed the wording of the related fields, but OTS wasn’t updated to handle this until very recently and browsers did not pick this up.

    You should report this against Firefox/Chrome. it is also possible to work around this limitation in the font.
  • Thanks! For now I'll run the fonts through OTS before doing the WOFF encoding.
  • Chris Lewis
    Chris Lewis Posts: 13
    edited September 2016
    Update! The problem wasn't OTS at all. The original font's glyf table entries were not padded to 4 bytes, so when the font was reconstructed by the WOFF2 decoding (which applies 4-byte padding), the file sizes didn't match. Fixed it by doing a quick padding of glyf to 4 bytes just before the WOFF2 conversion and now my tests work.

    Many thanks to @Khaled Hosny and Myles Maxfield of the Safari team for helping me figure this out!!
  • Khaled Hosny
    Khaled Hosny Posts: 289
    edited September 2016
    Though padding to 4 bytes is not a requirement. What is happening here is that if the WOFF 2 decoder uses a different glyph badding than the original font (the original padding is not known time of decoding) then the origLength of the glyf table will be different. WOFF 2 decoder used to reject the font in this case, but latest revisions of the spec treats origLength as a mere hint and the decoder should be able to decode the font even if it had a bad value.

    So padding to glyphs to 4 bytes is a good workaround in this cases, but a conforming implementation should accept the font regardless of the padding used.