Merge branch 'master' into cff-subset

This commit is contained in:
Michiharu Ariza 2018-09-13 12:44:00 -07:00
commit f2c4720ae6
6 changed files with 224 additions and 182 deletions

View File

@ -529,18 +529,20 @@ struct hb_array_t
struct hb_bytes_t struct hb_bytes_t
{ {
inline hb_bytes_t (void) : bytes (nullptr), len (0) {} inline hb_bytes_t (void) : arrayZ (nullptr), len (0) {}
inline hb_bytes_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {} inline hb_bytes_t (const char *bytes_, unsigned int len_) : arrayZ (bytes_), len (len_) {}
inline hb_bytes_t (const void *bytes_, unsigned int len_) : bytes ((const char *) bytes_), len (len_) {} inline hb_bytes_t (const void *bytes_, unsigned int len_) : arrayZ ((const char *) bytes_), len (len_) {}
template <typename T>
inline hb_bytes_t (const T& array) : arrayZ ((const char *) array.arrayZ), len (array.len) {}
inline void free (void) { ::free ((void *) bytes); bytes = nullptr; len = 0; } inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; }
inline int cmp (const hb_bytes_t &a) const inline int cmp (const hb_bytes_t &a) const
{ {
if (len != a.len) if (len != a.len)
return (int) a.len - (int) len; return (int) a.len - (int) len;
return memcmp (a.bytes, bytes, len); return memcmp (a.arrayZ, arrayZ, len);
} }
static inline int cmp (const void *pa, const void *pb) static inline int cmp (const void *pa, const void *pb)
{ {
@ -549,7 +551,7 @@ struct hb_bytes_t
return b->cmp (*a); return b->cmp (*a);
} }
const char *bytes; const char *arrayZ;
unsigned int len; unsigned int len;
}; };

View File

