RESOLVED FIXED 155009
[Font Loading] Crash when a single load request causes multiple fonts to fail loading
https://bugs.webkit.org/show_bug.cgi?id=155009
Summary [Font Loading] Crash when a single load request causes multiple fonts to fail...
Myles C. Maxfield
Reported 2016-03-03 20:57:30 PST
[Font Loading] Crash when multiple fonts fail
Attachments
Patch (5.64 KB, patch)
2016-03-03 20:59 PST, Myles C. Maxfield
no flags
Archive of layout-test-results from ews116 for mac-yosemite (818.54 KB, application/zip)
2016-03-03 21:58 PST, Build Bot
no flags
WIP (6.01 KB, patch)
2016-03-04 00:33 PST, Myles C. Maxfield
no flags
Patch (13.85 KB, patch)
2016-03-04 10:12 PST, Myles C. Maxfield
no flags
Patch (13.86 KB, patch)
2016-03-04 10:27 PST, Myles C. Maxfield
no flags
Patch (13.85 KB, patch)
2016-03-04 12:12 PST, Myles C. Maxfield
simon.fraser: review+
Patch for committing (15.72 KB, patch)
2016-03-04 14:10 PST, Myles C. Maxfield
no flags
Myles C. Maxfield
Comment 1 2016-03-03 20:59:42 PST
Myles C. Maxfield
Comment 2 2016-03-03 21:01:48 PST
Darin Adler
Comment 3 2016-03-03 21:16:25 PST
Comment on attachment 272826 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=272826&action=review > Source/WebCore/css/CSSFontFace.cpp:385 > + if (m_clients.contains(client)) What is this m_clients.contains check supposed to do? It can’t correctly handle the case where a client is deleted and removed from the set of clients, because it’s possible that the client was removed, deleted, a new object allocated at the same address, and the new object added as a client, all before the call to contains happens, falsely returning true even though it’s a different object. Making a copy and doing this contains check is a common pattern people try to use to fix this category of problem, but it’s an incorrect one. There are correct solutions to this kind of iteration, but they typically involve storing a pointer to the local temporary set being iterated in the object and having remove do removal from both sets, and other techniques like that.
Build Bot
Comment 4 2016-03-03 21:58:15 PST
Comment on attachment 272826 [details] Patch Attachment 272826 [details] did not pass mac-debug-ews (mac): Output: http://webkit-queues.webkit.org/results/920410 New failing tests: fast/text/font-face-set-document-multiple-failure.html
Build Bot
Comment 5 2016-03-03 21:58:17 PST
Created attachment 272832 [details] Archive of layout-test-results from ews116 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-debug-ews. Bot: ews116 Port: mac-yosemite Platform: Mac OS X 10.10.5
Myles C. Maxfield
Comment 6 2016-03-04 00:18:06 PST
The failure is WK1-specific.
Myles C. Maxfield
Comment 7 2016-03-04 00:33:56 PST
Myles C. Maxfield
Comment 8 2016-03-04 10:12:19 PST
Myles C. Maxfield
Comment 9 2016-03-04 10:27:32 PST
Simon Fraser (smfr)
Comment 10 2016-03-04 12:06:40 PST
fail to what?
Myles C. Maxfield
Comment 11 2016-03-04 12:12:12 PST
Simon Fraser (smfr)
Comment 12 2016-03-04 13:06:36 PST
Comment on attachment 273022 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=273022&action=review > Source/WebCore/ChangeLog:18 > + * css/CSSFontFace.cpp: > + (WebCore::CSSFontFace::setStatus): > + * css/FontFaceSet.cpp: > + (WebCore::FontFaceSet::faceFinished): > + * css/FontFaceSet.h: This doesn't mention the Document::fonts() change. > Source/WebCore/css/CSSFontFace.cpp:57 > + clientsCopy.append(client); I think this can be an uncheckedAppend() > Source/WebCore/dom/Document.cpp:6686 > + updateStyleIfNeeded(); This should be explained in the changelog.
Myles C. Maxfield
Comment 13 2016-03-04 14:10:16 PST
Created attachment 273038 [details] Patch for committing
Darin Adler
Comment 14 2016-03-05 18:28:44 PST
Comment on attachment 273038 [details] Patch for committing View in context: https://bugs.webkit.org/attachment.cgi?id=273038&action=review > Source/WebCore/ChangeLog:9 > + In Javascript, the first promise fulfilment/failure wins. However, in C++, any > + subsequent fulfulments/failures cause a crash. JavaScript has a capital S in it. Typo: it should be "fulfillment", not "fulfilment" or "fulfulment". > Source/WebCore/css/CSSFontFace.cpp:51 > +template <typename T> No space after the word template before the "<" in our coding style. I also like putting this all one one line rather than one template line and a separate function signature line. > Source/WebCore/css/CSSFontFace.cpp:58 > + client->guardAgainstClientRegistrationChanges(); If we arranged things so that the client class had functions named ref/deref that call through to the virtual functions, then we could use a Vector<Ref<CSSFontFace::Client>> (or maybe RefPtr instead of Ref) and not have to write as much code. This is the pattern we use in EventTarget, for example. This template could be even more generic then. > Source/WebCore/css/CSSFontFace.h:115 > + virtual void guardAgainstClientRegistrationChanges() { }; > + virtual void stopGuardingAgainstClientRegistrationChanges() { }; The semicolons are unneeded/incorrect. I see the same problem on previous lines of code. > Source/WebCore/css/FontFaceSet.h:104 > + bool terminalState { false }; Not too fond of this name. It’s called terminal state, but the variable doesn’t contain a terminal state or contain a state at all. Our normal style is to name booleans with clauses that fit the form "promise <xxx>", so it could be a name like hasReachedTerminalState.
Darin Adler
Comment 15 2016-03-05 18:30:30 PST
Comment on attachment 273038 [details] Patch for committing View in context: https://bugs.webkit.org/attachment.cgi?id=273038&action=review > Source/WebCore/css/FontFace.cpp:393 > + ref(); A good comment here would be something like: // This class's destructor is what removes it as a client; a ref is what it takes to prevent that from happening.
Myles C. Maxfield
Comment 16 2016-03-08 14:22:30 PST
Note You need to log in before you can comment on or make changes to this bug.