[name] Do record sanitization at run-time

This commit is contained in:
Behdad Esfahbod 2018-10-23 23:16:06 -07:00
parent a53d301b1c
commit dc9a5f88b4
3 changed files with 51 additions and 39 deletions

View File

@ -530,36 +530,6 @@ struct hb_auto_t : Type
void fini (void) {} void fini (void) {}
}; };
template <typename T>
struct hb_array_t
{
inline hb_array_t (void) : arrayZ (nullptr), len (0) {}
inline hb_array_t (T *array_, unsigned int len_) : arrayZ (array_), len (len_) {}
inline T& operator [] (unsigned int i) const
{
if (unlikely (i >= len)) return Null(T);
return arrayZ[i];
}
inline hb_array_t<T> sub_array (unsigned int start_offset, unsigned int seg_count) const
{
unsigned int count = len;
if (unlikely (start_offset > count))
count = 0;
else
count -= start_offset;
count = MIN (count, seg_count);
return hb_array_t<T> (arrayZ + start_offset, count);
}
inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; }
T *arrayZ;
unsigned int len;
};
template <typename T> static inline
hb_array_t<T> hb_array (T *array, unsigned int len) { return hb_array_t<T> (array, len); }
struct hb_bytes_t struct hb_bytes_t
{ {
@ -589,6 +559,42 @@ struct hb_bytes_t
unsigned int len; unsigned int len;
}; };
template <typename T>
struct hb_array_t
{
inline hb_array_t (void) : arrayZ (nullptr), len (0) {}
inline hb_array_t (T *array_, unsigned int len_) : arrayZ (array_), len (len_) {}
inline T& operator [] (unsigned int i) const
{
if (unlikely (i >= len)) return Null(T);
return arrayZ[i];
}
inline hb_array_t<T> sub_array (unsigned int start_offset, unsigned int seg_count) const
{
unsigned int count = len;
if (unlikely (start_offset > count))
count = 0;
else
count -= start_offset;
count = MIN (count, seg_count);
return hb_array_t<T> (arrayZ + start_offset, count);
}
inline hb_bytes_t as_bytes (void) const
{
return hb_bytes_t (arrayZ, len * sizeof (T));
}
inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; }
T *arrayZ;
unsigned int len;
};
template <typename T> static inline
hb_array_t<T> hb_array (T *array, unsigned int len) { return hb_array_t<T> (array, len); }
struct HbOpOr struct HbOpOr
{ {

View File

@ -152,13 +152,6 @@ struct name
{ {
static const hb_tag_t tableTag = HB_OT_TAG_name; static const hb_tag_t tableTag = HB_OT_TAG_name;
inline hb_bytes_t get_name (unsigned int idx) const
{
const hb_array_t<const NameRecord> all_names (nameRecordZ.arrayZ, count);
const NameRecord &record = all_names[idx];
return hb_bytes_t ((const char *) (this+stringOffset).arrayZ + record.offset, record.length);
}
inline unsigned int get_size (void) const inline unsigned int get_size (void) const
{ return min_size + count * nameRecordZ[0].min_size; } { return min_size + count * nameRecordZ[0].min_size; }
@ -178,7 +171,7 @@ struct name
return_trace (c->check_struct (this) && return_trace (c->check_struct (this) &&
likely (format == 0 || format == 1) && likely (format == 0 || format == 1) &&
c->check_array (nameRecordZ.arrayZ, count) && c->check_array (nameRecordZ.arrayZ, count) &&
sanitize_records (c)); c->check_range (this, stringOffset));
} }
struct accelerator_t struct accelerator_t
@ -187,6 +180,9 @@ struct name
{ {
this->blob = hb_sanitize_context_t().reference_table<name> (face); this->blob = hb_sanitize_context_t().reference_table<name> (face);
this->table = this->blob->as<name> (); this->table = this->blob->as<name> ();
assert (this->blob->length >= this->table->stringOffset);
this->pool = (this->table+this->table->stringOffset).arrayZ;
this->pool_len = this->blob->length - this->table->stringOffset;
const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ, const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ,
this->table->count); this->table->count);
@ -246,8 +242,18 @@ struct name
return entry->entry_index; return entry->entry_index;
} }
inline hb_bytes_t get_name (unsigned int idx) const
{
const hb_array_t<const NameRecord> all_names (table->nameRecordZ.arrayZ, table->count);
const NameRecord &record = all_names[idx];
const hb_array_t<const char> string_pool ((const char *) pool, pool_len);
return string_pool.sub_array (record.offset, record.length).as_bytes ();
}
private: private:
hb_blob_t *blob; hb_blob_t *blob;
const void *pool;
unsigned int pool_len;
public: public:
const name *table; const name *table;
hb_vector_t<hb_ot_name_entry_t> names; hb_vector_t<hb_ot_name_entry_t> names;

View File

@ -110,7 +110,7 @@ hb_ot_name_get_utf (hb_face_t *face,
int idx = name.get_index (name_id, language, &width); int idx = name.get_index (name_id, language, &width);
if (idx != -1) if (idx != -1)
{ {
hb_bytes_t bytes = name.table->get_name (idx); hb_bytes_t bytes = name.get_name (idx);
if (width == 2) /* UTF16-BE */ if (width == 2) /* UTF16-BE */
return hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (&bytes, text_size, text); return hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (&bytes, text_size, text);