[dfont] Clean up sanitize()
I don't think I broke anything. Fuzzers will let me know..
This commit is contained in:
parent
361fc26861
commit
dbb764dceb
|
@ -532,9 +532,17 @@ struct hb_bytes_t
|
||||||
inline hb_bytes_t (void) : bytes (nullptr), len (0) {}
|
inline hb_bytes_t (void) : bytes (nullptr), len (0) {}
|
||||||
inline hb_bytes_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {}
|
inline hb_bytes_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {}
|
||||||
inline hb_bytes_t (const void *bytes_, unsigned int len_) : bytes ((const char *) bytes_), len (len_) {}
|
inline hb_bytes_t (const void *bytes_, unsigned int len_) : bytes ((const char *) bytes_), len (len_) {}
|
||||||
|
template <typename T>
|
||||||
|
inline hb_bytes_t (const T& array) : bytes ((const char *) array.arrayZ), len (array.len) {}
|
||||||
|
|
||||||
inline void free (void) { ::free ((void *) bytes); bytes = nullptr; len = 0; }
|
inline void free (void) { ::free ((void *) bytes); bytes = nullptr; len = 0; }
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
inline const Type* as (void) const
|
||||||
|
{
|
||||||
|
return unlikely (!bytes) ? &Null(Type) : reinterpret_cast<const Type *> (bytes);
|
||||||
|
}
|
||||||
|
|
||||||
inline int cmp (const hb_bytes_t &a) const
|
inline int cmp (const hb_bytes_t &a) const
|
||||||
{
|
{
|
||||||
if (len != a.len)
|
if (len != a.len)
|
||||||
|
|
|
@ -293,18 +293,24 @@ struct TTCHeader
|
||||||
|
|
||||||
struct ResourceRecord
|
struct ResourceRecord
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline const hb_bytes_t get_data (const void *data_base) const
|
||||||
|
{ return hb_bytes_t (data_base+offset); }
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c,
|
||||||
|
const void *data_base) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
// actual data sanitization is done on ResourceForkHeader sanitizer
|
return_trace (c->check_struct (this) &&
|
||||||
return_trace (likely (c->check_struct (this)));
|
offset.sanitize (c, data_base));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
HBUINT16 id; /* Resource ID, is really should be signed? */
|
HBUINT16 id; /* Resource ID, is really should be signed? */
|
||||||
HBINT16 nameOffset; /* Offset from beginning of resource name list
|
HBINT16 nameOffset; /* Offset from beginning of resource name list
|
||||||
* to resource name, -1 means there is none. */
|
* to resource name, -1 means there is none. */
|
||||||
HBUINT8 attrs; /* Resource attributes */
|
HBUINT8 attrs; /* Resource attributes */
|
||||||
HBUINT24 dataOffset; /* Offset from beginning of resource data to
|
OffsetTo<LArrayOf<HBUINT8>, HBUINT24>
|
||||||
|
offset; /* Offset from beginning of data block to
|
||||||
* data for this resource */
|
* data for this resource */
|
||||||
HBUINT32 reserved; /* Reserved for handle to resource */
|
HBUINT32 reserved; /* Reserved for handle to resource */
|
||||||
public:
|
public:
|
||||||
|
@ -313,28 +319,33 @@ struct ResourceRecord
|
||||||
|
|
||||||
struct ResourceTypeRecord
|
struct ResourceTypeRecord
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
|
||||||
{
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
// RefList sanitization is done on ResourceMap sanitizer
|
|
||||||
return_trace (likely (c->check_struct (this)));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned int get_resource_count () const { return resCountM1 + 1; }
|
inline unsigned int get_resource_count () const { return resCountM1 + 1; }
|
||||||
|
|
||||||
inline bool is_sfnt () const { return tag == HB_TAG ('s','f','n','t'); }
|
inline bool is_sfnt () const { return tag == HB_TAG ('s','f','n','t'); }
|
||||||
|
|
||||||
inline const ResourceRecord& get_resource_record (const void *base,
|
inline const ResourceRecord& get_resource_record (unsigned int i,
|
||||||
unsigned int i) const
|
const void *type_base) const
|
||||||
{
|
{
|
||||||
return (base+refList)[i];
|
return hb_array_t<ResourceRecord> ((type_base+resourcesZ).arrayZ,
|
||||||
|
get_resource_count ()) [i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c,
|
||||||
|
const void *type_base,
|
||||||
|
const void *data_base) const
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return_trace (c->check_struct (this) &&
|
||||||
|
resourcesZ.sanitize (c, type_base,
|
||||||
|
get_resource_count (),
|
||||||
|
data_base));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Tag tag; /* Resource type. */
|
Tag tag; /* Resource type. */
|
||||||
HBUINT16 resCountM1; /* Number of resources minus 1. */
|
HBUINT16 resCountM1; /* Number of resources minus 1. */
|
||||||
OffsetTo<UnsizedArrayOf<ResourceRecord> >
|
OffsetTo<UnsizedArrayOf<ResourceRecord> >
|
||||||
refList; /* Offset from beginning of resource type list
|
resourcesZ; /* Offset from beginning of resource type list
|
||||||
* to reference item list for this type. */
|
* to reference item list for this type. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (8);
|
DEFINE_SIZE_STATIC (8);
|
||||||
|
@ -342,35 +353,30 @@ struct ResourceTypeRecord
|
||||||
|
|
||||||
struct ResourceMap
|
struct ResourceMap
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
|
||||||
{
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (unlikely (!c->check_struct (this)))
|
|
||||||
return_trace (false);
|
|
||||||
for (unsigned int i = 0; i < get_types_count (); ++i)
|
|
||||||
{
|
|
||||||
const ResourceTypeRecord& type = get_type_record (i);
|
|
||||||
if (unlikely (!type.sanitize (c)))
|
|
||||||
return_trace (false);
|
|
||||||
for (unsigned int j = 0; j < type.get_resource_count (); ++j)
|
|
||||||
if (unlikely (!get_resource_record (type, j).sanitize (c)))
|
|
||||||
return_trace (false);
|
|
||||||
}
|
|
||||||
return_trace (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const ResourceTypeRecord& get_type_record (unsigned int i) const
|
inline const ResourceTypeRecord& get_type_record (unsigned int i) const
|
||||||
{
|
{
|
||||||
// Why offset from the third byte of the object? I'm not sure
|
// Why offset from the third byte of the object? I'm not sure
|
||||||
return (((const char *) this + 2)+typeListZ)[i];
|
return hb_array_t<ResourceTypeRecord> (((2 + (const char *) this )+typeListZ).arrayZ,
|
||||||
|
get_type_count ()) [i];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned int get_types_count () const { return typeCountM1 + 1; }
|
inline unsigned int get_type_count () const { return typeCountM1 + 1; }
|
||||||
|
|
||||||
inline const ResourceRecord &get_resource_record (const ResourceTypeRecord &type,
|
inline const ResourceRecord &get_resource_record (const ResourceTypeRecord &type,
|
||||||
unsigned int i) const
|
unsigned int i) const
|
||||||
{
|
{
|
||||||
return type.get_resource_record (&(this+typeListZ), i);
|
return type.get_resource_record (i, &(this+typeListZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c, const void *data_base) const
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
const void *type_base = &(this+typeListZ);
|
||||||
|
return_trace (c->check_struct (this) &&
|
||||||
|
typeListZ.sanitize (c, 2 + (const char *) this,
|
||||||
|
get_type_count (),
|
||||||
|
type_base,
|
||||||
|
data_base));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -393,7 +399,8 @@ struct ResourceForkHeader
|
||||||
inline unsigned int get_face_count () const
|
inline unsigned int get_face_count () const
|
||||||
{
|
{
|
||||||
const ResourceMap &resource_map = this+map;
|
const ResourceMap &resource_map = this+map;
|
||||||
for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
|
unsigned int count = resource_map.get_type_count ();
|
||||||
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
const ResourceTypeRecord& type = resource_map.get_type_record (i);
|
const ResourceTypeRecord& type = resource_map.get_type_record (i);
|
||||||
if (type.is_sfnt ())
|
if (type.is_sfnt ())
|
||||||
|
@ -402,23 +409,24 @@ struct ResourceForkHeader
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const LArrayOf<HBUINT8>& get_data (const ResourceTypeRecord& type,
|
inline const hb_bytes_t get_data (const ResourceTypeRecord& type,
|
||||||
unsigned int idx) const
|
unsigned int idx) const
|
||||||
{
|
{
|
||||||
const ResourceMap &resource_map = this+map;
|
const ResourceMap &resource_map = this+map;
|
||||||
unsigned int offset = dataOffset + resource_map.get_resource_record (type, idx).dataOffset;
|
const void *data_base = &(this+data);
|
||||||
return StructAtOffset<LArrayOf<HBUINT8> > (this, offset);
|
return resource_map.get_resource_record (type, idx).get_data (data_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const OpenTypeFontFace& get_face (unsigned int idx, unsigned int *base_offset = nullptr) const
|
inline const OpenTypeFontFace& get_face (unsigned int idx,
|
||||||
|
unsigned int *base_offset = nullptr) const
|
||||||
{
|
{
|
||||||
const ResourceMap &resource_map = this+map;
|
const ResourceMap &resource_map = this+map;
|
||||||
for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
|
for (unsigned int i = 0; i < resource_map.get_type_count (); ++i)
|
||||||
{
|
{
|
||||||
const ResourceTypeRecord& type = resource_map.get_type_record (i);
|
const ResourceTypeRecord& type = resource_map.get_type_record (i);
|
||||||
if (type.is_sfnt () && idx < type.get_resource_count ())
|
if (type.is_sfnt () && idx < type.get_resource_count ())
|
||||||
{
|
{
|
||||||
const OpenTypeFontFace &face = (OpenTypeFontFace&) get_data (type, idx).arrayZ;
|
const OpenTypeFontFace &face = *get_data (type, idx).as<OpenTypeFontFace> ();
|
||||||
if (base_offset)
|
if (base_offset)
|
||||||
*base_offset = (const char *) &face - (const char *) this;
|
*base_offset = (const char *) &face - (const char *) this;
|
||||||
return face;
|
return face;
|
||||||
|
@ -430,33 +438,15 @@ struct ResourceForkHeader
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!c->check_struct (this)))
|
return_trace (c->check_struct (this) &&
|
||||||
return_trace (false);
|
map.sanitize (c, this, &(this+data)));
|
||||||
|
|
||||||
const ResourceMap &resource_map = this+map;
|
// XXX Sanitize OpenTypeFontFace's
|
||||||
if (unlikely (!resource_map.sanitize (c)))
|
|
||||||
return_trace (false);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
|
|
||||||
{
|
|
||||||
const ResourceTypeRecord& type = resource_map.get_type_record (i);
|
|
||||||
for (unsigned int j = 0; j < type.get_resource_count (); ++j)
|
|
||||||
{
|
|
||||||
const LArrayOf<HBUINT8>& data = get_data (type, j);
|
|
||||||
if (unlikely (!data.sanitize (c)))
|
|
||||||
return_trace (false);
|
|
||||||
|
|
||||||
if (unlikely (type.is_sfnt () &&
|
|
||||||
!((OpenTypeFontFace&) data.arrayZ).sanitize (c)))
|
|
||||||
return_trace (false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return_trace (true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Offset32 dataOffset; /* Offset from beginning of resource fork
|
LOffsetTo<UnsizedArrayOf<HBUINT8> >
|
||||||
|
data; /* Offset from beginning of resource fork
|
||||||
* to resource data */
|
* to resource data */
|
||||||
LOffsetTo<ResourceMap>
|
LOffsetTo<ResourceMap>
|
||||||
map; /* Offset from beginning of resource fork
|
map; /* Offset from beginning of resource fork
|
||||||
|
|
Loading…
Reference in New Issue