Bug 1452467 - Make native font resource memory allocations fallible. r=lsalzman
☠☠ backed out by 19e60113f96d ☠ ☠
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 13 Apr 2018 09:41:29 -0400
changeset 413232 e5336e51b77f8d95a51eae13ff5f8676d3886083
parent 413231 dfb12ea49fd7d8883329ed4dbe2e0da6d1d81ac1
child 413233 e73f2e16ec4195375a293f7361a6ff972ff89f21
push id33840
push userapavel@mozilla.com
push dateFri, 13 Apr 2018 21:56:54 +0000
treeherdermozilla-central@6547c27303bc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1452467
milestone61.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 1452467 - Make native font resource memory allocations fallible. r=lsalzman
gfx/2d/NativeFontResourceDWrite.cpp
gfx/2d/NativeFontResourceFontconfig.cpp
--- a/gfx/2d/NativeFontResourceDWrite.cpp
+++ b/gfx/2d/NativeFontResourceDWrite.cpp
@@ -7,16 +7,17 @@
 #include "NativeFontResourceDWrite.h"
 #include "UnscaledFontDWrite.h"
 
 #include <unordered_map>
 
 #include "Logging.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/StaticMutex.h"
+#include "nsTArray.h"
 
 namespace mozilla {
 namespace gfx {
 
 static StaticMutex sFontFileStreamsMutex;
 static uint64_t sNextFontFileKey = 0;
 static std::unordered_map<uint64_t, IDWriteFontFileStream*> sFontFileStreams;
 
@@ -79,25 +80,27 @@ public:
 
 private:
   static IDWriteFontFileLoader* mInstance;
 };
 
 class DWriteFontFileStream final : public IDWriteFontFileStream
 {
 public:
+  DWriteFontFileStream(uint64_t aFontFileKey);
+
   /**
     * Used by the FontFileLoader to create a new font stream,
     * this font stream is created from data in memory. The memory
     * passed may be released after object creation, it will be
     * copied internally.
     *
     * @param aData Font data
     */
-  DWriteFontFileStream(uint8_t *aData, uint32_t aSize, uint64_t aFontFileKey);
+  bool Initialize(uint8_t *aData, uint32_t aSize);
 
   // IUnknown interface
   IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject)
   {
     if (iid == __uuidof(IDWriteFontFileStream)) {
       *ppObject = static_cast<IDWriteFontFileStream*>(this);
       return S_OK;
     } else if (iid == __uuidof(IUnknown)) {
@@ -130,17 +133,17 @@ public:
 
   virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext);
 
   virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize);
 
   virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime);
 
 private:
-  std::vector<uint8_t> mData;
+  nsTArray<uint8_t> mData;
   Atomic<uint32_t> mRefCnt;
   uint64_t mFontFileKey;
 
   ~DWriteFontFileStream();
 };
 
 IDWriteFontFileLoader* DWriteFontFileLoader::mInstance = nullptr;
 
@@ -161,52 +164,59 @@ DWriteFontFileLoader::CreateStreamFromKe
     return E_FAIL;
   }
 
   found->second->AddRef();
   *fontFileStream = found->second;
   return S_OK;
 }
 
-DWriteFontFileStream::DWriteFontFileStream(uint8_t *aData, uint32_t aSize,
-                                           uint64_t aFontFileKey)
+DWriteFontFileStream::DWriteFontFileStream(uint64_t aFontFileKey)
   : mRefCnt(0)
   , mFontFileKey(aFontFileKey)
 {
-  mData.resize(aSize);
-  memcpy(&mData.front(), aData, aSize);
 }
 
 DWriteFontFileStream::~DWriteFontFileStream()
 {
   StaticMutexAutoLock lock(sFontFileStreamsMutex);
   sFontFileStreams.erase(mFontFileKey);
 }
 
+bool
+DWriteFontFileStream::Initialize(uint8_t *aData, uint32_t aSize)
+{
+  if (!mData.SetLength(aSize, fallible)) {
+    return false;
+  }
+  memcpy(mData.Elements(), aData, aSize);
+  return true;
+}
+
 HRESULT STDMETHODCALLTYPE
 DWriteFontFileStream::GetFileSize(UINT64 *fileSize)
 {
-  *fileSize = mData.size();
+  *fileSize = mData.Length();
   return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE
 DWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime)
 {
   return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE
 DWriteFontFileStream::ReadFileFragment(const void **fragmentStart,
                                        UINT64 fileOffset,
                                        UINT64 fragmentSize,
                                        void **fragmentContext)
 {
   // We are required to do bounds checking.
-  if (fileOffset + fragmentSize > mData.size()) {
+  if (fileOffset + fragmentSize > mData.Length()) {
     return E_FAIL;
   }
 
   // truncate the 64 bit fileOffset to size_t sized index into mData
   size_t index = static_cast<size_t>(fileOffset);
 
   // We should be alive for the duration of this.
   *fragmentStart = &mData[index];
@@ -227,18 +237,22 @@ NativeFontResourceDWrite::Create(uint8_t
   RefPtr<IDWriteFactory> factory = Factory::GetDWriteFactory();
   if (!factory) {
     gfxWarning() << "Failed to get DWrite Factory.";
     return nullptr;
   }
 
   sFontFileStreamsMutex.Lock();
   uint64_t fontFileKey = sNextFontFileKey++;
-  RefPtr<IDWriteFontFileStream> ffsRef =
-    new DWriteFontFileStream(aFontData, aDataLength, fontFileKey);
+  RefPtr<DWriteFontFileStream> ffsRef = new DWriteFontFileStream(fontFileKey);
+  if (!ffsRef->Initialize(aFontData, aDataLength)) {
+    sFontFileStreamsMutex.Unlock();
+    gfxWarning() << "Failed to create DWriteFontFileStream.";
+    return nullptr;
+  }
   sFontFileStreams[fontFileKey] = ffsRef;
   sFontFileStreamsMutex.Unlock();
 
   RefPtr<IDWriteFontFile> fontFile;
   HRESULT hr =
     factory->CreateCustomFontFileReference(&fontFileKey, sizeof(fontFileKey),
                                            DWriteFontFileLoader::Instance(),
                                            getter_AddRefs(fontFile));
--- a/gfx/2d/NativeFontResourceFontconfig.cpp
+++ b/gfx/2d/NativeFontResourceFontconfig.cpp
@@ -27,17 +27,20 @@ NativeFontResourceFontconfig::~NativeFon
 }
 
 already_AddRefed<NativeFontResourceFontconfig>
 NativeFontResourceFontconfig::Create(uint8_t *aFontData, uint32_t aDataLength, FT_Library aFTLibrary)
 {
   if (!aFontData || !aDataLength) {
     return nullptr;
   }
-  UniquePtr<uint8_t[]> fontData(new uint8_t[aDataLength]);
+  UniquePtr<uint8_t[]> fontData(new (fallible) uint8_t[aDataLength]);
+  if (!fontData) {
+    return nullptr;
+  }
   memcpy(fontData.get(), aFontData, aDataLength);
 
   FT_Face face = Factory::NewFTFaceFromData(aFTLibrary, fontData.get(), aDataLength, 0);
   if (!face) {
     return nullptr;
   }
   if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != FT_Err_Ok) {
     Factory::ReleaseFTFace(face);