[HB] GPOS sanitize()
This commit is contained in:
parent
dc9c4d93cd
commit
42b778f89e
|
@ -68,11 +68,14 @@ struct _hb_sanitize_context_t
|
||||||
context
|
context
|
||||||
|
|
||||||
#define SANITIZE(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG))
|
#define SANITIZE(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG))
|
||||||
#define SANITIZE2(X,Y) SANITIZE (X) && SANITIZE (Y)
|
#define SANITIZE2(X,Y) (SANITIZE (X) && SANITIZE (Y))
|
||||||
|
|
||||||
#define SANITIZE_THIS(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG, CONST_CHARP(this)))
|
#define SANITIZE_THIS(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG, CONST_CHARP(this)))
|
||||||
#define SANITIZE_THIS2(X,Y) SANITIZE_THIS (X) && SANITIZE_THIS (Y)
|
#define SANITIZE_THIS2(X,Y) (SANITIZE_THIS (X) && SANITIZE_THIS (Y))
|
||||||
#define SANITIZE_THIS3(X,Y,Z) SANITIZE_THIS (X) && SANITIZE_THIS (Y) && SANITIZE_THIS(Z)
|
#define SANITIZE_THIS3(X,Y,Z) (SANITIZE_THIS (X) && SANITIZE_THIS (Y) && SANITIZE_THIS(Z))
|
||||||
|
|
||||||
|
#define SANITIZE_BASE(X,B) HB_LIKELY ((X).sanitize (SANITIZE_ARG, B))
|
||||||
|
#define SANITIZE_BASE2(X,Y,B) (SANITIZE_BASE (X,B) && SANITIZE_BASE (Y,B))
|
||||||
|
|
||||||
#define SANITIZE_SELF() SANITIZE_OBJ (*this)
|
#define SANITIZE_SELF() SANITIZE_OBJ (*this)
|
||||||
#define SANITIZE_OBJ(X) SANITIZE_MEM(&(X), sizeof (X))
|
#define SANITIZE_OBJ(X) SANITIZE_MEM(&(X), sizeof (X))
|
||||||
|
@ -351,6 +354,12 @@ struct GenericOffsetTo : OffsetType
|
||||||
if (HB_UNLIKELY (!offset)) return true;
|
if (HB_UNLIKELY (!offset)) return true;
|
||||||
return SANITIZE (CAST(Type, *DECONST_CHARP(base), offset)) || NEUTER (*this, 0);
|
return SANITIZE (CAST(Type, *DECONST_CHARP(base), offset)) || NEUTER (*this, 0);
|
||||||
}
|
}
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF, const void *base, unsigned int user_data) {
|
||||||
|
if (!SANITIZE_OBJ (*this)) return false;
|
||||||
|
unsigned int offset = *this;
|
||||||
|
if (HB_UNLIKELY (!offset)) return true;
|
||||||
|
return SANITIZE_BASE (CAST(Type, *DECONST_CHARP(base), offset), user_data) || NEUTER (*this, 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
template <typename Base, typename OffsetType, typename Type>
|
template <typename Base, typename OffsetType, typename Type>
|
||||||
inline const Type& operator + (const Base &base, GenericOffsetTo<OffsetType, Type> offset) { return offset (base); }
|
inline const Type& operator + (const Base &base, GenericOffsetTo<OffsetType, Type> offset) { return offset (base); }
|
||||||
|
@ -391,6 +400,13 @@ struct GenericArrayOf
|
||||||
if (!array[i].sanitize (SANITIZE_ARG, base))
|
if (!array[i].sanitize (SANITIZE_ARG, base))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF, const void *base, unsigned int user_data) {
|
||||||
|
if (!SANITIZE_GET_SIZE()) return false;
|
||||||
|
unsigned int count = len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!array[i].sanitize (SANITIZE_ARG, base, user_data))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LenType len;
|
LenType len;
|
||||||
Type array[];
|
Type array[];
|
||||||
|
|
|
@ -54,6 +54,8 @@ struct ValueFormat : USHORT
|
||||||
|
|
||||||
inline unsigned int get_len () const
|
inline unsigned int get_len () const
|
||||||
{ return _hb_popcount32 ((unsigned int) *this); }
|
{ return _hb_popcount32 ((unsigned int) *this); }
|
||||||
|
inline unsigned int get_size () const
|
||||||
|
{ return get_len () * sizeof (Value); }
|
||||||
|
|
||||||
const void apply_value (hb_ot_layout_context_t *context,
|
const void apply_value (hb_ot_layout_context_t *context,
|
||||||
const char *base,
|
const char *base,
|
||||||
|
@ -153,6 +155,10 @@ struct AnchorFormat1
|
||||||
*y = context->font->y_scale * yCoordinate / 0x10000;
|
*y = context->font->y_scale * yCoordinate / 0x10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_SELF ();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 1 */
|
USHORT format; /* Format identifier--format = 1 */
|
||||||
SHORT xCoordinate; /* Horizontal value--in design units */
|
SHORT xCoordinate; /* Horizontal value--in design units */
|
||||||
|
@ -173,6 +179,10 @@ struct AnchorFormat2
|
||||||
*y = context->font->y_scale * yCoordinate / 0x10000;
|
*y = context->font->y_scale * yCoordinate / 0x10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_SELF ();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 2 */
|
USHORT format; /* Format identifier--format = 2 */
|
||||||
SHORT xCoordinate; /* Horizontal value--in design units */
|
SHORT xCoordinate; /* Horizontal value--in design units */
|
||||||
|
@ -198,6 +208,10 @@ struct AnchorFormat3
|
||||||
*y += (this+yDeviceTable).get_delta (context->font->y_ppem) << 6;
|
*y += (this+yDeviceTable).get_delta (context->font->y_ppem) << 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_SELF () && SANITIZE_THIS2 (xDeviceTable, yDeviceTable);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 3 */
|
USHORT format; /* Format identifier--format = 3 */
|
||||||
SHORT xCoordinate; /* Horizontal value--in design units */
|
SHORT xCoordinate; /* Horizontal value--in design units */
|
||||||
|
@ -227,6 +241,16 @@ struct Anchor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
if (!SANITIZE (u.format)) return false;
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return u.format1->sanitize (SANITIZE_ARG);
|
||||||
|
case 2: return u.format2->sanitize (SANITIZE_ARG);
|
||||||
|
case 3: return u.format3->sanitize (SANITIZE_ARG);
|
||||||
|
default:return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
|
@ -242,6 +266,10 @@ struct MarkRecord
|
||||||
{
|
{
|
||||||
friend struct MarkArray;
|
friend struct MarkArray;
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF, const void *base) {
|
||||||
|
return SANITIZE_SELF () && SANITIZE_BASE (markAnchor, base);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT klass; /* Class defined for this mark */
|
USHORT klass; /* Class defined for this mark */
|
||||||
OffsetTo<Anchor>
|
OffsetTo<Anchor>
|
||||||
|
@ -255,6 +283,10 @@ struct MarkArray
|
||||||
inline unsigned int get_class (unsigned int index) const { return markRecord[index].klass; }
|
inline unsigned int get_class (unsigned int index) const { return markRecord[index].klass; }
|
||||||
inline const Anchor& get_anchor (unsigned int index) const { return this+markRecord[index].markAnchor; }
|
inline const Anchor& get_anchor (unsigned int index) const { return this+markRecord[index].markAnchor; }
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_THIS (markRecord);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ArrayOf<MarkRecord>
|
ArrayOf<MarkRecord>
|
||||||
markRecord; /* Array of MarkRecords--in Coverage order */
|
markRecord; /* Array of MarkRecords--in Coverage order */
|
||||||
|
@ -281,6 +313,11 @@ struct SinglePosFormat1
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_SELF () && SANITIZE_THIS (coverage) &&
|
||||||
|
SANITIZE_MEM (values, valueFormat.get_size ());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 1 */
|
USHORT format; /* Format identifier--format = 1 */
|
||||||
OffsetTo<Coverage>
|
OffsetTo<Coverage>
|
||||||
|
@ -316,6 +353,11 @@ struct SinglePosFormat2
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_SELF () && SANITIZE_THIS (coverage) &&
|
||||||
|
SANITIZE_MEM (values, valueFormat.get_size () * valueCount);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 2 */
|
USHORT format; /* Format identifier--format = 2 */
|
||||||
OffsetTo<Coverage>
|
OffsetTo<Coverage>
|
||||||
|
@ -343,6 +385,15 @@ struct SinglePos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
if (!SANITIZE (u.format)) return false;
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return u.format1->sanitize (SANITIZE_ARG);
|
||||||
|
case 2: return u.format2->sanitize (SANITIZE_ARG);
|
||||||
|
default:return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
|
@ -370,6 +421,12 @@ struct PairSet
|
||||||
{
|
{
|
||||||
friend struct PairPosFormat1;
|
friend struct PairPosFormat1;
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF, unsigned int format_len) {
|
||||||
|
if (!SANITIZE_SELF ()) return false;
|
||||||
|
unsigned int count = (1 + format_len) * len;
|
||||||
|
return SANITIZE_MEM (array, sizeof (array[0]) * count);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT len; /* Number of PairValueRecords */
|
USHORT len; /* Number of PairValueRecords */
|
||||||
PairValueRecord
|
PairValueRecord
|
||||||
|
@ -426,6 +483,12 @@ struct PairPosFormat1
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_SELF () && SANITIZE_THIS (coverage) &&
|
||||||
|
pairSet.sanitize (SANITIZE_ARG, CONST_CHARP(this),
|
||||||
|
valueFormat1.get_len () + valueFormat2.get_len ());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 1 */
|
USHORT format; /* Format identifier--format = 1 */
|
||||||
OffsetTo<Coverage>
|
OffsetTo<Coverage>
|
||||||
|
@ -486,6 +549,13 @@ struct PairPosFormat2
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_SELF () && SANITIZE_THIS (coverage) &&
|
||||||
|
SANITIZE_THIS2 (classDef1, classDef2) &&
|
||||||
|
SANITIZE_MEM (values,
|
||||||
|
(valueFormat1.get_size () + valueFormat2.get_size ()) *
|
||||||
|
class1Count * class2Count);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 2 */
|
USHORT format; /* Format identifier--format = 2 */
|
||||||
|
@ -530,6 +600,15 @@ struct PairPos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
if (!SANITIZE (u.format)) return false;
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return u.format1->sanitize (SANITIZE_ARG);
|
||||||
|
case 2: return u.format2->sanitize (SANITIZE_ARG);
|
||||||
|
default:return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
|
@ -542,6 +621,10 @@ ASSERT_SIZE (PairPos, 2);
|
||||||
|
|
||||||
struct EntryExitRecord
|
struct EntryExitRecord
|
||||||
{
|
{
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF, const void *base) {
|
||||||
|
return SANITIZE_BASE2 (entryAnchor, exitAnchor, base);
|
||||||
|
}
|
||||||
|
|
||||||
OffsetTo<Anchor>
|
OffsetTo<Anchor>
|
||||||
entryAnchor; /* Offset to EntryAnchor table--from
|
entryAnchor; /* Offset to EntryAnchor table--from
|
||||||
* beginning of CursivePos
|
* beginning of CursivePos
|
||||||
|
@ -732,6 +815,10 @@ struct CursivePosFormat1
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_THIS2 (coverage, entryExitRecord);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 1 */
|
USHORT format; /* Format identifier--format = 1 */
|
||||||
OffsetTo<Coverage>
|
OffsetTo<Coverage>
|
||||||
|
@ -756,6 +843,14 @@ struct CursivePos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
if (!SANITIZE (u.format)) return false;
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return u.format1->sanitize (SANITIZE_ARG);
|
||||||
|
default:return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
|
@ -769,6 +864,15 @@ struct BaseArray
|
||||||
{
|
{
|
||||||
friend struct MarkBasePosFormat1;
|
friend struct MarkBasePosFormat1;
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF, unsigned int cols) {
|
||||||
|
if (!SANITIZE_SELF ()) return false;
|
||||||
|
unsigned int count = cols * len;
|
||||||
|
if (!SANITIZE_MEM (matrix, sizeof (matrix[0]) * count)) return false;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!SANITIZE_THIS (matrix[i])) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT len; /* Number of rows */
|
USHORT len; /* Number of rows */
|
||||||
OffsetTo<Anchor>
|
OffsetTo<Anchor>
|
||||||
|
@ -836,6 +940,11 @@ struct MarkBasePosFormat1
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_SELF () && SANITIZE_THIS2 (markCoverage, baseCoverage) &&
|
||||||
|
SANITIZE_THIS (markArray) && baseArray.sanitize (SANITIZE_ARG, CONST_CHARP(this), classCount);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 1 */
|
USHORT format; /* Format identifier--format = 1 */
|
||||||
OffsetTo<Coverage>
|
OffsetTo<Coverage>
|
||||||
|
@ -867,6 +976,14 @@ struct MarkBasePos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
if (!SANITIZE (u.format)) return false;
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return u.format1->sanitize (SANITIZE_ARG);
|
||||||
|
default:return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
|
@ -973,6 +1090,12 @@ struct MarkLigPosFormat1
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_SELF () &&
|
||||||
|
SANITIZE_THIS2 (markCoverage, ligatureCoverage) &&
|
||||||
|
SANITIZE_THIS2 (markArray, ligatureArray);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 1 */
|
USHORT format; /* Format identifier--format = 1 */
|
||||||
OffsetTo<Coverage>
|
OffsetTo<Coverage>
|
||||||
|
@ -1005,6 +1128,14 @@ struct MarkLigPos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
if (!SANITIZE (u.format)) return false;
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return u.format1->sanitize (SANITIZE_ARG);
|
||||||
|
default:return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
|
@ -1018,6 +1149,15 @@ struct Mark2Array
|
||||||
{
|
{
|
||||||
friend struct MarkMarkPosFormat1;
|
friend struct MarkMarkPosFormat1;
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF, unsigned int cols) {
|
||||||
|
if (!SANITIZE_SELF ()) return false;
|
||||||
|
unsigned int count = cols * len;
|
||||||
|
if (!SANITIZE_MEM (matrix, sizeof (matrix[0]) * count)) return false;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!SANITIZE_THIS (matrix[i])) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT len; /* Number of rows */
|
USHORT len; /* Number of rows */
|
||||||
OffsetTo<Anchor>
|
OffsetTo<Anchor>
|
||||||
|
@ -1088,6 +1228,11 @@ struct MarkMarkPosFormat1
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
return SANITIZE_SELF () && SANITIZE_THIS2 (mark1Coverage, mark2Coverage) &&
|
||||||
|
SANITIZE_THIS (mark1Array) && mark2Array.sanitize (SANITIZE_ARG, CONST_CHARP(this), classCount);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT format; /* Format identifier--format = 1 */
|
USHORT format; /* Format identifier--format = 1 */
|
||||||
OffsetTo<Coverage>
|
OffsetTo<Coverage>
|
||||||
|
@ -1121,6 +1266,14 @@ struct MarkMarkPos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
if (!SANITIZE (u.format)) return false;
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return u.format1->sanitize (SANITIZE_ARG);
|
||||||
|
default:return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
|
@ -1158,7 +1311,12 @@ struct ExtensionPos : Extension
|
||||||
friend struct PosLookupSubTable;
|
friend struct PosLookupSubTable;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
inline const struct PosLookupSubTable& get_subtable (void) const
|
||||||
|
{ return CONST_CAST (PosLookupSubTable, Extension::get_subtable (), 0); }
|
||||||
|
|
||||||
inline bool apply (APPLY_ARG_DEF) const;
|
inline bool apply (APPLY_ARG_DEF) const;
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF);
|
||||||
};
|
};
|
||||||
ASSERT_SIZE (ExtensionPos, 2);
|
ASSERT_SIZE (ExtensionPos, 2);
|
||||||
|
|
||||||
|
@ -1201,6 +1359,22 @@ struct PosLookupSubTable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
if (!SANITIZE (u.format)) return false;
|
||||||
|
switch (u.format) {
|
||||||
|
case Single: return u.single->sanitize (SANITIZE_ARG);
|
||||||
|
case Pair: return u.pair->sanitize (SANITIZE_ARG);
|
||||||
|
case Cursive: return u.cursive->sanitize (SANITIZE_ARG);
|
||||||
|
case MarkBase: return u.markBase->sanitize (SANITIZE_ARG);
|
||||||
|
case MarkLig: return u.markLig->sanitize (SANITIZE_ARG);
|
||||||
|
case MarkMark: return u.markMark->sanitize (SANITIZE_ARG);
|
||||||
|
case Context: return u.context->sanitize (SANITIZE_ARG);
|
||||||
|
case ChainContext: return u.chainContext->sanitize (SANITIZE_ARG);
|
||||||
|
case Extension: return u.extension->sanitize (SANITIZE_ARG);
|
||||||
|
default:return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
USHORT format;
|
USHORT format;
|
||||||
|
@ -1296,9 +1470,17 @@ struct PosLookup : Lookup
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
if (Lookup::sanitize (SANITIZE_ARG)) return false;
|
||||||
|
OffsetArrayOf<PosLookupSubTable> &list = (OffsetArrayOf<PosLookupSubTable> &) subTable;
|
||||||
|
return SANITIZE_THIS (list);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
ASSERT_SIZE (PosLookup, 6);
|
ASSERT_SIZE (PosLookup, 6);
|
||||||
|
|
||||||
|
typedef OffsetListOf<PosLookup> PosLookupList;
|
||||||
|
ASSERT_SIZE (PosLookupList, 2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPOS
|
* GPOS
|
||||||
|
@ -1320,6 +1502,11 @@ struct GPOS : GSUBGPOS
|
||||||
hb_ot_layout_feature_mask_t mask) const
|
hb_ot_layout_feature_mask_t mask) const
|
||||||
{ return get_lookup (lookup_index).apply_string (context, buffer, mask); }
|
{ return get_lookup (lookup_index).apply_string (context, buffer, mask); }
|
||||||
|
|
||||||
|
inline bool sanitize (SANITIZE_ARG_DEF) {
|
||||||
|
if (GSUBGPOS::sanitize (SANITIZE_ARG)) return false;
|
||||||
|
OffsetTo<PosLookupList> &list = CAST(OffsetTo<PosLookupList>, lookupList, 0);
|
||||||
|
return SANITIZE_THIS (list);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
ASSERT_SIZE (GPOS, 10);
|
ASSERT_SIZE (GPOS, 10);
|
||||||
|
|
||||||
|
@ -1333,7 +1520,13 @@ inline bool ExtensionPos::apply (APPLY_ARG_DEF) const
|
||||||
if (HB_UNLIKELY (lookup_type == PosLookupSubTable::Extension))
|
if (HB_UNLIKELY (lookup_type == PosLookupSubTable::Extension))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return ((PosLookupSubTable&) get_subtable ()).apply (APPLY_ARG, lookup_type);
|
return get_subtable ().apply (APPLY_ARG, lookup_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ExtensionPos::sanitize (SANITIZE_ARG_DEF)
|
||||||
|
{
|
||||||
|
return Extension::sanitize (SANITIZE_ARG) &&
|
||||||
|
DECONST_CAST (PosLookupSubTable, get_subtable (), 0).sanitize (SANITIZE_ARG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
|
static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
|
||||||
|
|
|
@ -830,8 +830,6 @@ struct GSUB : GSUBGPOS
|
||||||
|
|
||||||
inline const SubstLookup& get_lookup (unsigned int i) const
|
inline const SubstLookup& get_lookup (unsigned int i) const
|
||||||
{ return (const SubstLookup&) GSUBGPOS::get_lookup (i); }
|
{ return (const SubstLookup&) GSUBGPOS::get_lookup (i); }
|
||||||
inline SubstLookup& get_lookup (unsigned int i)
|
|
||||||
{ return (SubstLookup&) GSUBGPOS::get_lookup (i); }
|
|
||||||
|
|
||||||
inline bool substitute_lookup (hb_ot_layout_context_t *context,
|
inline bool substitute_lookup (hb_ot_layout_context_t *context,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
|
|
Loading…
Reference in New Issue