*
* Adobe Author(s): Michiharu Ariza
*/
-#ifndef HB_OT_CFF_COMMON_HH
-#define HB_OT_CFF_COMMON_HH
+#ifndef HB_OT_CFF_COMMON_PRIVATE_HH
+#define HB_OT_CFF_COMMON_PRIVATE_HH
#include "hb-open-type-private.hh"
#include "hb-ot-layout-common-private.hh"
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
- c->check_array (offsets, offSize, count + 1) &&
- c->check_array (data_base (), 1, offset_at (count)));
+ return_trace (likely (c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
+ c->check_array (offsets, offSize, count + 1) &&
+ c->check_array (data_base (), 1, max_offset () - 1)));
}
inline unsigned int offset_array_size (void) const
inline unsigned int get_size (void) const
{ return count.static_size + offSize.static_size + offset_array_size () + (offset_at (count) - 1); }
+ protected:
+ inline unsigned int max_offset (void) const
+ {
+ unsigned int max = 0;
+ for (unsigned int i = 0; i <= count; i++)
+ {
+ unsigned int off = offset_at (i);
+ if (off > max) max = off;
+ }
+ return max;
+ }
+
+ public:
HBUINT32 count; /* Number of object data. Note there are (count+1) offsets */
HBUINT8 offSize; /* The byte size of each offset in the offsets array. */
HBUINT8 offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */
template <typename Type>
struct IndexOf : Index
{
- inline bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
- c->check_array (offsets, offSize, count + 1) &&
- c->check_array (data_base (), sizeof (Type), offset_at (count)));
- }
-
inline const Type& operator [] (unsigned int index) const
{
if (likely (index < count))
/* FDSelect */
struct FDSelect0 {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ }
+
HBUINT8 fds[VAR];
+
+ DEFINE_SIZE_MIN (1);
};
struct FDSelect3_Range {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (likely (c->check_struct (this) && (first < c->get_num_glyphs ())));
+ }
+
HBUINT16 first;
HBUINT8 fd;
+
+ DEFINE_SIZE_STATIC (3);
};
struct FDSelect3 {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (likely (c->check_struct (this) && (nRanges > 0) &&
+ (ranges[nRanges - 1].sanitize (c))));
+ }
+
HBUINT16 nRanges;
FDSelect3_Range ranges[VAR];
/* HBUINT16 sentinel */
+
+ DEFINE_SIZE_MIN (5);
};
struct FDSelect {
- // XXX: need to sanitize at run time
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (likely (c->check_struct (this) && (format == 0 || format == 3) &&
+ (format == 0)? u.format0.sanitize (c): u.format3.sanitize (c)));
+ }
+
HBUINT8 format;
union {
FDSelect0 format0;
FDSelect3 format3;
} u;
+
+ DEFINE_SIZE_MIN (2);
};
inline float parse_bcd (const ByteStr& str, unsigned int& offset, float& v)
} /* namespace CFF */
-#endif /* HB_OT_CFF_COMMON_HH */
+#endif /* HB_OT_CFF_COMMON_PRIVATE_HH */
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
- version.sanitize (c) &&
likely (version.major == 2));
}
{
inline void init (hb_face_t *face)
{
- this->blob = OT::Sanitizer<OT::cff2>().sanitize (face->reference_table (HB_OT_TAG_cff2));
+ hb_sanitize_context_t c;
+ this->blob = c.reference_table<cff2> (face);
const OT::cff2 *cff2 = this->blob->as<OT::cff2> ();
if (cff2 == &Null(OT::cff2))
{
- hb_blob_destroy (blob);
+ fini ();
return;
}
{ /* parse top dict */
ByteStr topDictStr (cff2 + cff2->topDict, cff2->topDictSize);
+ if (unlikely (!topDictStr.sanitize (&c)))
+ {
+ fini ();
+ return;
+ }
CFF2TopDict_Interpreter top_interp;
top_interp.init ();
top_interp.interpret (topDictStr, top);
fdArray = &OT::StructAtOffset<FDArray>(cff2, top.FDArrayOffset);
fdSelect = &OT::StructAtOffset<FDSelect>(cff2, top.FDSelectOffset);
- // XXX: sanitize above?
- if ((charStrings == &Null(CharStrings)) ||
- (fdArray == &Null(FDArray)))
+ if (((varStore != &Null(VariationStore)) && unlikely (!varStore->sanitize (&c))) ||
+ ((charStrings == &Null(CharStrings)) || unlikely (!charStrings->sanitize (&c))) ||
+ ((fdArray == &Null(FDArray)) || unlikely (!fdArray->sanitize (&c))) ||
+ ((fdSelect == &Null(FDSelect)) || unlikely (!fdSelect->sanitize (&c))))
{
- hb_blob_destroy (blob);
+ fini ();
return;
}
num_glyphs = charStrings->count;
+ if (num_glyphs != c.get_num_glyphs ())
+ {
+ fini ();
+ return;
+ }
}
inline void fini (void)
{
hb_blob_destroy (blob);
+ blob = nullptr;
}
inline bool get_extents (hb_codepoint_t glyph,