bug 494130 - log downloadable font errors to console. r=jdaggett

This commit is contained in:
Jonathan Kew 2011-07-12 12:24:36 +01:00
parent fbfb5d07d2
commit 8d6d499d91
4 changed files with 155 additions and 70 deletions

View File

@ -55,11 +55,11 @@
using namespace mozilla;
#ifdef PR_LOGGING
static PRLogModuleInfo *gUserFontsLog = PR_NewLogModule("userfonts");
PRLogModuleInfo *gfxUserFontSet::sUserFontsLog = PR_NewLogModule("userfonts");
#endif /* PR_LOGGING */
#define LOG(args) PR_LOG(gUserFontsLog, PR_LOG_DEBUG, args)
#define LOG_ENABLED() PR_LOG_TEST(gUserFontsLog, PR_LOG_DEBUG)
#define LOG(args) PR_LOG(sUserFontsLog, PR_LOG_DEBUG, args)
#define LOG_ENABLED() PR_LOG_TEST(sUserFontsLog, PR_LOG_DEBUG)
static PRUint64 sFontSetGeneration = LL_INIT(0, 0);
@ -445,7 +445,7 @@ CopyWOFFMetadata(const PRUint8* aFontData, PRUint32 aLength,
// ensure that it is eventually deleted via NS_Free().
PRBool
gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy,
const PRUint8 *aFontData, PRUint32 aLength,
const PRUint8 *aFontData, PRUint32 aLength,
nsresult aDownloadStatus)
{
// download successful, make platform font using font data
@ -482,14 +482,9 @@ gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy,
const PRUint8* saneData =
SanitizeOpenTypeData(aFontData, aLength, saneLen,
fontType == GFX_USERFONT_WOFF);
#ifdef DEBUG
if (!saneData) {
char buf[1000];
sprintf(buf, "downloaded font rejected for \"%s\"",
NS_ConvertUTF16toUTF8(aProxy->FamilyName()).get());
NS_WARNING(buf);
LogMessage(aProxy, "rejected by sanitizer");
}
#endif
if (saneData) {
// The sanitizer ensures that we have a valid sfnt and a usable
// name table, so this should never fail unless we're out of
@ -503,7 +498,7 @@ gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy,
saneData,
saneLen);
if (!fe) {
NS_WARNING("failed to make platform font from download");
LogMessage(aProxy, "not usable by platform");
}
}
} else {
@ -523,11 +518,14 @@ gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy,
fe = gfxPlatform::GetPlatform()->MakePlatformFont(aProxy,
aFontData,
aLength);
if (!fe) {
LogMessage(aProxy, "not usable by platform");
}
aFontData = nsnull; // we must NOT free this below!
} else {
// the data was unusable, so just discard it
// (error will be reported below, if logging is enabled)
NS_WARNING("failed to make platform font from download");
LogMessage(aProxy, "SFNT header or tables invalid");
}
}
}
@ -572,16 +570,8 @@ gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy,
}
} else {
// download failed
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCAutoString fontURI;
aProxy->mSrcList[aProxy->mSrcIndex].mURI->GetSpec(fontURI);
LOG(("userfonts (%p) [src %d] failed uri: (%s) for (%s) error %8.8x downloading font data\n",
this, aProxy->mSrcIndex, fontURI.get(),
NS_ConvertUTF16toUTF8(aProxy->mFamily->Name()).get(),
aDownloadStatus));
}
#endif
LogMessage(aProxy, "download failed", nsIScriptError::errorFlag,
aDownloadStatus);
}
if (aFontData) {
@ -606,7 +596,8 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
{
PRUint32 numSrc = aProxyEntry->mSrcList.Length();
NS_ASSERTION(aProxyEntry->mSrcIndex < numSrc, "already at the end of the src list for user font");
NS_ASSERTION(aProxyEntry->mSrcIndex < numSrc,
"already at the end of the src list for user font");
if (aProxyEntry->mLoadingState == gfxProxyFontEntry::NOT_LOADING) {
aProxyEntry->mLoadingState = gfxProxyFontEntry::LOADING_STARTED;
@ -617,21 +608,22 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
aProxyEntry->mSrcIndex++;
}
// load each src entry in turn, until a local face is found or a download begins successfully
// load each src entry in turn, until a local face is found
// or a download begins successfully
while (aProxyEntry->mSrcIndex < numSrc) {
const gfxFontFaceSrc& currSrc = aProxyEntry->mSrcList[aProxyEntry->mSrcIndex];
// src local ==> lookup and load
// src local ==> lookup and load
if (currSrc.mIsLocal) {
gfxFontEntry *fe =
gfxPlatform::GetPlatform()->LookupLocalFont(aProxyEntry,
currSrc.mLocalName);
if (fe) {
LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
this, aProxyEntry->mSrcIndex,
NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(),
NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get(),
LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
this, aProxyEntry->mSrcIndex,
NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(),
NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get(),
PRUint32(mGeneration)));
fe->mFeatureSettings.AppendElements(aProxyEntry->mFeatureSettings);
fe->mLanguageOverride = aProxyEntry->mLanguageOverride;
@ -639,52 +631,37 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
ReplaceFontEntry(aProxyEntry, fe);
return STATUS_LOADED;
} else {
LOG(("userfonts (%p) [src %d] failed local: (%s) for (%s)\n",
this, aProxyEntry->mSrcIndex,
NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(),
NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get()));
LOG(("userfonts (%p) [src %d] failed local: (%s) for (%s)\n",
this, aProxyEntry->mSrcIndex,
NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(),
NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get()));
}
}
}
// src url ==> start the load process
else {
if (gfxPlatform::GetPlatform()->IsFontFormatSupported(currSrc.mURI,
if (gfxPlatform::GetPlatform()->IsFontFormatSupported(currSrc.mURI,
currSrc.mFormatFlags)) {
nsresult rv = StartLoad(aProxyEntry, &currSrc);
PRBool loadOK = NS_SUCCEEDED(rv);
if (loadOK) {
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCAutoString fontURI;
currSrc.mURI->GetSpec(fontURI);
LOG(("userfonts (%p) [src %d] loading uri: (%s) for (%s)\n",
this, aProxyEntry->mSrcIndex, fontURI.get(),
LOG(("userfonts (%p) [src %d] loading uri: (%s) for (%s)\n",
this, aProxyEntry->mSrcIndex, fontURI.get(),
NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get()));
}
#endif
return STATUS_LOADING;
return STATUS_LOADING;
} else {
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCAutoString fontURI;
currSrc.mURI->GetSpec(fontURI);
LOG(("userfonts (%p) [src %d] failed uri: (%s) for (%s) download failed\n",
this, aProxyEntry->mSrcIndex, fontURI.get(),
NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get()));
}
#endif
LogMessage(aProxyEntry, "download failed",
nsIScriptError::errorFlag, rv);
}
} else {
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCAutoString fontURI;
currSrc.mURI->GetSpec(fontURI);
LOG(("userfonts (%p) [src %d] failed uri: (%s) for (%s) format not supported\n",
this, aProxyEntry->mSrcIndex, fontURI.get(),
NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get()));
}
#endif
LogMessage(aProxyEntry, "format not supported",
nsIScriptError::warningFlag);
}
}
@ -692,8 +669,8 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
}
// all src's failed; mark this entry as unusable (so fallback will occur)
LOG(("userfonts (%p) failed all src for (%s)\n",
this, NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get()));
LOG(("userfonts (%p) failed all src for (%s)\n",
this, NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get()));
aProxyEntry->mLoadingState = gfxProxyFontEntry::LOADING_FAILED;
return STATUS_END_OF_LIST;

