fix FDSelect fuzzing bug (#1539)
Rewrote struct FDSelect3_4.ranges as ArrayOf Updated FDSelect3_4::sanitize () to call ranges.sanitize () nRanges now a function to return a reference to ranges.len
This commit is contained in:
parent
9f6172d669
commit
0d2727f4fe
|
@ -588,10 +588,10 @@ struct FDSelect0 {
|
||||||
|
|
||||||
template <typename GID_TYPE, typename FD_TYPE>
|
template <typename GID_TYPE, typename FD_TYPE>
|
||||||
struct FDSelect3_4_Range {
|
struct FDSelect3_4_Range {
|
||||||
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
|
bool sanitize (hb_sanitize_context_t *c, const void */*nullptr*/, unsigned int fdcount) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (likely (c->check_struct (this) && (first < c->get_num_glyphs ()) && (fd < fdcount)));
|
return_trace (first < c->get_num_glyphs () && (fd < fdcount));
|
||||||
}
|
}
|
||||||
|
|
||||||
GID_TYPE first;
|
GID_TYPE first;
|
||||||
|
@ -603,21 +603,21 @@ struct FDSelect3_4_Range {
|
||||||
template <typename GID_TYPE, typename FD_TYPE>
|
template <typename GID_TYPE, typename FD_TYPE>
|
||||||
struct FDSelect3_4 {
|
struct FDSelect3_4 {
|
||||||
unsigned int get_size () const
|
unsigned int get_size () const
|
||||||
{ return GID_TYPE::static_size * 2 + FDSelect3_4_Range<GID_TYPE, FD_TYPE>::static_size * nRanges; }
|
{ return GID_TYPE::static_size * 2 + ranges.get_size (); }
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
|
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!(c->check_struct (this) && (nRanges > 0) && (ranges[0].first == 0))))
|
if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) ||
|
||||||
|
(nRanges () == 0) || ranges[0].first != 0))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < nRanges; i++)
|
for (unsigned int i = 1; i < nRanges (); i++)
|
||||||
{
|
{
|
||||||
if (unlikely (!ranges[i].sanitize (c, fdcount)))
|
if (unlikely (ranges[i - 1].first >= ranges[i].first))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
if ((0 < i) && unlikely (ranges[i - 1].first >= ranges[i].first))
|
|
||||||
return_trace (false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ())))
|
if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ())))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
|
||||||
|
@ -627,18 +627,19 @@ struct FDSelect3_4 {
|
||||||
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 1; i < nRanges; i++)
|
for (i = 1; i < nRanges (); i++)
|
||||||
if (glyph < ranges[i].first)
|
if (glyph < ranges[i].first)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
return (hb_codepoint_t)ranges[i - 1].fd;
|
return (hb_codepoint_t)ranges[i - 1].fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
GID_TYPE &sentinel () { return StructAfter<GID_TYPE> (ranges[nRanges - 1]); }
|
GID_TYPE &nRanges () { return ranges.len; }
|
||||||
const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges - 1]); }
|
GID_TYPE nRanges () const { return ranges.len; }
|
||||||
|
GID_TYPE &sentinel () { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
|
||||||
|
const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
|
||||||
|
|
||||||
GID_TYPE nRanges;
|
ArrayOf<FDSelect3_4_Range<GID_TYPE, FD_TYPE>, GID_TYPE> ranges;
|
||||||
FDSelect3_4_Range<GID_TYPE, FD_TYPE> ranges[VAR];
|
|
||||||
/* GID_TYPE sentinel */
|
/* GID_TYPE sentinel */
|
||||||
|
|
||||||
DEFINE_SIZE_ARRAY (GID_TYPE::static_size, ranges);
|
DEFINE_SIZE_ARRAY (GID_TYPE::static_size, ranges);
|
||||||
|
|
|
@ -153,7 +153,7 @@ serialize_fdselect_3_4 (hb_serialize_context_t *c,
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
FDSELECT3_4 *p = c->allocate_size<FDSELECT3_4> (size);
|
FDSELECT3_4 *p = c->allocate_size<FDSELECT3_4> (size);
|
||||||
if (unlikely (p == nullptr)) return_trace (false);
|
if (unlikely (p == nullptr)) return_trace (false);
|
||||||
p->nRanges.set (fdselect_ranges.length);
|
p->nRanges ().set (fdselect_ranges.length);
|
||||||
for (unsigned int i = 0; i < fdselect_ranges.length; i++)
|
for (unsigned int i = 0; i < fdselect_ranges.length; i++)
|
||||||
{
|
{
|
||||||
p->ranges[i].first.set (fdselect_ranges[i].glyph);
|
p->ranges[i].first.set (fdselect_ranges[i].glyph);
|
||||||
|
|
Loading…
Reference in New Issue