Bug 156605 - [CSS Font Loading] FontFace's promise may never be resolved/rejected if Content Security Policy blocks all the URLs
Summary: [CSS Font Loading] FontFace's promise may never be resolved/rejected if Conte...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Text (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Myles C. Maxfield
URL:
Keywords:
Depends on:
Blocks: 156643
  Show dependency treegraph
 
Reported: 2016-04-14 15:57 PDT by Myles C. Maxfield
Modified: 2016-04-15 14:28 PDT (History)
3 users (show)

See Also:


Attachments
Run this inside Github.com (835 bytes, text/html)
2016-04-14 15:57 PDT, Myles C. Maxfield
no flags Details
Needs a test (1.29 KB, patch)
2016-04-14 16:16 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch (4.28 KB, patch)
2016-04-15 12:06 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch (4.29 KB, patch)
2016-04-15 12:14 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch (4.29 KB, patch)
2016-04-15 13:49 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Patch (4.21 KB, patch)
2016-04-15 13:51 PDT, Myles C. Maxfield
dbates: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Myles C. Maxfield 2016-04-14 15:57:03 PDT
Created attachment 276444 [details]
Run this inside Github.com

Run the attached JavaScript file inside the inspector when it's attached to github.com (github has CSP).
Comment 2 Myles C. Maxfield 2016-04-14 15:59:33 PDT
If CSP blocks all the URLs, we'll create a CSSFontFace without any CSSFontFaceSources.
Comment 3 Myles C. Maxfield 2016-04-14 16:02:38 PDT
This means that CSSFontFace::pump() will never execute its loop, so the CSSFontFace's status will still be Pending. Therefore, we never call setStatus() with a terminal state, so we never resolve / reject the promise.
Comment 4 Myles C. Maxfield 2016-04-14 16:07:16 PDT
The spec isn't quite clear what to do in this case. It seems like the load should fail, causing the promise to be rejected.
Comment 5 Myles C. Maxfield 2016-04-14 16:16:57 PDT
Created attachment 276447 [details]
Needs a test
Comment 6 Myles C. Maxfield 2016-04-14 16:33:17 PDT
(In reply to comment #5)
> Created attachment 276447 [details]
> Needs a test

Talking with dbates, the load should fail.
Comment 7 Myles C. Maxfield 2016-04-15 12:06:54 PDT
Created attachment 276490 [details]
Patch
Comment 8 Myles C. Maxfield 2016-04-15 12:14:26 PDT
Created attachment 276491 [details]
Patch
Comment 9 Daniel Bates 2016-04-15 12:35:07 PDT
Comment on attachment 276491 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=276491&action=review

> LayoutTests/fast/text/font-loading-csp-block-all.html:16
> +var globalVariable;

The name of this variable is generic and does not convey its purpose. Can we come up with a better name for this variable? Maybe exception?

> LayoutTests/fast/text/font-loading-csp-block-all.html:33
> +}, 10000);

A timeout of 10 seconds is excessive. I am not at a computer with a checkout at he moment.  What do we do in other tests that use promises?
Comment 10 Myles C. Maxfield 2016-04-15 13:49:49 PDT
Created attachment 276504 [details]
Patch
Comment 11 Myles C. Maxfield 2016-04-15 13:50:41 PDT
Comment on attachment 276504 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=276504&action=review

> LayoutTests/fast/text/font-loading-csp-block-all.html:15
> +var promiseFired = false;

This is unnecessary anymore.
Comment 12 Myles C. Maxfield 2016-04-15 13:51:15 PDT
Created attachment 276506 [details]
Patch
Comment 13 Daniel Bates 2016-04-15 14:12:42 PDT
Comment on attachment 276506 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=276506&action=review

> Source/WebCore/css/CSSFontFace.cpp:462
> +    if (!m_sources.size() && m_status == Status::Pending)

Can m_sources.size() change while executing this function? I assume it can since we repeatedly compute it on each loop iteration, here, and on line 464 (below). If we can assume that it will not change, thence should cache its value once and use it throughout this function. Otherwise, we should use m_sources.isEmpty() here instead of checking if the size of m_sources is zero.

> Source/WebCore/css/CSSFontFace.cpp:466
>      return m_sources.size();

I know this this is not part of the patch. Is it necessary to compute m_sources.size() here?

> LayoutTests/fast/text/font-loading-csp-block-all.html:4
> +<meta http-equiv="Content-Security-Policy" content="font-src 'none';">

Nit: The trailing semicolon is not necessary since the policy consists of exactly one directive. Semicolons are used to separate directives.

> LayoutTests/fast/text/font-loading-csp-block-all.html:13
> +var face = new FontFace('WebFont', "url(../../resources/Ahem.woff) format('woff')", { });

Nit: 'WebFont' => "WebFont"
(notice the use of double quotes to be consistent with the quoting style used for other string literals in this patch)
Comment 14 Myles C. Maxfield 2016-04-15 14:22:04 PDT
Comment on attachment 276506 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=276506&action=review

>> Source/WebCore/css/CSSFontFace.cpp:462
>> +    if (!m_sources.size() && m_status == Status::Pending)
> 
> Can m_sources.size() change while executing this function? I assume it can since we repeatedly compute it on each loop iteration, here, and on line 464 (below). If we can assume that it will not change, thence should cache its value once and use it throughout this function. Otherwise, we should use m_sources.isEmpty() here instead of checking if the size of m_sources is zero.

It can't change here, but a cache is unnecessary because the call is inlined.

But you're right about isEmpty(), that is a better name.
Comment 15 Myles C. Maxfield 2016-04-15 14:28:03 PDT
Committed r199611: <http://trac.webkit.org/changeset/199611>