[repacker] sanitize PairPos during subtable extension.

This commit is contained in:
Garret Rieger 2022-07-29 18:29:12 +00:00
parent 2a5902ee50
commit 46c1fa7d1b
2 changed files with 44 additions and 2 deletions

View File

@ -47,6 +47,12 @@ struct ExtensionFormat1 : public OT::ExtensionFormat1<T>
this->extensionOffset = 0; this->extensionOffset = 0;
} }
bool sanitize (graph_t::vertex_t& vertex) const
{
int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
return vertex_len >= OT::ExtensionFormat1<T>::static_size;
}
unsigned get_lookup_type () const unsigned get_lookup_type () const
{ {
return this->extensionLookupType; return this->extensionLookupType;
@ -118,7 +124,6 @@ struct Lookup : public OT::Lookup
if (!is_ext && type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair) if (!is_ext && type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair)
return true; return true;
// TODO check subtable type.
hb_vector_t<unsigned> all_new_subtables; hb_vector_t<unsigned> all_new_subtables;
for (unsigned i = 0; i < subTable.len; i++) for (unsigned i = 0; i < subTable.len; i++)
{ {
@ -128,6 +133,8 @@ struct Lookup : public OT::Lookup
ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>* extension = ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>* extension =
(ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*) (ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*)
c.graph.object (ext_subtable_index).head; c.graph.object (ext_subtable_index).head;
if (!extension->sanitize (c.graph.vertices_[ext_subtable_index]))
continue;
subtable_index = extension->get_subtable_index (c.graph, ext_subtable_index); subtable_index = extension->get_subtable_index (c.graph, ext_subtable_index);
type = extension->get_lookup_type (); type = extension->get_lookup_type ();
@ -136,7 +143,8 @@ struct Lookup : public OT::Lookup
} }
PairPos* pairPos = (PairPos*) c.graph.object (subtable_index).head; PairPos* pairPos = (PairPos*) c.graph.object (subtable_index).head;
// TODO sanitize if (!pairPos->sanitize (c.graph.vertices_[subtable_index])) continue;
hb_vector_t<unsigned> new_sub_tables = pairPos->split_subtables (c, subtable_index); hb_vector_t<unsigned> new_sub_tables = pairPos->split_subtables (c, subtable_index);
if (new_sub_tables.in_error ()) return false; if (new_sub_tables.in_error ()) return false;
+ new_sub_tables.iter() | hb_sink (all_new_subtables); + new_sub_tables.iter() | hb_sink (all_new_subtables);

View File

@ -34,6 +34,16 @@ namespace graph {
struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes> struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>
{ {
bool sanitize (graph_t::vertex_t& vertex) const
{
int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
unsigned min_size = OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size;
if (vertex_len < min_size) return false;
return vertex_len >=
min_size + pairSet.get_size () - pairSet.len.get_size();
}
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index) hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index)
{ {
hb_set_t visited; hb_set_t visited;
@ -218,6 +228,12 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallType
struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes> struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes>
{ {
bool sanitize (graph_t::vertex_t& vertex) const
{
// TODO
return true;
}
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index) hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index)
{ {
// TODO // TODO
@ -243,6 +259,24 @@ struct PairPos : public OT::Layout::GPOS_impl::PairPos
return hb_vector_t<unsigned> (); return hb_vector_t<unsigned> ();
} }
} }
bool sanitize (graph_t::vertex_t& vertex) const
{
int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
if (vertex_len < u.format.get_size ()) return false;
switch (u.format) {
case 1:
return ((PairPosFormat1*)(&u.format1))->sanitize (vertex);
case 2:
return ((PairPosFormat2*)(&u.format2))->sanitize (vertex);
case 3:
case 4:
default:
// We don't handle format 3 and 4 here.
return false;
}
}
}; };
} }