mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 906521. Part 6: Make gfxSVGGlyphs understand the new table format. r=jfkthame
This also adds a bunch of buffer sanity checks to the code. This may not be strictly necessary, thanks to OTS, but I think we should code defensively here too. --HG-- extra : rebase_source : 26b11505aa143fae6f63cd5858c87a259bb54b50
This commit is contained in:
parent
fc5637dc25
commit
8bdab20fd7
@ -46,9 +46,21 @@ gfxSVGGlyphs::gfxSVGGlyphs(hb_blob_t *aSVGTable)
|
||||
{
|
||||
mSVGData = aSVGTable;
|
||||
|
||||
const char* svgData = hb_blob_get_data(mSVGData, nullptr);
|
||||
unsigned int length;
|
||||
const char* svgData = hb_blob_get_data(mSVGData, &length);
|
||||
mHeader = reinterpret_cast<const Header*>(svgData);
|
||||
mIndex = reinterpret_cast<const IndexEntry*>(svgData + sizeof(Header));
|
||||
mDocIndex = nullptr;
|
||||
|
||||
if (sizeof(Header) <= length && uint16_t(mHeader->mVersion) == 0 &&
|
||||
uint64_t(mHeader->mDocIndexOffset) + 2 <= length) {
|
||||
const DocIndex* docIndex = reinterpret_cast<const DocIndex*>
|
||||
(svgData + mHeader->mDocIndexOffset);
|
||||
// Limit the number of documents to avoid overflow
|
||||
if (uint64_t(mHeader->mDocIndexOffset) + 2 +
|
||||
uint16_t(docIndex->mNumEntries) * sizeof(IndexEntry) <= length) {
|
||||
mDocIndex = docIndex;
|
||||
}
|
||||
}
|
||||
|
||||
mGlyphDocs.Init();
|
||||
mGlyphIdMap.Init();
|
||||
@ -88,13 +100,13 @@ gfxSVGGlyphs::CompareIndexEntries(const void *aKey, const void *aEntry)
|
||||
gfxSVGGlyphsDocument *
|
||||
gfxSVGGlyphs::FindOrCreateGlyphsDocument(uint32_t aGlyphId)
|
||||
{
|
||||
if (uint16_t(mHeader->mVersion) != 0) {
|
||||
// Version not understood
|
||||
if (!mDocIndex) {
|
||||
// Invalid table
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IndexEntry *entry = (IndexEntry*)bsearch(&aGlyphId, mIndex,
|
||||
uint16_t(mHeader->mIndexLength),
|
||||
IndexEntry *entry = (IndexEntry*)bsearch(&aGlyphId, mDocIndex->mEntries,
|
||||
uint16_t(mDocIndex->mNumEntries),
|
||||
sizeof(IndexEntry),
|
||||
CompareIndexEntries);
|
||||
if (!entry) {
|
||||
@ -104,11 +116,15 @@ gfxSVGGlyphs::FindOrCreateGlyphsDocument(uint32_t aGlyphId)
|
||||
gfxSVGGlyphsDocument *result = mGlyphDocs.Get(entry->mDocOffset);
|
||||
|
||||
if (!result) {
|
||||
const uint8_t *data = (const uint8_t*)hb_blob_get_data(mSVGData, nullptr);
|
||||
result = new gfxSVGGlyphsDocument(data + entry->mDocOffset,
|
||||
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 + entry->mDocLength <= length) {
|
||||
result = new gfxSVGGlyphsDocument(data + mHeader->mDocIndexOffset + entry->mDocOffset,
|
||||
entry->mDocLength);
|
||||
mGlyphDocs.Put(entry->mDocOffset, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -127,15 +127,21 @@ private:
|
||||
|
||||
const struct Header {
|
||||
mozilla::AutoSwap_PRUint16 mVersion;
|
||||
mozilla::AutoSwap_PRUint16 mIndexLength;
|
||||
mozilla::AutoSwap_PRUint32 mDocIndexOffset;
|
||||
mozilla::AutoSwap_PRUint32 mColorPalettesOffset;
|
||||
} *mHeader;
|
||||
|
||||
const struct IndexEntry {
|
||||
struct IndexEntry {
|
||||
mozilla::AutoSwap_PRUint16 mStartGlyph;
|
||||
mozilla::AutoSwap_PRUint16 mEndGlyph;
|
||||
mozilla::AutoSwap_PRUint32 mDocOffset;
|
||||
mozilla::AutoSwap_PRUint32 mDocLength;
|
||||
} *mIndex;
|
||||
};
|
||||
|
||||
const struct DocIndex {
|
||||
mozilla::AutoSwap_PRUint16 mNumEntries;
|
||||
IndexEntry mEntries[1]; /* actual length = mNumEntries */
|
||||
} *mDocIndex;
|
||||
|
||||
static int CompareIndexEntries(const void *_a, const void *_b);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user