remote fonts: Validate format on deserialized glyph.
R=mtklein@google.com, herb@google.com Bug: 949000 Change-Id: Ib17635ea34db80987a1f2b3c0e6fcc33ab2b7a6b Reviewed-on: https://skia-review.googlesource.com/c/skia/+/206173 Commit-Queue: Khushal Sagar <khushalsagar@chromium.org> Reviewed-by: Mike Klein <mtklein@google.com> Reviewed-by: Herb Derby <herb@google.com> Auto-Submit: Khushal Sagar <khushalsagar@chromium.org>
This commit is contained in:
parent
8cc424806e
commit
add8cf90b2
@ -40,6 +40,8 @@ struct SkMask {
|
|||||||
uint32_t fRowBytes;
|
uint32_t fRowBytes;
|
||||||
Format fFormat;
|
Format fFormat;
|
||||||
|
|
||||||
|
static bool IsValidFormat(uint8_t format) { return format < kCountMaskFormats; }
|
||||||
|
|
||||||
/** Returns true if the mask is empty: i.e. it has an empty bounds.
|
/** Returns true if the mask is empty: i.e. it has an empty bounds.
|
||||||
*/
|
*/
|
||||||
bool isEmpty() const { return fBounds.isEmpty(); }
|
bool isEmpty() const { return fBounds.isEmpty(); }
|
||||||
|
@ -174,6 +174,10 @@ bool read_path(Deserializer* deserializer, SkGlyph* glyph, SkStrike* cache) {
|
|||||||
auto* path = deserializer->read(pathSize, kPathAlignment);
|
auto* path = deserializer->read(pathSize, kPathAlignment);
|
||||||
if (!path) return false;
|
if (!path) return false;
|
||||||
|
|
||||||
|
// Don't overwrite the path if we already have one. We could have used a fallback if the
|
||||||
|
// glyph was missing earlier.
|
||||||
|
if (glyph->fPathData != nullptr) return true;
|
||||||
|
|
||||||
return cache->initializePath(glyph, path, pathSize);
|
return cache->initializePath(glyph, path, pathSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,8 +490,9 @@ void SkStrikeServer::SkGlyphCacheState::writePendingGlyphs(Serializer* serialize
|
|||||||
for (const auto& glyphID : fPendingGlyphImages) {
|
for (const auto& glyphID : fPendingGlyphImages) {
|
||||||
SkGlyph glyph{glyphID};
|
SkGlyph glyph{glyphID};
|
||||||
fContext->getMetrics(&glyph);
|
fContext->getMetrics(&glyph);
|
||||||
writeGlyph(&glyph, serializer);
|
SkASSERT(SkMask::IsValidFormat(glyph.fMaskFormat));
|
||||||
|
|
||||||
|
writeGlyph(&glyph, serializer);
|
||||||
auto imageSize = glyph.computeImageSize();
|
auto imageSize = glyph.computeImageSize();
|
||||||
if (imageSize == 0u) continue;
|
if (imageSize == 0u) continue;
|
||||||
|
|
||||||
@ -503,6 +508,8 @@ void SkStrikeServer::SkGlyphCacheState::writePendingGlyphs(Serializer* serialize
|
|||||||
for (const auto& glyphID : fPendingGlyphPaths) {
|
for (const auto& glyphID : fPendingGlyphPaths) {
|
||||||
SkGlyph glyph{glyphID};
|
SkGlyph glyph{glyphID};
|
||||||
fContext->getMetrics(&glyph);
|
fContext->getMetrics(&glyph);
|
||||||
|
SkASSERT(SkMask::IsValidFormat(glyph.fMaskFormat));
|
||||||
|
|
||||||
writeGlyph(&glyph, serializer);
|
writeGlyph(&glyph, serializer);
|
||||||
writeGlyphPath(glyphID, serializer);
|
writeGlyphPath(glyphID, serializer);
|
||||||
}
|
}
|
||||||
@ -680,6 +687,8 @@ static bool readGlyph(SkTLazy<SkGlyph>& glyph, Deserializer* deserializer) {
|
|||||||
if (!deserializer->read<int16_t>(&glyph->fLeft)) return false;
|
if (!deserializer->read<int16_t>(&glyph->fLeft)) return false;
|
||||||
if (!deserializer->read<int8_t>(&glyph->fForceBW)) return false;
|
if (!deserializer->read<int8_t>(&glyph->fForceBW)) return false;
|
||||||
if (!deserializer->read<uint8_t>(&glyph->fMaskFormat)) return false;
|
if (!deserializer->read<uint8_t>(&glyph->fMaskFormat)) return false;
|
||||||
|
if (!SkMask::IsValidFormat(glyph->fMaskFormat)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,9 +773,14 @@ bool SkStrikeClient::readStrikeData(const volatile void* memory, size_t memorySi
|
|||||||
auto imageSize = glyph->computeImageSize();
|
auto imageSize = glyph->computeImageSize();
|
||||||
if (imageSize == 0u) continue;
|
if (imageSize == 0u) continue;
|
||||||
|
|
||||||
auto* image = deserializer.read(imageSize, allocatedGlyph->formatAlignment());
|
auto* image = deserializer.read(imageSize, glyph->formatAlignment());
|
||||||
if (!image) READ_FAILURE
|
if (!image) READ_FAILURE
|
||||||
strike->initializeImage(image, imageSize, allocatedGlyph);
|
|
||||||
|
// Don't overwrite the image if we already have one. We could have used a fallback if
|
||||||
|
// the glyph was missing earlier.
|
||||||
|
if (allocatedGlyph->fImage == nullptr) {
|
||||||
|
strike->initializeImage(image, imageSize, allocatedGlyph);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t glyphPathsCount = 0u;
|
uint64_t glyphPathsCount = 0u;
|
||||||
|
@ -142,9 +142,7 @@ const void* SkStrike::findImage(const SkGlyph& glyph) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SkStrike::initializeImage(const volatile void* data, size_t size, SkGlyph* glyph) {
|
void SkStrike::initializeImage(const volatile void* data, size_t size, SkGlyph* glyph) {
|
||||||
// Don't overwrite the image if we already have one. We could have used a fallback if the
|
SkASSERT(!glyph->fImage);
|
||||||
// glyph was missing earlier.
|
|
||||||
if (glyph->fImage) return;
|
|
||||||
|
|
||||||
if (glyph->fWidth > 0 && glyph->fWidth < kMaxGlyphWidth) {
|
if (glyph->fWidth > 0 && glyph->fWidth < kMaxGlyphWidth) {
|
||||||
size_t allocSize = glyph->allocImage(&fAlloc);
|
size_t allocSize = glyph->allocImage(&fAlloc);
|
||||||
@ -180,9 +178,7 @@ const SkPath* SkStrike::findPath(const SkGlyph& glyph) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SkStrike::initializePath(SkGlyph* glyph, const volatile void* data, size_t size) {
|
bool SkStrike::initializePath(SkGlyph* glyph, const volatile void* data, size_t size) {
|
||||||
// Don't overwrite the path if we already have one. We could have used a fallback if the
|
SkASSERT(!glyph->fPathData);
|
||||||
// glyph was missing earlier.
|
|
||||||
if (glyph->fPathData) return true;
|
|
||||||
|
|
||||||
if (glyph->fWidth) {
|
if (glyph->fWidth) {
|
||||||
SkGlyph::PathData* pathData = fAlloc.make<SkGlyph::PathData>();
|
SkGlyph::PathData* pathData = fAlloc.make<SkGlyph::PathData>();
|
||||||
|
@ -950,12 +950,6 @@ DEF_TEST(SkRemoteGlyphCache_ReWriteGlyph, reporter) {
|
|||||||
REPORTER_ASSERT(reporter, fallbackCache.get() != nullptr);
|
REPORTER_ASSERT(reporter, fallbackCache.get() != nullptr);
|
||||||
auto glyph = fallbackCache->getRawGlyphByID(lostGlyphID);
|
auto glyph = fallbackCache->getRawGlyphByID(lostGlyphID);
|
||||||
REPORTER_ASSERT(reporter, glyph->fMaskFormat == fakeMask);
|
REPORTER_ASSERT(reporter, glyph->fMaskFormat == fakeMask);
|
||||||
|
|
||||||
// Try overriding the image, it should stay the same.
|
|
||||||
REPORTER_ASSERT(reporter,
|
|
||||||
memcmp(glyph->fImage, glyphImage, glyph->computeImageSize()) == 0);
|
|
||||||
const uint8_t newGlyphImage[] = {0, 0};
|
|
||||||
fallbackCache->initializeImage(newGlyphImage, glyph->computeImageSize(), glyph);
|
|
||||||
REPORTER_ASSERT(reporter,
|
REPORTER_ASSERT(reporter,
|
||||||
memcmp(glyph->fImage, glyphImage, glyph->computeImageSize()) == 0);
|
memcmp(glyph->fImage, glyphImage, glyph->computeImageSize()) == 0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user