View File

@ -47,6 +47,7 @@
#include "nsIURI.h"
#include "nsIFile.h"
#include "nsISupportsImpl.h"
#include "nsIScriptError.h"
class nsIURI;
class gfxMixedFontFamily;
@ -252,10 +253,18 @@ protected:
gfxMixedFontFamily *GetFamily(const nsAString& aName) const;
// report a problem of some kind (implemented in nsUserFontSet)
virtual nsresult LogMessage(gfxProxyFontEntry *aProxy,
const char *aMessage,
PRUint32 aFlags = nsIScriptError::errorFlag,
nsresult aStatus = 0) = 0;
// font families defined by @font-face rules
nsRefPtrHashtable<nsStringHashKey, gfxMixedFontFamily> mFontFamilies;
PRUint64 mGeneration;
static PRLogModuleInfo *sUserFontsLog;
};
// acts a placeholder until the real font is downloaded

View File

@ -73,6 +73,8 @@
#include "nsIChannelPolicy.h"
#include "nsChannelPolicy.h"
#include "nsIConsoleService.h"
#include "nsStyleSet.h"
using namespace mozilla;
@ -342,17 +344,7 @@ nsUserFontSet::StartLoad(gfxProxyFontEntry *aProxy,
rv = nsFontFaceLoader::CheckLoadAllowed(principal, aFontFaceSrc->mURI,
ps->GetDocument());
if (NS_FAILED(rv)) {
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCAutoString fontURI, referrerURI;
aFontFaceSrc->mURI->GetSpec(fontURI);
if (aFontFaceSrc->mReferrer)
aFontFaceSrc->mReferrer->GetSpec(referrerURI);
LOG(("fontdownloader download blocked - font uri: (%s) "
"referrer uri: (%s) err: %8.8x\n",
fontURI.get(), referrerURI.get(), rv));
}
#endif
LogMessage(aProxy, "download not allowed", nsIScriptError::errorFlag, rv);
return rv;
}
@ -697,3 +689,105 @@ nsUserFontSet::FindRuleForEntry(gfxFontEntry *aFontEntry)
}
return nsnull;
}
nsresult
nsUserFontSet::LogMessage(gfxProxyFontEntry *aProxy,
const char *aMessage,
PRUint32 aFlags,
nsresult aStatus)
{
nsCOMPtr<nsIConsoleService>
console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
if (!console) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_ConvertUTF16toUTF8 familyName(aProxy->FamilyName());
nsCAutoString fontURI;
aProxy->mSrcList[aProxy->mSrcIndex].mURI->GetSpec(fontURI);
char weightKeywordBuf[8]; // plenty to sprintf() a PRUint16
const char *weightKeyword;
const nsAFlatCString& weightKeywordString =
nsCSSProps::ValueToKeyword(aProxy->Weight(),
nsCSSProps::kFontWeightKTable);
if (weightKeywordString.Length() > 0) {
weightKeyword = weightKeywordString.get();
} else {
sprintf(weightKeywordBuf, "%u", aProxy->Weight());
weightKeyword = weightKeywordBuf;
}
nsPrintfCString
msg(1024,
"downloadable font: %s "
"(font-family: \"%s\" style:%s weight:%s stretch:%s src index:%d)",
aMessage,
familyName.get(),
aProxy->IsItalic() ? "italic" : "normal",
weightKeyword,
nsCSSProps::ValueToKeyword(aProxy->Stretch(),
nsCSSProps::kFontStretchKTable).get(),
aProxy->mSrcIndex);
if (aStatus != 0) {
msg.Append(": ");
switch (aStatus) {
case NS_ERROR_DOM_BAD_URI:
msg.Append("bad URI or cross-site access not allowed");
break;
case NS_ERROR_CONTENT_BLOCKED:
msg.Append("content blocked");
break;
default:
msg.Append("status=");
msg.AppendInt(aStatus);
break;
}
}
msg.Append("\nsource: ");
msg.Append(fontURI);
#ifdef PR_LOGGING
if (PR_LOG_TEST(sUserFontsLog, PR_LOG_DEBUG)) {
PR_LOG(sUserFontsLog, PR_LOG_DEBUG,
("userfonts (%p) %s", this, msg.get()));
}
#endif
// try to give the user an indication of where the rule came from
nsCSSFontFaceRule* rule = FindRuleForEntry(aProxy);
nsString href;
nsString text;
nsresult rv;
if (rule) {
rv = rule->GetCssText(text);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMCSSStyleSheet> sheet;
rv = rule->GetParentStyleSheet(getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
rv = sheet->GetHref(href);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIScriptError2> scriptError =
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUint64 windowID = GetPresContext()->Document()->OuterWindowID();
rv = scriptError->InitWithWindowID(NS_ConvertUTF8toUTF16(msg).get(),
href.get(), // file
text.get(), // src line
0, 0, // line & column number
aFlags, // flags
"CSS Loader", // category (make separate?)
windowID);
if (NS_SUCCEEDED(rv)){
nsCOMPtr<nsIScriptError> logError = do_QueryInterface(scriptError);
if (logError) {
console->LogMessage(logError);
}
}
return NS_OK;
}

View File

@ -102,6 +102,11 @@ protected:
nsTArray<FontFaceRuleRecord>& oldRules,
PRBool& aFontSetModified);
virtual nsresult LogMessage(gfxProxyFontEntry *aProxy,
const char *aMessage,
PRUint32 aFlags = nsIScriptError::errorFlag,
nsresult aStatus = 0);
nsPresContext *mPresContext; // weak reference
// Set of all loaders pointing to us. These are not strong pointers,