[Webkit-unassigned] [Bug 261508] New: Loading disallowed FontFace from ArrayBuffer in Lockdown Mode doesn't reject promise

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Wed Sep 13 06:24:07 PDT 2023


            Bug ID: 261508
           Summary: Loading disallowed FontFace from ArrayBuffer in
                    Lockdown Mode doesn't reject promise
           Product: WebKit
           Version: Safari 16
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: CSS
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: pajowu at pajowu.de

Created attachment 467671

  --> https://bugs.webkit.org/attachment.cgi?id=467671&action=review

Minimal Reproducing Example

The CSS Font Loading API can be used to load fonts via JS using the `FontFace` constructor. The constructor is passed a source, which can either be a css string or `BinaryData` (an ArrayBuffer or ArrayBufferView). According to the spec[1], if BinaryData is passed, the data is directly stored in the FontFaces internal `[[Data]]` slot and then parsed asynchronously. After this parsing finished, the fonts `loading` promise shall be resolved (either fulfilled if the parsing was successful or rejected otherwise). According to the spec, the `load()` method of a `FontFace` is a no-op if the font-face is constructed from BinaryData[2].

In conclusion: According to the spec, if a FontFace is constructed from BinaryData, its `loaded` property can be used immediately without calling the `load()` method and is guaranteed to be resolved.

However, when loading a custom FontFace from BinaryData in Lockdown Mode, the `loaded` promise is never resolved until `load()` is called.

A simple example to reproduce this is attached as `mre.html`. The page should show "font.loaded fulfilled" or "font.loaded rejected" almost immediately after loading. However in current Safari, it is stock on `Loading font ...` forever. Adding a `font.load()` at the end fixes this, making the promise fail as expected immediately.


The following is educated speculation, as I'm not familiar with the webkit codebase.

The problem seems to be the code in [3]/[4], which checks if the loaded font is within a number of allow-listed webfonts[5] and otherwise returns. My impression is that instead of returning empty, this should reject the `loaded` promise (`return Exception { NetworkError }`)

[1]: https://www.w3.org/TR/css-font-loading/#font-face-constructor
[2]: https://www.w3.org/TR/css-font-loading/#font-face-load
[3]: https://github.com/WebKit/WebKit/blob/d68d5c148eb3616448ae8d8e28408c0340823181/Source/WebCore/css/FontFace.cpp#L88-L90
[3]: https://github.com/WebKit/WebKit/blob/d68d5c148eb3616448ae8d8e28408c0340823181/Source/WebCore/css/FontFace.cpp#L82-L83
[5]: https://github.com/WebKit/WebKit/blob/main/Source/WebCore/loader/cache/AllowedFonts.cpp#L41

You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20230913/23f33709/attachment.htm>

More information about the webkit-unassigned mailing list