Added sanitize functions & calls

Added sanitize functions to FDSelect
Added satnitize calls for FDSelect, VariationStore, FDArray, TopDict
This commit is contained in:
Michiharu Ariza 2018-07-30 14:28:40 -07:00
parent 161b642ec5
commit 9c4cadaef0
3 changed files with 72 additions and 23 deletions

View File

@ -23,8 +23,8 @@
* *
* Adobe Author(s): Michiharu Ariza * Adobe Author(s): Michiharu Ariza
*/ */
#ifndef HB_OT_CFF_COMMON_HH #ifndef HB_OT_CFF_COMMON_PRIVATE_HH
#define HB_OT_CFF_COMMON_HH #define HB_OT_CFF_COMMON_PRIVATE_HH
#include "hb-open-type-private.hh" #include "hb-open-type-private.hh"
#include "hb-ot-layout-common-private.hh" #include "hb-ot-layout-common-private.hh"
@ -140,9 +140,9 @@ struct Index
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && offSize >= 1 && offSize <= 4 && return_trace (likely (c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
c->check_array (offsets, offSize, count + 1) && c->check_array (offsets, offSize, count + 1) &&
c->check_array (data_base (), 1, offset_at (count))); c->check_array (data_base (), 1, max_offset () - 1)));
} }
inline unsigned int offset_array_size (void) const inline unsigned int offset_array_size (void) const
@ -182,6 +182,19 @@ struct Index
inline unsigned int get_size (void) const inline unsigned int get_size (void) const
{ return count.static_size + offSize.static_size + offset_array_size () + (offset_at (count) - 1); } { 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 */ 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 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). */ HBUINT8 offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */
@ -193,14 +206,6 @@ struct Index
template <typename Type> template <typename Type>
struct IndexOf : Index 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 inline const Type& operator [] (unsigned int index) const
{ {
if (likely (index < count)) if (likely (index < count))
@ -235,27 +240,59 @@ typedef IndexOf<Dict> FDArray;
/* FDSelect */ /* FDSelect */
struct FDSelect0 { struct FDSelect0 {
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
}
HBUINT8 fds[VAR]; HBUINT8 fds[VAR];
DEFINE_SIZE_MIN (1);
}; };
struct FDSelect3_Range { 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; HBUINT16 first;
HBUINT8 fd; HBUINT8 fd;
DEFINE_SIZE_STATIC (3);
}; };
struct FDSelect3 { 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; HBUINT16 nRanges;
FDSelect3_Range ranges[VAR]; FDSelect3_Range ranges[VAR];
/* HBUINT16 sentinel */ /* HBUINT16 sentinel */
DEFINE_SIZE_MIN (5);
}; };
struct FDSelect { 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; HBUINT8 format;
union { union {
FDSelect0 format0; FDSelect0 format0;
FDSelect3 format3; FDSelect3 format3;
} u; } u;
DEFINE_SIZE_MIN (2);
}; };
inline float parse_bcd (const ByteStr& str, unsigned int& offset, float& v) inline float parse_bcd (const ByteStr& str, unsigned int& offset, float& v)
@ -471,5 +508,5 @@ struct Interpreter {
} /* namespace CFF */ } /* namespace CFF */
#endif /* HB_OT_CFF_COMMON_HH */ #endif /* HB_OT_CFF_COMMON_PRIVATE_HH */

View File

@ -289,7 +289,6 @@ struct cff2
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && return_trace (c->check_struct (this) &&
version.sanitize (c) &&
likely (version.major == 2)); likely (version.major == 2));
} }
@ -297,17 +296,23 @@ struct cff2
{ {
inline void init (hb_face_t *face) 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> (); const OT::cff2 *cff2 = this->blob->as<OT::cff2> ();
if (cff2 == &Null(OT::cff2)) if (cff2 == &Null(OT::cff2))
{ {
hb_blob_destroy (blob); fini ();
return; return;
} }
{ /* parse top dict */ { /* parse top dict */
ByteStr topDictStr (cff2 + cff2->topDict, cff2->topDictSize); ByteStr topDictStr (cff2 + cff2->topDict, cff2->topDictSize);
if (unlikely (!topDictStr.sanitize (&c)))
{
fini ();
return;
}
CFF2TopDict_Interpreter top_interp; CFF2TopDict_Interpreter top_interp;
top_interp.init (); top_interp.init ();
top_interp.interpret (topDictStr, top); top_interp.interpret (topDictStr, top);
@ -319,20 +324,27 @@ struct cff2
fdArray = &OT::StructAtOffset<FDArray>(cff2, top.FDArrayOffset); fdArray = &OT::StructAtOffset<FDArray>(cff2, top.FDArrayOffset);
fdSelect = &OT::StructAtOffset<FDSelect>(cff2, top.FDSelectOffset); fdSelect = &OT::StructAtOffset<FDSelect>(cff2, top.FDSelectOffset);
// XXX: sanitize above? if (((varStore != &Null(VariationStore)) && unlikely (!varStore->sanitize (&c))) ||
if ((charStrings == &Null(CharStrings)) || ((charStrings == &Null(CharStrings)) || unlikely (!charStrings->sanitize (&c))) ||
(fdArray == &Null(FDArray))) ((fdArray == &Null(FDArray)) || unlikely (!fdArray->sanitize (&c))) ||
((fdSelect == &Null(FDSelect)) || unlikely (!fdSelect->sanitize (&c))))
{ {
hb_blob_destroy (blob); fini ();
return; return;
} }
num_glyphs = charStrings->count; num_glyphs = charStrings->count;
if (num_glyphs != c.get_num_glyphs ())
{
fini ();
return;
}
} }
inline void fini (void) inline void fini (void)
{ {
hb_blob_destroy (blob); hb_blob_destroy (blob);
blob = nullptr;
} }
inline bool get_extents (hb_codepoint_t glyph, inline bool get_extents (hb_codepoint_t glyph,

View File

@ -104,7 +104,7 @@ bool
hb_subset_cff2 (hb_subset_plan_t *plan, hb_subset_cff2 (hb_subset_plan_t *plan,
hb_blob_t **cff2_prime /* OUT */) hb_blob_t **cff2_prime /* OUT */)
{ {
hb_blob_t *cff2_blob = OT::Sanitizer<OT::cff2>().sanitize (plan->source->reference_table (HB_OT_TAG_cff2)); hb_blob_t *cff2_blob = OT::hb_sanitize_context_t().reference_table<CFF::cff2> (plan->source);
const char *cff2_data = hb_blob_get_data(cff2_blob, nullptr); const char *cff2_data = hb_blob_get_data(cff2_blob, nullptr);
OT::cff2::accelerator_t cff2; OT::cff2::accelerator_t cff2;