Bug 1452467 - Make native font resource memory allocations fallible. r=lsalzman
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 13 Apr 2018 13:33:15 -0400
changeset 413265 6f19a98e3d4c101614e606bcf52f071dc3ea172e
parent 413264 69f26860c7d23c1c71db6778f342829ee7c8b118
child 413266 498dc1fd6954cd8fa817a5eb49594ec33b0ed49b
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:
+  explicit 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);