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:
Robert O'Callahan 2013-08-20 01:08:43 +12:00
parent fc5637dc25
commit 8bdab20fd7
2 changed files with 35 additions and 13 deletions

View File

@ -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,10 +116,14 @@ 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,
entry->mDocLength);
mGlyphDocs.Put(entry->mDocOffset, result);
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;

View File

@ -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);
};