Skip to content

Commit 913f63f

Browse files
liguishenggspencergoog
authored andcommitted
fix crash in FontCollection::init() when FontFamily is empty (flutter#23019)
1 parent 47b68d1 commit 913f63f

File tree

4 files changed

+39
-24
lines changed

4 files changed

+39
-24
lines changed

third_party/txt/src/minikin/FontCollection.cpp

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,20 @@ std::string GetFontLocale(uint32_t langListId) {
5151
return langs.size() ? langs[0].getString() : "";
5252
}
5353

54-
FontCollection::FontCollection(std::shared_ptr<FontFamily>&& typeface)
55-
: mMaxChar(0) {
56-
std::vector<std::shared_ptr<FontFamily>> typefaces;
57-
typefaces.push_back(typeface);
58-
init(typefaces);
54+
std::shared_ptr<minikin::FontCollection> FontCollection::Create(
55+
const std::vector<std::shared_ptr<FontFamily>>& typefaces) {
56+
std::shared_ptr<minikin::FontCollection> font_collection(
57+
new minikin::FontCollection());
58+
if (!font_collection || !font_collection->init(typefaces)) {
59+
return nullptr;
60+
}
61+
return font_collection;
5962
}
6063

61-
FontCollection::FontCollection(
62-
const vector<std::shared_ptr<FontFamily>>& typefaces)
63-
: mMaxChar(0) {
64-
init(typefaces);
65-
}
64+
FontCollection::FontCollection() : mMaxChar(0) {}
6665

67-
void FontCollection::init(
68-
const vector<std::shared_ptr<FontFamily>>& typefaces) {
66+
bool FontCollection::init(
67+
const std::vector<std::shared_ptr<FontFamily>>& typefaces) {
6968
std::scoped_lock _l(gMinikinLock);
7069
mId = sNextId++;
7170
vector<uint32_t> lastChar;
@@ -91,10 +90,14 @@ void FontCollection::init(
9190
mSupportedAxes.insert(supportedAxes.begin(), supportedAxes.end());
9291
}
9392
nTypefaces = mFamilies.size();
94-
LOG_ALWAYS_FATAL_IF(nTypefaces == 0,
95-
"Font collection must have at least one valid typeface");
96-
LOG_ALWAYS_FATAL_IF(nTypefaces > 254,
97-
"Font collection may only have up to 254 font families.");
93+
if (nTypefaces == 0) {
94+
ALOGE("Font collection must have at least one valid typeface.");
95+
return false;
96+
}
97+
if (nTypefaces > 254) {
98+
ALOGE("Font collection may only have up to 254 font families.");
99+
return false;
100+
}
98101
size_t nPages = (mMaxChar + kPageMask) >> kLogCharsPerPage;
99102
// TODO: Use variation selector map for mRanges construction.
100103
// A font can have a glyph for a base code point and variation selector pair
@@ -122,9 +125,12 @@ void FontCollection::init(
122125
}
123126
range->end = mFamilyVec.size();
124127
}
125-
// See the comment in Range for more details.
126-
LOG_ALWAYS_FATAL_IF(mFamilyVec.size() >= 0xFFFF,
127-
"Exceeded the maximum indexable cmap coverage.");
128+
129+
if (mFamilyVec.size() >= 0xFFFF) {
130+
ALOGE("Exceeded the maximum indexable cmap coverage.");
131+
return false;
132+
}
133+
return true;
128134
}
129135

130136
// Special scores for the font fallback.
@@ -566,7 +572,7 @@ std::shared_ptr<FontCollection> FontCollection::createCollectionWithVariation(
566572
}
567573
}
568574

569-
return std::shared_ptr<FontCollection>(new FontCollection(families));
575+
return FontCollection::Create(std::move(families));
570576
}
571577

572578
uint32_t FontCollection::getId() const {

third_party/txt/src/minikin/FontCollection.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@
2828
namespace minikin {
2929

3030
class FontCollection {
31+
private:
32+
explicit FontCollection();
33+
3134
public:
32-
explicit FontCollection(
35+
static std::shared_ptr<minikin::FontCollection> Create(
3336
const std::vector<std::shared_ptr<FontFamily>>& typefaces);
34-
explicit FontCollection(std::shared_ptr<FontFamily>&& typeface);
3537

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

9698
// Initialize the FontCollection.
97-
void init(const std::vector<std::shared_ptr<FontFamily>>& typefaces);
99+
bool init(const std::vector<std::shared_ptr<FontFamily>>& typefaces);
98100

99101
const std::shared_ptr<FontFamily>& getFamilyForChar(uint32_t ch,
100102
uint32_t vs,

third_party/txt/src/txt/font_collection.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,11 @@ FontCollection::GetMinikinFontCollectionForFamilies(
207207
}
208208
// Create the minikin font collection.
209209
auto font_collection =
210-
std::make_shared<minikin::FontCollection>(std::move(minikin_families));
210+
minikin::FontCollection::Create(std::move(minikin_families));
211+
if (!font_collection) {
212+
font_collections_cache_[family_key] = nullptr;
213+
return nullptr;
214+
}
211215
if (enable_font_fallback_) {
212216
font_collection->set_fallback_font_provider(
213217
std::make_unique<TxtFallbackFontProvider>(shared_from_this()));

third_party/txt/src/txt/paragraph_txt.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,9 @@ void ParagraphTxt::Layout(double width) {
807807

808808
std::shared_ptr<minikin::FontCollection> minikin_font_collection =
809809
GetMinikinFontCollectionForStyle(run.style());
810+
if (!minikin_font_collection) {
811+
return;
812+
}
810813

811814
// Lay out this run.
812815
uint16_t* text_ptr = text_.data();

0 commit comments

Comments
 (0)