@ -287,52 +287,69 @@ struct TTCHeader
/* /*
* Mac Resource Fork * Mac Resource Fork
*
* http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html
*/ */
struct ResourceRefItem struct ResourceRecord
{ {
inline bool sanitize (hb_sanitize_context_t *c) const inline const OpenTypeFontFace & get_face (const void *data_base) const
{ return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); }
inline bool sanitize (hb_sanitize_context_t *c,
const void *data_base) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
// actual data sanitization is done on ResourceForkHeader sanitizer return_trace (c->check_struct (this) &&
return_trace (likely (c->check_struct (this))); offset.sanitize (c, data_base) &&
get_face (data_base).sanitize (c));
} }
HBINT16 id; /* Resource ID, is really should be signed? */ protected:
HBUINT16 id; /* Resource ID. */
HBINT16 nameOffset; /* Offset from beginning of resource name list HBINT16 nameOffset; /* Offset from beginning of resource name list
* to resource name, minus means there is none. */ * to resource name, -1 means there is none. */
HBUINT8 attr; /* Resource attributes */ HBUINT8 attrs; /* Resource attributes */
HBUINT24 dataOffset; /* Offset from beginning of resource data to OffsetTo<LArrayOf<HBUINT8>, HBUINT24, false>
offset; /* Offset from beginning of data block to
* data for this resource */ * data for this resource */
HBUINT32 reserved; /* Reserved for handle to resource */ HBUINT32 reserved; /* Reserved for handle to resource */
public: public:
DEFINE_SIZE_STATIC (12); DEFINE_SIZE_STATIC (12);
}; };
struct ResourceTypeItem #define HB_TAG_sfnt HB_TAG ('s','f','n','t')
struct ResourceTypeRecord
{ {
inline bool sanitize (hb_sanitize_context_t *c) const inline unsigned int get_resource_count (void) const
{ return tag == HB_TAG_sfnt ? resCountM1 + 1 : 0; }
inline bool is_sfnt (void) const { return tag == HB_TAG_sfnt; }
inline const ResourceRecord& get_resource_record (unsigned int i,
const void *type_base) const
{ {
TRACE_SANITIZE (this); return hb_array_t<ResourceRecord> ((type_base+resourcesZ).arrayZ,
// RefList sanitization is done on ResourceMap sanitizer get_resource_count ()) [i];
return_trace (likely (c->check_struct (this)));
} }
inline unsigned int get_resource_count () const { return numRes + 1; } inline bool sanitize (hb_sanitize_context_t *c,
const void *type_base,
inline bool is_sfnt () const { return type == HB_TAG ('s','f','n','t'); } const void *data_base) const
inline const ResourceRefItem& get_ref_item (const void *base,
unsigned int i) const
{ {
return (base+refList)[i]; TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
resourcesZ.sanitize (c, type_base,
get_resource_count (),
data_base));
} }
protected: protected:
Tag type; /* Resource type. */ Tag tag; /* Resource type. */
HBUINT16 numRes; /* Number of resources minus 1. */ HBUINT16 resCountM1; /* Number of resources minus 1. */
OffsetTo<UnsizedArrayOf<ResourceRefItem> > OffsetTo<UnsizedArrayOf<ResourceRecord> >
refList; /* Offset from beginning of resource type list resourcesZ; /* Offset from beginning of resource type list
* to reference item list for this type. */ * to reference item list for this type. */
public: public:
DEFINE_SIZE_STATIC (8); DEFINE_SIZE_STATIC (8);
@ -340,132 +357,88 @@ struct ResourceTypeItem
struct ResourceMap struct ResourceMap
{ {
inline bool sanitize (hb_sanitize_context_t *c) const inline unsigned int get_face_count (void) const
{ {
TRACE_SANITIZE (this); unsigned int count = get_type_count ();
if (unlikely (!c->check_struct (this))) for (unsigned int i = 0; i < count; i++)
return_trace (false);
for (unsigned int i = 0; i < get_types_count (); ++i)
{ {
const ResourceTypeItem& type = get_type (i); const ResourceTypeRecord& type = get_type_record (i);
if (unlikely (!type.sanitize (c)))
return_trace (false);
for (unsigned int j = 0; j < type.get_resource_count (); ++j)
if (unlikely (!get_ref_item (type, j).sanitize (c)))
return_trace (false);
}
return_trace (true);
}
inline const ResourceTypeItem& get_type (unsigned int i) const
{
// Why offset from the second byte of the object? I'm not sure
return ((&reserved[2])+typeList)[i];
}
inline unsigned int get_types_count () const
{
return nTypes + 1;
}
inline const ResourceRefItem &get_ref_item (const ResourceTypeItem &type,
unsigned int i) const
{
return type.get_ref_item (&(this+typeList), i);
}
inline const PString& get_name (const ResourceRefItem &item,
unsigned int i) const
{
if (item.nameOffset == -1)
return Null (PString);
return StructAtOffset<PString> (this, nameList + item.nameOffset);
}
protected:
HBUINT8 reserved[16]; /* Reserved for copy of resource header */
LOffsetTo<ResourceMap>
reserved1; /* Reserved for handle to next resource map */
HBUINT16 reserved2; /* Reserved for file reference number */
HBUINT16 attr; /* Resource fork attribute */
OffsetTo<UnsizedArrayOf<ResourceTypeItem> >
typeList; /* Offset from beginning of map to
* resource type list */
HBUINT16 nameList; /* Offset from beginning of map to
* resource name list */
HBUINT16 nTypes; /* Number of types in the map minus 1 */
public:
DEFINE_SIZE_STATIC (30);
};
struct ResourceForkHeader
{
inline unsigned int get_face_count () const
{
const ResourceMap &resource_map = this+map;
for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
{
const ResourceTypeItem& type = resource_map.get_type (i);
if (type.is_sfnt ()) if (type.is_sfnt ())
return type.get_resource_count (); return type.get_resource_count ();
} }
return 0; return 0;
} }
inline const LArrayOf<HBUINT8>& get_data (const ResourceTypeItem& type, inline const OpenTypeFontFace& get_face (unsigned int idx,
unsigned int idx) const const void *data_base) const
{ {
const ResourceMap &resource_map = this+map; unsigned int count = get_type_count ();
unsigned int offset = dataOffset; for (unsigned int i = 0; i < count; i++)
offset += resource_map.get_ref_item (type, idx).dataOffset;
return StructAtOffset<LArrayOf<HBUINT8> > (this, offset);
}
inline const OpenTypeFontFace& get_face (unsigned int idx, unsigned int *base_offset = nullptr) const
{
const ResourceMap &resource_map = this+map;
for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
{ {
const ResourceTypeItem& type = resource_map.get_type (i); const ResourceTypeRecord& type = get_type_record (i);
/* The check for idx < count is here because ResourceRecord is NOT null-safe.
* Because an offset of 0 there does NOT mean null. */
if (type.is_sfnt () && idx < type.get_resource_count ()) if (type.is_sfnt () && idx < type.get_resource_count ())
{ return type.get_resource_record (idx, &(this+typeList)).get_face (data_base);
const OpenTypeFontFace &face = (OpenTypeFontFace&) get_data (type, idx).arrayZ;
if (base_offset)
*base_offset = (const char *) &face - (const char *) this;
return face;
}
} }
return Null (OpenTypeFontFace); return Null (OpenTypeFontFace);
} }
inline bool sanitize (hb_sanitize_context_t *c, const void *data_base) const
{
TRACE_SANITIZE (this);
const void *type_base = &(this+typeList);
return_trace (c->check_struct (this) &&
typeList.sanitize (c, this,
type_base,
data_base));
}
private:
inline unsigned int get_type_count (void) const { return (this+typeList).lenM1 + 1; }
inline const ResourceTypeRecord& get_type_record (unsigned int i) const
{ return (this+typeList)[i]; }
protected:
HBUINT8 reserved0[16]; /* Reserved for copy of resource header */
HBUINT32 reserved1; /* Reserved for handle to next resource map */
HBUINT16 resreved2; /* Reserved for file reference number */
HBUINT16 attrs; /* Resource fork attribute */
OffsetTo<ArrayOfM1<ResourceTypeRecord> >
typeList; /* Offset from beginning of map to
* resource type list */
Offset16 nameList; /* Offset from beginning of map to
* resource name list */
public:
DEFINE_SIZE_STATIC (28);
};
struct ResourceForkHeader
{
inline unsigned int get_face_count (void) const
{ return (this+map).get_face_count (); }
inline const OpenTypeFontFace& get_face (unsigned int idx,
unsigned int *base_offset = nullptr) const
{
const OpenTypeFontFace &face = (this+map).get_face (idx, &(this+data));
if (base_offset)
*base_offset = (const char *) &face - (const char *) this;
return face;
}
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return_trace (c->check_struct (this) &&
return_trace (false); data.sanitize (c, this, dataLen) &&
map.sanitize (c, this, &(this+data)));
const ResourceMap &resource_map = this+map;
if (unlikely (!resource_map.sanitize (c)))
return_trace (false);
for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
{
const ResourceTypeItem& type = resource_map.get_type (i);
for (unsigned int j = 0; j < type.get_resource_count (); ++j)
{
const LArrayOf<HBUINT8>& data = get_data (type, j);
if (unlikely (!(data.sanitize (c) &&
((OpenTypeFontFace&) data.arrayZ).sanitize (c))))
return_trace (false);
}
}
return_trace (true);
} }
protected: protected:
HBUINT32 dataOffset; /* Offset from beginning of resource fork LOffsetTo<UnsizedArrayOf<HBUINT8> >
data; /* Offset from beginning of resource fork
* to resource data */ * to resource data */
LOffsetTo<ResourceMap> LOffsetTo<ResourceMap>
map; /* Offset from beginning of resource fork map; /* Offset from beginning of resource fork

View File

@ -155,10 +155,10 @@ struct Index : HBUINT16 {
DECLARE_NULL_NAMESPACE_BYTES (OT, Index); DECLARE_NULL_NAMESPACE_BYTES (OT, Index);
/* Offset, Null offset = 0 */ /* Offset, Null offset = 0 */
template <typename Type> template <typename Type, bool has_null=true>
struct Offset : Type struct Offset : Type
{ {
inline bool is_null (void) const { return 0 == *this; } inline bool is_null (void) const { return has_null && 0 == *this; }
inline void *serialize (hb_serialize_context_t *c, const void *base) inline void *serialize (hb_serialize_context_t *c, const void *base)
{ {
@ -226,20 +226,18 @@ struct FixedVersion
* Use: (base+offset) * Use: (base+offset)
*/ */
template <typename Type, typename OffsetType=HBUINT16> template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
struct OffsetTo : Offset<OffsetType> struct OffsetTo : Offset<OffsetType, has_null>
{ {
inline const Type& operator () (const void *base) const inline const Type& operator () (const void *base) const
{ {
unsigned int offset = *this; if (unlikely (this->is_null ())) return Null(Type);
if (unlikely (!offset)) return Null(Type); return StructAtOffset<const Type> (base, *this);
return StructAtOffset<const Type> (base, offset);
} }
inline Type& operator () (void *base) const inline Type& operator () (void *base) const
{ {
unsigned int offset = *this; if (unlikely (this->is_null ())) return Crap(Type);
if (unlikely (!offset)) return Crap(Type); return StructAtOffset<Type> (base, *this);
return StructAtOffset<Type> (base, offset);
} }
inline Type& serialize (hb_serialize_context_t *c, const void *base) inline Type& serialize (hb_serialize_context_t *c, const void *base)
@ -260,39 +258,64 @@ struct OffsetTo : Offset<OffsetType>
this->set (0); this->set (0);
} }
inline bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return_trace (false);
if (unlikely (this->is_null ())) return_trace (true);
if (unlikely (!c->check_range (base, *this))) return_trace (false);
return_trace (true);
}
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return_trace (false); return_trace (sanitize_shallow (c, base) &&
unsigned int offset = *this; (this->is_null () ||
if (unlikely (!offset)) return_trace (true); StructAtOffset<Type> (base, *this).sanitize (c) ||
if (unlikely (!c->check_range (base, offset))) return_trace (false); neuter (c)));
const Type &obj = StructAtOffset<Type> (base, offset);
return_trace (likely (obj.sanitize (c)) || neuter (c));
} }
template <typename T> template <typename T1>
inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return_trace (false); return_trace (sanitize_shallow (c, base) &&
unsigned int offset = *this; (this->is_null () ||
if (unlikely (!offset)) return_trace (true); StructAtOffset<Type> (base, *this).sanitize (c, d1) ||
if (unlikely (!c->check_range (base, offset))) return_trace (false); neuter (c)));
const Type &obj = StructAtOffset<Type> (base, offset); }
return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); template <typename T1, typename T2>
inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2) const
{
TRACE_SANITIZE (this);
return_trace (sanitize_shallow (c, base) &&
(this->is_null () ||
StructAtOffset<Type> (base, *this).sanitize (c, d1, d2) ||
neuter (c)));
}
template <typename T1, typename T2, typename T3>
inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2, T3 d3) const
{
TRACE_SANITIZE (this);
return_trace (sanitize_shallow (c, base) &&
(this->is_null () ||
StructAtOffset<Type> (base, *this).sanitize (c, d1, d2, d3) ||
neuter (c)));
} }
/* Set the offset to Null */ /* Set the offset to Null */
inline bool neuter (hb_sanitize_context_t *c) const { inline bool neuter (hb_sanitize_context_t *c) const
{
if (!has_null) return false;
return c->try_set (this, 0); return c->try_set (this, 0);
} }
DEFINE_SIZE_STATIC (sizeof(OffsetType)); DEFINE_SIZE_STATIC (sizeof(OffsetType));
}; };
template <typename Type> struct LOffsetTo : OffsetTo<Type, HBUINT32> {}; template <typename Type> struct LOffsetTo : OffsetTo<Type, HBUINT32> {};
template <typename Base, typename OffsetType, typename Type> template <typename Base, typename OffsetType, bool has_null, typename Type>
static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); } static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); }
template <typename Base, typename OffsetType, typename Type> template <typename Base, typename OffsetType, bool has_null, typename Type>
static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); } static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); }
/* /*
@ -547,16 +570,16 @@ struct HeadlessArrayOf
{ {
inline const Type& operator [] (unsigned int i) const inline const Type& operator [] (unsigned int i) const
{ {
if (unlikely (i >= len || !i)) return Null(Type); if (unlikely (i >= lenP1 || !i)) return Null(Type);
return arrayZ[i-1]; return arrayZ[i-1];
} }
inline Type& operator [] (unsigned int i) inline Type& operator [] (unsigned int i)
{ {
if (unlikely (i >= len || !i)) return Crap(Type); if (unlikely (i >= lenP1 || !i)) return Crap(Type);
return arrayZ[i-1]; return arrayZ[i-1];
} }
inline unsigned int get_size (void) const inline unsigned int get_size (void) const
{ return len.static_size + (len ? len - 1 : 0) * Type::static_size; } { return lenP1.static_size + (lenP1 ? lenP1 - 1 : 0) * Type::static_size; }
inline bool serialize (hb_serialize_context_t *c, inline bool serialize (hb_serialize_context_t *c,
Supplier<Type> &items, Supplier<Type> &items,
@ -564,7 +587,7 @@ struct HeadlessArrayOf
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false); if (unlikely (!c->extend_min (*this))) return_trace (false);
len.set (items_len); /* TODO(serialize) Overflow? */ lenP1.set (items_len); /* TODO(serialize) Overflow? */
if (unlikely (!items_len)) return_trace (true); if (unlikely (!items_len)) return_trace (true);
if (unlikely (!c->extend (*this))) return_trace (false); if (unlikely (!c->extend (*this))) return_trace (false);
for (unsigned int i = 0; i < items_len - 1; i++) for (unsigned int i = 0; i < items_len - 1; i++)
@ -594,12 +617,56 @@ struct HeadlessArrayOf
inline bool sanitize_shallow (hb_sanitize_context_t *c) const inline bool sanitize_shallow (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (len.sanitize (c) && return_trace (lenP1.sanitize (c) &&
(!len || c->check_array (arrayZ, len - 1))); (!lenP1 || c->check_array (arrayZ, lenP1 - 1)));
} }
public: public:
LenType len; LenType lenP1;
Type arrayZ[VAR];
public:
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
};
/* An array storing length-1. */
template <typename Type, typename LenType=HBUINT16>
struct ArrayOfM1
{
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i > lenM1)) return Null(Type);
return arrayZ[i];
}
inline Type& operator [] (unsigned int i)
{
if (unlikely (i > lenM1)) return Crap(Type);
return arrayZ[i];
}
inline unsigned int get_size (void) const
{ return lenM1.static_size + (lenM1 + 1) * Type::static_size; }
template <typename T>
inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
unsigned int count = lenM1 + 1;
for (unsigned int i = 0; i < count; i++)
if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
return_trace (false);
return_trace (true);
}
private:
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (lenM1.sanitize (c) &&
(c->check_array (arrayZ, lenM1 + 1)));
}
public:
LenType lenM1;
Type arrayZ[VAR]; Type arrayZ[VAR];
public: public:
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);

