Commit e9dcc62c authored by Jonathan Kew's avatar Jonathan Kew Committed by Pier Angelo Vendrame
Browse files

Bug 2029446 - Don't hold on to EntryHandles while creating an svg-glyphs...

Bug 2029446 - Don't hold on to EntryHandles while creating an svg-glyphs document.  a=RyanVM DONTBUILD

(clauditor-suggested fix)

Original Revision: https://phabricator.services.mozilla.com/D293134

Differential Revision: https://phabricator.services.mozilla.com/D293515
parent e6a6fd60
Loading
Loading
Loading
Loading
+33 −28
Original line number Diff line number Diff line
@@ -103,30 +103,29 @@ gfxSVGGlyphsDocument* gfxSVGGlyphs::FindOrCreateGlyphsDocument(
    return nullptr;
  }

  return mGlyphDocs.WithEntryHandle(
      entry->mDocOffset, [&](auto&& glyphDocsEntry) -> gfxSVGGlyphsDocument* {
        if (!glyphDocsEntry) {
  // Do not hold an EntryHandle on mGlyphDocs while constructing the
  // gfxSVGGlyphsDocument: its SetupPresentation() flushes layout and may
  // re-enter font code, which could mutate our hashtables and invalidate the
  // handle.
  if (auto existing = mGlyphDocs.Lookup(entry->mDocOffset)) {
    return existing.Data().get();
  }

  unsigned int length;
          const uint8_t* data =
              (const uint8_t*)hb_blob_get_data(mSVGData, &length);
          if (entry->mDocOffset > 0 && uint64_t(mHeader->mDocIndexOffset) +
                                               entry->mDocOffset +
  const uint8_t* data = (const uint8_t*)hb_blob_get_data(mSVGData, &length);
  if (entry->mDocOffset > 0 &&
      uint64_t(mHeader->mDocIndexOffset) + entry->mDocOffset +
              entry->mDocLength <=
          length) {
            return glyphDocsEntry
                .Insert(MakeUnique<gfxSVGGlyphsDocument>(
                    data + mHeader->mDocIndexOffset + entry->mDocOffset,
                    entry->mDocLength, this))
                .get();
    auto doc = MakeUnique<gfxSVGGlyphsDocument>(
        data + mHeader->mDocIndexOffset + entry->mDocOffset, entry->mDocLength,
        this);
    return mGlyphDocs.InsertOrUpdate(entry->mDocOffset, std::move(doc)).get();
  }

  return nullptr;
}

        return glyphDocsEntry->get();
      });
}

nsresult gfxSVGGlyphsDocument::SetupPresentation() {
  nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
      nsContentUtils::FindInternalDocumentViewer(SVG_CONTENT_TYPE);
@@ -223,13 +222,19 @@ bool gfxSVGGlyphs::GetGlyphExtents(uint32_t aGlyphId,
}

Element* gfxSVGGlyphs::GetGlyphElement(uint32_t aGlyphId) {
  return mGlyphIdMap.LookupOrInsertWith(aGlyphId, [&] {
  // Do not hold an EntryHandle on mGlyphIdMap across
  // FindOrCreateGlyphsDocument: creating the glyphs document flushes layout
  // and may recursively enter this method, mutating mGlyphIdMap and
  // invalidating the handle.
  if (auto existing = mGlyphIdMap.Lookup(aGlyphId)) {
    return existing.Data();
  }
  Element* elem = nullptr;
  if (gfxSVGGlyphsDocument* set = FindOrCreateGlyphsDocument(aGlyphId)) {
    elem = set->GetGlyphElement(aGlyphId);
  }
  mGlyphIdMap.InsertOrUpdate(aGlyphId, elem);
  return elem;
  });
}

bool gfxSVGGlyphs::HasSVGGlyph(uint32_t aGlyphId) {