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
*/
#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"
@ -140,9 +140,9 @@ struct 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 (), 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
@ -182,6 +182,19 @@ struct Index
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). */
@ -193,14 +206,6 @@ struct Index
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))
@ -235,27 +240,59 @@ typedef IndexOf<Dict> FDArray;
/* 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)
@ -471,5 +508,5 @@ struct Interpreter {
} /* 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);
return_trace (c->check_struct (this) &&
version.sanitize (c) &&
likely (version.major == 2));
}
@ -297,17 +296,23 @@ struct cff2
{
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);
@ -319,20 +324,27 @@ struct cff2
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,

View File

@ -104,7 +104,7 @@ bool
hb_subset_cff2 (hb_subset_plan_t *plan,
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);
OT::cff2::accelerator_t cff2;