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;
|
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);
|
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();
|
mGlyphDocs.Init();
|
||||||
mGlyphIdMap.Init();
|
mGlyphIdMap.Init();
|
||||||
@ -88,13 +100,13 @@ gfxSVGGlyphs::CompareIndexEntries(const void *aKey, const void *aEntry)
|
|||||||
gfxSVGGlyphsDocument *
|
gfxSVGGlyphsDocument *
|
||||||
gfxSVGGlyphs::FindOrCreateGlyphsDocument(uint32_t aGlyphId)
|
gfxSVGGlyphs::FindOrCreateGlyphsDocument(uint32_t aGlyphId)
|
||||||
{
|
{
|
||||||
if (uint16_t(mHeader->mVersion) != 0) {
|
if (!mDocIndex) {
|
||||||
// Version not understood
|
// Invalid table
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexEntry *entry = (IndexEntry*)bsearch(&aGlyphId, mIndex,
|
IndexEntry *entry = (IndexEntry*)bsearch(&aGlyphId, mDocIndex->mEntries,
|
||||||
uint16_t(mHeader->mIndexLength),
|
uint16_t(mDocIndex->mNumEntries),
|
||||||
sizeof(IndexEntry),
|
sizeof(IndexEntry),
|
||||||
CompareIndexEntries);
|
CompareIndexEntries);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
@ -104,10 +116,14 @@ gfxSVGGlyphs::FindOrCreateGlyphsDocument(uint32_t aGlyphId)
|
|||||||
gfxSVGGlyphsDocument *result = mGlyphDocs.Get(entry->mDocOffset);
|
gfxSVGGlyphsDocument *result = mGlyphDocs.Get(entry->mDocOffset);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
const uint8_t *data = (const uint8_t*)hb_blob_get_data(mSVGData, nullptr);
|
unsigned int length;
|
||||||
result = new gfxSVGGlyphsDocument(data + entry->mDocOffset,
|
const uint8_t *data = (const uint8_t*)hb_blob_get_data(mSVGData, &length);
|
||||||
entry->mDocLength);
|
if (entry->mDocOffset > 0 &&
|
||||||
mGlyphDocs.Put(entry->mDocOffset, result);
|
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;
|
return result;
|
||||||
|
@ -127,15 +127,21 @@ private:
|
|||||||
|
|
||||||
const struct Header {
|
const struct Header {
|
||||||
mozilla::AutoSwap_PRUint16 mVersion;
|
mozilla::AutoSwap_PRUint16 mVersion;
|
||||||
mozilla::AutoSwap_PRUint16 mIndexLength;
|
mozilla::AutoSwap_PRUint32 mDocIndexOffset;
|
||||||
|
mozilla::AutoSwap_PRUint32 mColorPalettesOffset;
|
||||||
} *mHeader;
|
} *mHeader;
|
||||||
|
|
||||||
const struct IndexEntry {
|
struct IndexEntry {
|
||||||
mozilla::AutoSwap_PRUint16 mStartGlyph;
|
mozilla::AutoSwap_PRUint16 mStartGlyph;
|
||||||
mozilla::AutoSwap_PRUint16 mEndGlyph;
|
mozilla::AutoSwap_PRUint16 mEndGlyph;
|
||||||
mozilla::AutoSwap_PRUint32 mDocOffset;
|
mozilla::AutoSwap_PRUint32 mDocOffset;
|
||||||
mozilla::AutoSwap_PRUint32 mDocLength;
|
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);
|
static int CompareIndexEntries(const void *_a, const void *_b);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user