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:
Cameron McCormack
2019-06-06 18:23:31 +00:00
parent 493aa8f10d
commit 24fb837902
2 changed files with 50 additions and 29 deletions

View File

@@ -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) {

View File

@@ -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,