Bug 1490792 - Part 3: Split some work out of LoadPlatformFont. r=jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D33896
This commit is contained in:
@@ -588,7 +588,7 @@ void gfxUserFontEntry::DoLoadNextSrc(bool aForceAsync) {
|
|||||||
nsresult rv =
|
nsresult rv =
|
||||||
mFontSet->SyncLoadFontData(this, &currSrc, buffer, bufferLength);
|
mFontSet->SyncLoadFontData(this, &currSrc, buffer, bufferLength);
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && LoadPlatformFont(buffer, bufferLength)) {
|
if (NS_SUCCEEDED(rv) && LoadPlatformFontSync(buffer, bufferLength)) {
|
||||||
SetLoadState(STATUS_LOADED);
|
SetLoadState(STATUS_LOADED);
|
||||||
Telemetry::Accumulate(Telemetry::WEBFONT_SRCTYPE,
|
Telemetry::Accumulate(Telemetry::WEBFONT_SRCTYPE,
|
||||||
currSrc.mSourceType + 1);
|
currSrc.mSourceType + 1);
|
||||||
@@ -632,8 +632,8 @@ void gfxUserFontEntry::DoLoadNextSrc(bool aForceAsync) {
|
|||||||
|
|
||||||
// sync load font immediately
|
// sync load font immediately
|
||||||
currSrc.mBuffer->TakeBuffer(buffer, bufferLength);
|
currSrc.mBuffer->TakeBuffer(buffer, bufferLength);
|
||||||
if (buffer && LoadPlatformFont(buffer, bufferLength)) {
|
if (buffer && LoadPlatformFontSync(buffer, bufferLength)) {
|
||||||
// LoadPlatformFont takes ownership of the buffer, so no need
|
// LoadPlatformFontSync takes ownership of the buffer, so no need
|
||||||
// to free it here.
|
// to free it here.
|
||||||
SetLoadState(STATUS_LOADED);
|
SetLoadState(STATUS_LOADED);
|
||||||
Telemetry::Accumulate(Telemetry::WEBFONT_SRCTYPE,
|
Telemetry::Accumulate(Telemetry::WEBFONT_SRCTYPE,
|
||||||
@@ -666,9 +666,9 @@ void gfxUserFontEntry::SetLoadState(UserFontLoadState aLoadState) {
|
|||||||
|
|
||||||
MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(UserFontMallocSizeOfOnAlloc)
|
MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(UserFontMallocSizeOfOnAlloc)
|
||||||
|
|
||||||
bool gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData,
|
bool gfxUserFontEntry::LoadPlatformFontSync(const uint8_t* aFontData,
|
||||||
uint32_t aLength) {
|
uint32_t aLength) {
|
||||||
AUTO_PROFILER_LABEL("gfxUserFontEntry::LoadPlatformFont", OTHER);
|
AUTO_PROFILER_LABEL("gfxUserFontEntry::LoadPlatformFontSync", OTHER);
|
||||||
NS_ASSERTION((mUserFontLoadState == STATUS_NOT_LOADED ||
|
NS_ASSERTION((mUserFontLoadState == STATUS_NOT_LOADED ||
|
||||||
mUserFontLoadState == STATUS_LOAD_PENDING ||
|
mUserFontLoadState == STATUS_LOAD_PENDING ||
|
||||||
mUserFontLoadState == STATUS_LOADING) &&
|
mUserFontLoadState == STATUS_LOADING) &&
|
||||||
@@ -684,17 +684,28 @@ bool gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData,
|
|||||||
gfxUserFontType fontType;
|
gfxUserFontType fontType;
|
||||||
const uint8_t* saneData =
|
const uint8_t* saneData =
|
||||||
SanitizeOpenTypeData(aFontData, aLength, saneLen, fontType);
|
SanitizeOpenTypeData(aFontData, aLength, saneLen, fontType);
|
||||||
if (!saneData) {
|
|
||||||
|
return LoadPlatformFont(aFontData, aLength, fontType, saneData, saneLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gfxUserFontEntry::LoadPlatformFont(const uint8_t* aOriginalFontData,
|
||||||
|
uint32_t aOriginalLength,
|
||||||
|
gfxUserFontType aFontType,
|
||||||
|
const uint8_t* aSanitizedFontData,
|
||||||
|
uint32_t aSanitizedLength) {
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (!aSanitizedFontData) {
|
||||||
mFontSet->LogMessage(this, "rejected by sanitizer");
|
mFontSet->LogMessage(this, "rejected by sanitizer");
|
||||||
} else {
|
} else {
|
||||||
// Check whether saneData is a known OpenType format; it might be
|
// Check whether aSanitizedFontData is a known OpenType format; it might be
|
||||||
// a TrueType Collection, which OTS would accept but we don't yet
|
// a TrueType Collection, which OTS would accept but we don't yet
|
||||||
// know how to handle. If so, discard.
|
// know how to handle. If so, discard.
|
||||||
if (gfxFontUtils::DetermineFontDataType(saneData, saneLen) !=
|
if (gfxFontUtils::DetermineFontDataType(
|
||||||
GFX_USERFONT_OPENTYPE) {
|
aSanitizedFontData, aSanitizedLength) != GFX_USERFONT_OPENTYPE) {
|
||||||
mFontSet->LogMessage(this, "not a supported OpenType format");
|
mFontSet->LogMessage(this, "not a supported OpenType format");
|
||||||
free((void*)saneData);
|
free((void*)aSanitizedFontData);
|
||||||
saneData = nullptr;
|
aSanitizedFontData = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -707,11 +718,12 @@ bool gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData,
|
|||||||
uint32_t fontCompressionRatio = 0;
|
uint32_t fontCompressionRatio = 0;
|
||||||
size_t computedSize = 0;
|
size_t computedSize = 0;
|
||||||
|
|
||||||
if (saneData) {
|
if (aSanitizedFontData) {
|
||||||
if (saneLen) {
|
if (aSanitizedLength) {
|
||||||
fontCompressionRatio = uint32_t(100.0 * aLength / saneLen + 0.5);
|
fontCompressionRatio =
|
||||||
if (fontType == GFX_USERFONT_WOFF || fontType == GFX_USERFONT_WOFF2) {
|
uint32_t(100.0 * aOriginalLength / aSanitizedLength + 0.5);
|
||||||
Telemetry::Accumulate(fontType == GFX_USERFONT_WOFF
|
if (aFontType == GFX_USERFONT_WOFF || aFontType == GFX_USERFONT_WOFF2) {
|
||||||
|
Telemetry::Accumulate(aFontType == GFX_USERFONT_WOFF
|
||||||
? Telemetry::WEBFONT_COMPRESSION_WOFF
|
? Telemetry::WEBFONT_COMPRESSION_WOFF
|
||||||
: Telemetry::WEBFONT_COMPRESSION_WOFF2,
|
: Telemetry::WEBFONT_COMPRESSION_WOFF2,
|
||||||
fontCompressionRatio);
|
fontCompressionRatio);
|
||||||
@@ -722,7 +734,8 @@ bool gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData,
|
|||||||
// name table, so this should never fail unless we're out of
|
// name table, so this should never fail unless we're out of
|
||||||
// memory, and GetFullNameFromSFNT is not directly exposed to
|
// memory, and GetFullNameFromSFNT is not directly exposed to
|
||||||
// arbitrary/malicious data from the web.
|
// arbitrary/malicious data from the web.
|
||||||
gfxFontUtils::GetFullNameFromSFNT(saneData, saneLen, originalFullName);
|
gfxFontUtils::GetFullNameFromSFNT(aSanitizedFontData, aSanitizedLength,
|
||||||
|
originalFullName);
|
||||||
|
|
||||||
// Record size for memory reporting purposes. We measure this now
|
// Record size for memory reporting purposes. We measure this now
|
||||||
// because by the time we potentially want to collect reports, this
|
// because by the time we potentially want to collect reports, this
|
||||||
@@ -730,12 +743,13 @@ bool gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData,
|
|||||||
// don't allow us to retrieve or measure it directly.
|
// don't allow us to retrieve or measure it directly.
|
||||||
// The *OnAlloc function will also tell DMD about this block, as the
|
// The *OnAlloc function will also tell DMD about this block, as the
|
||||||
// OS font code may hold on to it for an extended period.
|
// OS font code may hold on to it for an extended period.
|
||||||
computedSize = UserFontMallocSizeOfOnAlloc(saneData);
|
computedSize = UserFontMallocSizeOfOnAlloc(aSanitizedFontData);
|
||||||
|
|
||||||
// Here ownership of saneData is passed to the platform,
|
// Here ownership of aSanitizedFontData is passed to the platform,
|
||||||
// which will delete it when no longer required
|
// which will delete it when no longer required
|
||||||
fe = gfxPlatform::GetPlatform()->MakePlatformFont(
|
fe = gfxPlatform::GetPlatform()->MakePlatformFont(
|
||||||
mName, Weight(), Stretch(), SlantStyle(), saneData, saneLen);
|
mName, Weight(), Stretch(), SlantStyle(), aSanitizedFontData,
|
||||||
|
aSanitizedLength);
|
||||||
if (!fe) {
|
if (!fe) {
|
||||||
mFontSet->LogMessage(this, "not usable by platform");
|
mFontSet->LogMessage(this, "not usable by platform");
|
||||||
}
|
}
|
||||||
@@ -750,12 +764,13 @@ bool gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData,
|
|||||||
FallibleTArray<uint8_t> metadata;
|
FallibleTArray<uint8_t> metadata;
|
||||||
uint32_t metaOrigLen = 0;
|
uint32_t metaOrigLen = 0;
|
||||||
uint8_t compression = gfxUserFontData::kUnknownCompression;
|
uint8_t compression = gfxUserFontData::kUnknownCompression;
|
||||||
if (fontType == GFX_USERFONT_WOFF) {
|
if (aFontType == GFX_USERFONT_WOFF) {
|
||||||
CopyWOFFMetadata<WOFFHeader>(aFontData, aLength, &metadata, &metaOrigLen);
|
CopyWOFFMetadata<WOFFHeader>(aOriginalFontData, aOriginalLength,
|
||||||
|
&metadata, &metaOrigLen);
|
||||||
compression = gfxUserFontData::kZlibCompression;
|
compression = gfxUserFontData::kZlibCompression;
|
||||||
} else if (fontType == GFX_USERFONT_WOFF2) {
|
} else if (aFontType == GFX_USERFONT_WOFF2) {
|
||||||
CopyWOFFMetadata<WOFF2Header>(aFontData, aLength, &metadata,
|
CopyWOFFMetadata<WOFF2Header>(aOriginalFontData, aOriginalLength,
|
||||||
&metaOrigLen);
|
&metadata, &metaOrigLen);
|
||||||
compression = gfxUserFontData::kBrotliCompression;
|
compression = gfxUserFontData::kBrotliCompression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,7 +807,7 @@ bool gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData,
|
|||||||
|
|
||||||
// The downloaded data can now be discarded; the font entry is using the
|
// The downloaded data can now be discarded; the font entry is using the
|
||||||
// sanitized copy
|
// sanitized copy
|
||||||
free((void*)aFontData);
|
free((void*)aOriginalFontData);
|
||||||
|
|
||||||
return fe != nullptr;
|
return fe != nullptr;
|
||||||
}
|
}
|
||||||
@@ -824,7 +839,7 @@ bool gfxUserFontEntry::FontDataDownloadComplete(const uint8_t* aFontData,
|
|||||||
// download successful, make platform font using font data
|
// download successful, make platform font using font data
|
||||||
if (NS_SUCCEEDED(aDownloadStatus) &&
|
if (NS_SUCCEEDED(aDownloadStatus) &&
|
||||||
mFontDataLoadingState != LOADING_TIMED_OUT) {
|
mFontDataLoadingState != LOADING_TIMED_OUT) {
|
||||||
bool loaded = LoadPlatformFont(aFontData, aLength);
|
bool loaded = LoadPlatformFontSync(aFontData, aLength);
|
||||||
aFontData = nullptr;
|
aFontData = nullptr;
|
||||||
|
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
|
|||||||
@@ -661,7 +661,13 @@ class gfxUserFontEntry : public gfxFontEntry {
|
|||||||
// returns true if platform font creation successful
|
// returns true if platform font creation successful
|
||||||
// Ownership of aFontData is passed in here; the font must
|
// Ownership of aFontData is passed in here; the font must
|
||||||
// ensure that it is eventually deleted with free().
|
// ensure that it is eventually deleted with free().
|
||||||
bool LoadPlatformFont(const uint8_t* aFontData, uint32_t aLength);
|
bool LoadPlatformFontSync(const uint8_t* aFontData, uint32_t aLength);
|
||||||
|
|
||||||
|
// helper method for LoadPlatformFontSync
|
||||||
|
bool LoadPlatformFont(const uint8_t* aOriginalFontData,
|
||||||
|
uint32_t aOriginalLength, gfxUserFontType aFontType,
|
||||||
|
const uint8_t* aSanitizedFontData,
|
||||||
|
uint32_t aSanitizedLength);
|
||||||
|
|
||||||
// store metadata and src details for current src into aFontEntry
|
// store metadata and src details for current src into aFontEntry
|
||||||
void StoreUserFontData(gfxFontEntry* aFontEntry, bool aPrivate,
|
void StoreUserFontData(gfxFontEntry* aFontEntry, bool aPrivate,
|
||||||
|
|||||||
Reference in New Issue
Block a user