View File

@ -710,7 +710,7 @@ struct Ligature
{ {
inline bool intersects (const hb_set_t *glyphs) const inline bool intersects (const hb_set_t *glyphs) const
{ {
unsigned int count = component.len; unsigned int count = component.lenP1;
for (unsigned int i = 1; i < count; i++) for (unsigned int i = 1; i < count; i++)
if (!glyphs->has (component[i])) if (!glyphs->has (component[i]))
return false; return false;
@ -720,7 +720,7 @@ struct Ligature
inline void closure (hb_closure_context_t *c) const inline void closure (hb_closure_context_t *c) const
{ {
TRACE_CLOSURE (this); TRACE_CLOSURE (this);
unsigned int count = component.len; unsigned int count = component.lenP1;
for (unsigned int i = 1; i < count; i++) for (unsigned int i = 1; i < count; i++)
if (!c->glyphs->has (component[i])) if (!c->glyphs->has (component[i]))
return; return;
@ -730,14 +730,14 @@ struct Ligature
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{ {
TRACE_COLLECT_GLYPHS (this); TRACE_COLLECT_GLYPHS (this);
c->input->add_array (component.arrayZ, component.len ? component.len - 1 : 0); c->input->add_array (component.arrayZ, component.lenP1 ? component.lenP1 - 1 : 0);
c->output->add (ligGlyph); c->output->add (ligGlyph);
} }
inline bool would_apply (hb_would_apply_context_t *c) const inline bool would_apply (hb_would_apply_context_t *c) const
{ {
TRACE_WOULD_APPLY (this); TRACE_WOULD_APPLY (this);
if (c->len != component.len) if (c->len != component.lenP1)
return_trace (false); return_trace (false);
for (unsigned int i = 1; i < c->len; i++) for (unsigned int i = 1; i < c->len; i++)
@ -750,7 +750,7 @@ struct Ligature
inline bool apply (hb_ot_apply_context_t *c) const inline bool apply (hb_ot_apply_context_t *c) const
{ {
TRACE_APPLY (this); TRACE_APPLY (this);
unsigned int count = component.len; unsigned int count = component.lenP1;
if (unlikely (!count)) return_trace (false); if (unlikely (!count)) return_trace (false);

View File

@ -1879,7 +1879,7 @@ struct ChainRule
const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
return chain_context_intersects (glyphs, return chain_context_intersects (glyphs,
backtrack.len, backtrack.arrayZ, backtrack.len, backtrack.arrayZ,
input.len, input.arrayZ, input.lenP1, input.arrayZ,
lookahead.len, lookahead.arrayZ, lookahead.len, lookahead.arrayZ,
lookup_context); lookup_context);
} }
@ -1892,7 +1892,7 @@ struct ChainRule
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
chain_context_closure_lookup (c, chain_context_closure_lookup (c,
backtrack.len, backtrack.arrayZ, backtrack.len, backtrack.arrayZ,
input.len, input.arrayZ, input.lenP1, input.arrayZ,
lookahead.len, lookahead.arrayZ, lookahead.len, lookahead.arrayZ,
lookup.len, lookup.arrayZ, lookup.len, lookup.arrayZ,
lookup_context); lookup_context);
@ -1906,7 +1906,7 @@ struct ChainRule
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
chain_context_collect_glyphs_lookup (c, chain_context_collect_glyphs_lookup (c,
backtrack.len, backtrack.arrayZ, backtrack.len, backtrack.arrayZ,
input.len, input.arrayZ, input.lenP1, input.arrayZ,
lookahead.len, lookahead.arrayZ, lookahead.len, lookahead.arrayZ,
lookup.len, lookup.arrayZ, lookup.len, lookup.arrayZ,
lookup_context); lookup_context);
@ -1920,7 +1920,7 @@ struct ChainRule
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
return_trace (chain_context_would_apply_lookup (c, return_trace (chain_context_would_apply_lookup (c,
backtrack.len, backtrack.arrayZ, backtrack.len, backtrack.arrayZ,
input.len, input.arrayZ, input.lenP1, input.arrayZ,
lookahead.len, lookahead.arrayZ, lookup.len, lookahead.len, lookahead.arrayZ, lookup.len,
lookup.arrayZ, lookup_context)); lookup.arrayZ, lookup_context));
} }
@ -1933,7 +1933,7 @@ struct ChainRule
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
return_trace (chain_context_apply_lookup (c, return_trace (chain_context_apply_lookup (c,
backtrack.len, backtrack.arrayZ, backtrack.len, backtrack.arrayZ,
input.len, input.arrayZ, input.lenP1, input.arrayZ,
lookahead.len, lookahead.arrayZ, lookup.len, lookahead.len, lookahead.arrayZ, lookup.len,
lookup.arrayZ, lookup_context)); lookup.arrayZ, lookup_context));
} }

View File

@ -143,7 +143,7 @@ struct post
return true; return true;
if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */ if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */
return false; return false;
strncpy (buf, s.bytes, s.len); strncpy (buf, s.arrayZ, s.len);
buf[s.len] = '\0'; buf[s.len] = '\0';
return true; return true;
} }