[subset] Fix checksum calc out-of-bounds access

This commit is contained in:
Behdad Esfahbod 2018-02-23 15:51:26 -08:00
parent d38f37b2e3
commit ec2538c880
2 changed files with 12 additions and 9 deletions

View File

@ -133,32 +133,34 @@ typedef struct OffsetTable
unsigned int table_count) unsigned int table_count)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
/* alloc 12 for the OTHeader */ /* Alloc 12 for the OTHeader. */
if (unlikely (!c->extend_min (*this))) return_trace (false); if (unlikely (!c->extend_min (*this))) return_trace (false);
/* write sfntVersion (bytes 0..3) */ /* Write sfntVersion (bytes 0..3) */
sfnt_version.set (sfnt_tag); sfnt_version.set (sfnt_tag);
/* take space for numTables, searchRange, entrySelector, RangeShift /* Take space for numTables, searchRange, entrySelector, RangeShift
* and the TableRecords themselves * and the TableRecords themselves
*/ */
if (unlikely (!tables.serialize (c, table_count))) return_trace (false); if (unlikely (!tables.serialize (c, table_count))) return_trace (false);
/* write OffsetTables, alloc for and write actual table blobs */ /* Write OffsetTables, alloc for and write actual table blobs. */
for (unsigned int i = 0; i < table_count; i++) for (unsigned int i = 0; i < table_count; i++)
{ {
TableRecord &rec = tables.array[i]; TableRecord &rec = tables.array[i];
hb_blob_t *blob = blobs[i]; hb_blob_t *blob = blobs[i];
rec.tag.set (tags[i]); rec.tag.set (tags[i]);
rec.length.set (hb_blob_get_length (blob)); rec.length.set (hb_blob_get_length (blob));
rec.checkSum.set_for_data (hb_blob_get_data (blob, nullptr), rec.length);
rec.offset.serialize (c, this); rec.offset.serialize (c, this);
// take room for the table /* Allocate room for the table. */
void *p = c->allocate_size<void> (rec.length); void *p = c->allocate_size<void> (rec.length);
const char *start = (const char *) p;
if (unlikely (!p)) {return false;} if (unlikely (!p)) {return false;}
/* copy the actual table */ /* copy the actual table. */
memcpy (p, hb_blob_get_data (blob, nullptr), rec.length); memcpy (p, hb_blob_get_data (blob, nullptr), rec.length);
/* 4-byte allignment */ /* 4-byte allignment. */
if (rec.length % 4) if (rec.length % 4)
p = c->allocate_size<void> (4 - rec.length % 4); p = c->allocate_size<void> (4 - rec.length % 4);
const char *end = (const char *) c->head;
rec.checkSum.set_for_data (start, end - start);
} }
tags += table_count; tags += table_count;
blobs += table_count; blobs += table_count;

View File

@ -762,7 +762,8 @@ struct CheckSum : HBUINT32
static inline uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length) static inline uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length)
{ {
uint32_t Sum = 0L; uint32_t Sum = 0L;
const HBUINT32 *EndPtr = Table+((Length+3) & ~3) / HBUINT32::static_size; assert (0 == (Length & 3));
const HBUINT32 *EndPtr = Table + Length / HBUINT32::static_size;
while (Table < EndPtr) while (Table < EndPtr)
Sum += *Table++; Sum += *Table++;