[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


https://bugs.webkit.org/show_bug.cgi?id=261508

            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