2017-10-27 20:33:53 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2008-10-01 07:04:10 +04:00
|
|
|
|
|
|
|
/* code for loading in @font-face defined font data */
|
|
|
|
|
|
|
|
#ifndef nsFontFaceLoader_h_
|
|
|
|
#define nsFontFaceLoader_h_
|
|
|
|
|
2014-02-24 18:41:56 +04:00
|
|
|
#include "mozilla/Attributes.h"
|
2015-11-25 08:48:16 +03:00
|
|
|
#include "mozilla/TimeStamp.h"
|
2018-02-01 07:04:04 +03:00
|
|
|
#include "mozilla/dom/FontFaceSet.h"
|
2008-12-12 10:31:51 +03:00
|
|
|
#include "nsCOMPtr.h"
|
2019-06-06 22:08:52 +03:00
|
|
|
#include "nsIFontLoadCompleteCallback.h"
|
2008-10-29 21:09:50 +03:00
|
|
|
#include "nsIStreamLoader.h"
|
2009-01-19 12:21:29 +03:00
|
|
|
#include "nsIChannel.h"
|
2017-09-29 05:10:13 +03:00
|
|
|
#include "nsIRequestObserver.h"
|
2008-10-01 07:04:10 +04:00
|
|
|
#include "gfxUserFontSet.h"
|
2009-01-19 12:21:29 +03:00
|
|
|
#include "nsHashKeys.h"
|
|
|
|
#include "nsTHashtable.h"
|
2008-10-01 07:04:10 +04:00
|
|
|
|
2008-11-06 03:32:12 +03:00
|
|
|
class nsIPrincipal;
|
2008-10-01 07:04:10 +04:00
|
|
|
|
2018-09-06 04:23:14 +03:00
|
|
|
class nsFontFaceLoader final : public nsIStreamLoaderObserver,
|
2019-06-06 22:08:52 +03:00
|
|
|
public nsIRequestObserver,
|
|
|
|
public nsIFontLoadCompleteCallback {
|
2008-10-01 07:04:10 +04:00
|
|
|
public:
|
Bug 1694123 - Pass userfont source index to font loader and decoder tasks, to avoid potential race with the field in the gfxUserFontEntry being reset on the main thread. r=layout-reviewers,emilio
This is a preliminary step that is needed in order for the following patch to be safe. (It's
mostly just plumbing, although the patch looks big because we need to pass the index through
so many functions.)
The issue is that loading a font resource involves a couple of tasks that happen asynchronously -
fetching the data from the network, and decoding/sanitizing the font data. We have an implicit
assumption that once a font load has been initiated, the state of the associated gfxUserFontEntry
will not change; in particular, we depend on mSrcIndex remaining constant, because we may use it
to index into the mSrcList array and access the gfxFontFaceSrc record again in the various
completion tasks that are executed after the async steps finish.
But the following patch breaks this assumption, because it may reset mSrcIndex at arbitrary times
when we discover that we need to re-resolve the @font-face to potentially recognize a src:local()
resource that was earlier in the list, but was previously unavailable. If this happens while
a font-load is doing its off-main-thread work, then when it completes, it will end up accessing
the wrong gfxFontFaceSrc record, which would result at least in incorrect behavior, but can also
result in a crash (e.g. if the record is of the wrong type altogether, such as trying to use the
principal or URI fields from a record of type src:local).
To avoid this problem, we should pass the source index at the time the font load is initiated
through to the OMT tasks and back to their main-thread completion routines, so that we do not
depend on the field in the gfxUserFontEntry remaining frozen. This makes the loading process
safe even if the source index in the entry gets reset while loading tasks are in progress.
Differential Revision: https://phabricator.services.mozilla.com/D110911
2021-04-06 19:23:17 +03:00
|
|
|
nsFontFaceLoader(gfxUserFontEntry* aUserFontEntry, uint32_t aSrcIndex,
|
2014-10-02 06:32:05 +04:00
|
|
|
mozilla::dom::FontFaceSet* aFontFaceSet,
|
|
|
|
nsIChannel* aChannel);
|
2012-12-19 13:42:25 +04:00
|
|
|
|
2008-10-01 07:04:10 +04:00
|
|
|
NS_DECL_ISUPPORTS
|
2008-10-29 21:09:50 +03:00
|
|
|
NS_DECL_NSISTREAMLOADEROBSERVER
|
2017-09-29 05:10:13 +03:00
|
|
|
NS_DECL_NSIREQUESTOBSERVER
|
2008-10-01 07:04:10 +04:00
|
|
|
|
2014-10-02 06:32:05 +04:00
|
|
|
// cancel the load and remove its reference to mFontFaceSet
|
2009-01-19 12:21:29 +03:00
|
|
|
void Cancel();
|
2008-10-01 07:04:10 +04:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
void DropChannel() { mChannel = nullptr; }
|
2009-01-31 11:58:42 +03:00
|
|
|
|
2013-09-25 17:48:20 +04:00
|
|
|
void StartedLoading(nsIStreamLoader* aStreamLoader);
|
2011-01-06 00:48:48 +03:00
|
|
|
|
2013-09-25 17:48:20 +04:00
|
|
|
static void LoadTimerCallback(nsITimer* aTimer, void* aClosure);
|
2011-01-06 00:48:48 +03:00
|
|
|
|
2015-03-06 11:44:23 +03:00
|
|
|
gfxUserFontEntry* GetUserFontEntry() const { return mUserFontEntry; }
|
2009-01-31 11:58:42 +03:00
|
|
|
|
2019-06-06 22:08:52 +03:00
|
|
|
// Called by the gfxUserFontEntry once it has finished the platform font
|
|
|
|
// loading.
|
|
|
|
NS_IMETHODIMP FontLoadComplete() final;
|
|
|
|
|
2014-06-24 02:40:01 +04:00
|
|
|
protected:
|
|
|
|
virtual ~nsFontFaceLoader();
|
|
|
|
|
2016-01-07 08:03:05 +03:00
|
|
|
// helper method for determining the font-display value
|
2018-10-04 00:50:21 +03:00
|
|
|
mozilla::StyleFontDisplay GetFontDisplay();
|
2016-01-07 08:03:05 +03:00
|
|
|
|
2008-12-12 10:31:51 +03:00
|
|
|
private:
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<gfxUserFontEntry> mUserFontEntry;
|
2008-12-12 10:31:51 +03:00
|
|
|
nsCOMPtr<nsIURI> mFontURI;
|
2019-01-21 14:10:26 +03:00
|
|
|
// Cleared in FontFaceSet::~FontFaceSet, and on cancelation and such too.
|
|
|
|
mozilla::dom::FontFaceSet* MOZ_NON_OWNING_REF mFontFaceSet;
|
2009-01-19 12:21:29 +03:00
|
|
|
nsCOMPtr<nsIChannel> mChannel;
|
2011-01-06 00:48:48 +03:00
|
|
|
nsCOMPtr<nsITimer> mLoadTimer;
|
2015-09-10 13:24:34 +03:00
|
|
|
mozilla::TimeStamp mStartTime;
|
2013-09-25 17:48:20 +04:00
|
|
|
nsIStreamLoader* mStreamLoader;
|
Bug 1694123 - Pass userfont source index to font loader and decoder tasks, to avoid potential race with the field in the gfxUserFontEntry being reset on the main thread. r=layout-reviewers,emilio
This is a preliminary step that is needed in order for the following patch to be safe. (It's
mostly just plumbing, although the patch looks big because we need to pass the index through
so many functions.)
The issue is that loading a font resource involves a couple of tasks that happen asynchronously -
fetching the data from the network, and decoding/sanitizing the font data. We have an implicit
assumption that once a font load has been initiated, the state of the associated gfxUserFontEntry
will not change; in particular, we depend on mSrcIndex remaining constant, because we may use it
to index into the mSrcList array and access the gfxFontFaceSrc record again in the various
completion tasks that are executed after the async steps finish.
But the following patch breaks this assumption, because it may reset mSrcIndex at arbitrary times
when we discover that we need to re-resolve the @font-face to potentially recognize a src:local()
resource that was earlier in the list, but was previously unavailable. If this happens while
a font-load is doing its off-main-thread work, then when it completes, it will end up accessing
the wrong gfxFontFaceSrc record, which would result at least in incorrect behavior, but can also
result in a crash (e.g. if the record is of the wrong type altogether, such as trying to use the
principal or URI fields from a record of type src:local).
To avoid this problem, we should pass the source index at the time the font load is initiated
through to the OMT tasks and back to their main-thread completion routines, so that we do not
depend on the field in the gfxUserFontEntry remaining frozen. This makes the loading process
safe even if the source index in the entry gets reset while loading tasks are in progress.
Differential Revision: https://phabricator.services.mozilla.com/D110911
2021-04-06 19:23:17 +03:00
|
|
|
uint32_t mSrcIndex;
|
2019-01-25 23:52:00 +03:00
|
|
|
bool mInStreamComplete = false;
|
|
|
|
bool mInLoadTimerCallback = false;
|
2008-10-01 07:04:10 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* !defined(nsFontFaceLoader_h_) */
|