Bug 1256678 - Replace DrawTargetCairo::FillGlyphs crashes with other crashes - r=bobowen
authorEdwin Flores <eflores@mozilla.com>
Wed, 06 Apr 2016 11:07:27 +0100
changeset 291873 39c895b67af2e6fe91e70a1ea7bf8581401af274
parent 291872 49d808d13f4fab71b49019905cce3ba6eb6bb31f
child 291874 06d9d9cd6ab1187c284a46aa6830aa963d86456d
push id74701
push usereflores@mozilla.com
push dateWed, 06 Apr 2016 10:07:32 +0000
treeherdermozilla-inbound@39c895b67af2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbobowen
bugs1256678
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1256678 - Replace DrawTargetCairo::FillGlyphs crashes with other crashes - r=bobowen
gfx/2d/DrawTargetRecording.cpp
gfx/2d/Logging.h
gfx/2d/SFNTData.cpp
gfx/2d/ScaledFontWin.cpp
--- a/gfx/2d/DrawTargetRecording.cpp
+++ b/gfx/2d/DrawTargetRecording.cpp
@@ -384,16 +384,20 @@ void
 DrawTargetRecording::FillGlyphs(ScaledFont *aFont,
                                 const GlyphBuffer &aBuffer,
                                 const Pattern &aPattern,
                                 const DrawOptions &aOptions,
                                 const GlyphRenderingOptions *aRenderingOptions)
 {
   EnsurePatternDependenciesStored(aPattern);
 
+  if (aFont->GetType() != FontType::DWRITE && aFont->GetType() != FontType::GDI) {
+    gfxDevCrash(LogReason::GetFontFileDataFailed) << "Unexpected ScaledFont type " << (int)aFont->GetType();
+  }
+
   if (!aFont->GetUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()))) {
   // TODO support font in b2g recordings
 #ifndef MOZ_WIDGET_GONK
     RecordedFontData fontData(aFont);
     RecordedFontDetails fontDetails;
     if (fontData.GetFontDetails(fontDetails)) {
       if (!mRecorder->HasStoredFontData(fontDetails.fontDataKey)) {
         mRecorder->RecordEvent(fontData);
--- a/gfx/2d/Logging.h
+++ b/gfx/2d/Logging.h
@@ -128,16 +128,17 @@ enum class LogReason : int {
   SourceSurfaceIncompatible,
   GlyphAllocFailedCairo,
   GlyphAllocFailedCG,
   InvalidRect,
   CannotDraw3D, // 20
   IncompatibleBasicTexturedEffect,
   InvalidFont,
   PAllocTextureBackendMismatch,
+  GetFontFileDataFailed,
   // End
   MustBeLessThanThis = 101,
 };
 
 struct BasicLogger
 {
   // For efficiency, this method exists and copies the logic of the
   // OutputMessage below.  If making any changes here, also make it
--- a/gfx/2d/SFNTData.cpp
+++ b/gfx/2d/SFNTData.cpp
@@ -111,44 +111,46 @@ private:
 /* static */
 UniquePtr<SFNTData>
 SFNTData::Create(const uint8_t *aFontData, uint32_t aDataLength)
 {
   MOZ_ASSERT(aFontData);
 
   // Check to see if this is a font collection.
   if (aDataLength < sizeof(TTCHeader)) {
-    gfxWarning() << "Font data too short.";
+    gfxDevCrash(LogReason::GetFontFileDataFailed) << "Font data too short: length = " << aDataLength;
     return nullptr;
   }
 
   const TTCHeader *ttcHeader = reinterpret_cast<const TTCHeader*>(aFontData);
   if (ttcHeader->ttcTag == TRUETYPE_TAG('t', 't', 'c', 'f')) {
     uint32_t numFonts = ttcHeader->numFonts;
     if (aDataLength < sizeof(TTCHeader) + (numFonts * sizeof(BigEndianUint32))) {
-      gfxWarning() << "Font data too short to contain full TTC Header.";
+      gfxDevCrash(LogReason::GetFontFileDataFailed) << "Font data too short to contain full TTC Header: numFonts = " << numFonts << "; length = " << aDataLength;
       return nullptr;
     }
 
     UniquePtr<SFNTData> sfntData(new SFNTData);
     const BigEndianUint32* offset =
       reinterpret_cast<const BigEndianUint32*>(aFontData + sizeof(TTCHeader));
     const BigEndianUint32* endOfOffsets = offset + numFonts;
     while (offset != endOfOffsets) {
       if (!sfntData->AddFont(aFontData, aDataLength, *offset)) {
+        gfxDevCrash(LogReason::GetFontFileDataFailed) << "Failed to add font data from TTC";
         return nullptr;
       }
       ++offset;
     }
 
     return Move(sfntData);
   }
 
   UniquePtr<SFNTData> sfntData(new SFNTData);
   if (!sfntData->AddFont(aFontData, aDataLength, 0)) {
+    gfxDevCrash(LogReason::GetFontFileDataFailed) << "Failed to add single font data";
     return nullptr;
   }
 
   return Move(sfntData);
 }
 
 /* static */
 uint64_t
@@ -218,25 +220,25 @@ SFNTData::GetIndexForU16Name(const mozil
 }
 
 bool
 SFNTData::AddFont(const uint8_t *aFontData, uint32_t aDataLength,
                   uint32_t aOffset)
 {
   uint32_t remainingLength = aDataLength - aOffset;
   if (remainingLength < sizeof(OffsetTable)) {
-    gfxWarning() << "Font data too short to contain OffsetTable " << aOffset;
+    gfxCriticalError() << "Font data too short to contain OffsetTable: offset = " << aOffset << "; length = " << aDataLength;
     return false;
   }
 
   const OffsetTable *offsetTable =
     reinterpret_cast<const OffsetTable*>(aFontData + aOffset);
   if (remainingLength <
       sizeof(OffsetTable) + (offsetTable->numTables * sizeof(TableDirEntry))) {
-    gfxWarning() << "Font data too short to contain tables.";
+    gfxCriticalError() << "Font data too short to contain tables. numTables = " << offsetTable->numTables << "; offset = " << aOffset << "; length = " << aDataLength;
     return false;
   }
 
   return mFonts.append(new Font(offsetTable, aFontData, aDataLength));
 }
 
 } // gfx
 } // mozilla
--- a/gfx/2d/ScaledFontWin.cpp
+++ b/gfx/2d/ScaledFontWin.cpp
@@ -35,43 +35,45 @@ ScaledFontWin::GetFontFileData(FontFileD
   // Check for a font collection first.
   uint32_t table = 0x66637474; // 'ttcf'
   uint32_t tableSize = ::GetFontData(dc.GetDC(), table, 0, nullptr, 0);
   if (tableSize == GDI_ERROR) {
     // Try as if just a single font.
     table = 0;
     tableSize = ::GetFontData(dc.GetDC(), table, 0, nullptr, 0);
     if (tableSize == GDI_ERROR) {
+      gfxDevCrash(LogReason::GetFontFileDataFailed) << "Failed to get font data from GDI";
       return false;
     }
   }
 
   UniquePtr<uint8_t[]> fontData(new uint8_t[tableSize]);
 
   uint32_t sizeGot =
     ::GetFontData(dc.GetDC(), table, 0, fontData.get(), tableSize);
   if (sizeGot != tableSize) {
+    gfxDevCrash(LogReason::GetFontFileDataFailed) << "GDI did not return enough data for font: wanted " << tableSize << ", got " << sizeGot;
     return false;
   }
 
   // If it's a font collection then attempt to get the index.
   uint32_t index = 0;
   if (table != 0) {
     UniquePtr<SFNTData> sfntData = SFNTData::Create(fontData.get(),
                                                     tableSize);
     if (!sfntData) {
-      gfxWarning() << "Failed to create SFNTData for GetFontFileData.";
+      gfxDevCrash(LogReason::GetFontFileDataFailed) << "Failed to create SFNTData for GetFontFileData.";
       return false;
     }
 
     // We cast here because for VS2015 char16_t != wchar_t, even though they are
     // both 16 bit.
     if (!sfntData->GetIndexForU16Name(
           reinterpret_cast<char16_t*>(mLogFont.lfFaceName), &index)) {
-      gfxWarning() << "Failed to get index for face name.";
+      gfxDevCrash(LogReason::GetFontFileDataFailed) << "Failed to get index for face name.";
       return false;
     }
   }
 
   aDataCallback(fontData.get(), tableSize, index, mSize, aBaton);
   return true;
 }