Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

fix crash in FontCollection::init() when FontFamily is empty #23019

Merged
merged 5 commits into from
Dec 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 26 additions & 20 deletions third_party/txt/src/minikin/FontCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,20 @@ std::string GetFontLocale(uint32_t langListId) {
return langs.size() ? langs[0].getString() : "";
}

FontCollection::FontCollection(std::shared_ptr<FontFamily>&& typeface)
: mMaxChar(0) {
std::vector<std::shared_ptr<FontFamily>> typefaces;
typefaces.push_back(typeface);
init(typefaces);
std::shared_ptr<minikin::FontCollection> FontCollection::Create(
const std::vector<std::shared_ptr<FontFamily>>& typefaces) {
std::shared_ptr<minikin::FontCollection> font_collection(
new minikin::FontCollection());
if (!font_collection || !font_collection->init(typefaces)) {
return nullptr;
}
return font_collection;
}

FontCollection::FontCollection(
const vector<std::shared_ptr<FontFamily>>& typefaces)
: mMaxChar(0) {
init(typefaces);
}
FontCollection::FontCollection() : mMaxChar(0) {}

void FontCollection::init(
const vector<std::shared_ptr<FontFamily>>& typefaces) {
bool FontCollection::init(
const std::vector<std::shared_ptr<FontFamily>>& typefaces) {
std::scoped_lock _l(gMinikinLock);
mId = sNextId++;
vector<uint32_t> lastChar;
Expand All @@ -91,10 +90,14 @@ void FontCollection::init(
mSupportedAxes.insert(supportedAxes.begin(), supportedAxes.end());
}
nTypefaces = mFamilies.size();
LOG_ALWAYS_FATAL_IF(nTypefaces == 0,
"Font collection must have at least one valid typeface");
LOG_ALWAYS_FATAL_IF(nTypefaces > 254,
"Font collection may only have up to 254 font families.");
if (nTypefaces == 0) {
ALOGE("Font collection must have at least one valid typeface.");
return false;
}
if (nTypefaces > 254) {
ALOGE("Font collection may only have up to 254 font families.");
return false;
}
size_t nPages = (mMaxChar + kPageMask) >> kLogCharsPerPage;
// TODO: Use variation selector map for mRanges construction.
// A font can have a glyph for a base code point and variation selector pair
Expand Down Expand Up @@ -122,9 +125,12 @@ void FontCollection::init(
}
range->end = mFamilyVec.size();
}
// See the comment in Range for more details.
LOG_ALWAYS_FATAL_IF(mFamilyVec.size() >= 0xFFFF,
"Exceeded the maximum indexable cmap coverage.");

if (mFamilyVec.size() >= 0xFFFF) {
ALOGE("Exceeded the maximum indexable cmap coverage.");
return false;
}
return true;
}

// Special scores for the font fallback.
Expand Down Expand Up @@ -566,7 +572,7 @@ std::shared_ptr<FontCollection> FontCollection::createCollectionWithVariation(
}
}

return std::shared_ptr<FontCollection>(new FontCollection(families));
return FontCollection::Create(std::move(families));
}

uint32_t FontCollection::getId() const {
Expand Down
8 changes: 5 additions & 3 deletions third_party/txt/src/minikin/FontCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@
namespace minikin {

class FontCollection {
private:
explicit FontCollection();

public:
explicit FontCollection(
static std::shared_ptr<minikin::FontCollection> Create(
const std::vector<std::shared_ptr<FontFamily>>& typefaces);
explicit FontCollection(std::shared_ptr<FontFamily>&& typeface);

// libtxt extension: an interface for looking up fallback fonts for characters
// that do not match this collection's font families.
Expand Down Expand Up @@ -94,7 +96,7 @@ class FontCollection {
};

// Initialize the FontCollection.
void init(const std::vector<std::shared_ptr<FontFamily>>& typefaces);
bool init(const std::vector<std::shared_ptr<FontFamily>>& typefaces);

const std::shared_ptr<FontFamily>& getFamilyForChar(uint32_t ch,
uint32_t vs,
Expand Down
6 changes: 5 additions & 1 deletion third_party/txt/src/txt/font_collection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,11 @@ FontCollection::GetMinikinFontCollectionForFamilies(
}
// Create the minikin font collection.
auto font_collection =
std::make_shared<minikin::FontCollection>(std::move(minikin_families));
minikin::FontCollection::Create(std::move(minikin_families));
if (!font_collection) {
font_collections_cache_[family_key] = nullptr;
return nullptr;
}
if (enable_font_fallback_) {
font_collection->set_fallback_font_provider(
std::make_unique<TxtFallbackFontProvider>(shared_from_this()));
Expand Down
3 changes: 3 additions & 0 deletions third_party/txt/src/txt/paragraph_txt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,9 @@ void ParagraphTxt::Layout(double width) {

std::shared_ptr<minikin::FontCollection> minikin_font_collection =
GetMinikinFontCollectionForStyle(run.style());
if (!minikin_font_collection) {
return;
}

// Lay out this run.
uint16_t* text_ptr = text_.data();
Expand Down