| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. |
| 3 * Copyright © 2012 Google, Inc. | 3 * Copyright © 2012 Google, Inc. |
| 4 * | 4 * |
| 5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
| 6 * | 6 * |
| 7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
| 8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
| 9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
| 10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 /* This limits sanitizing time on really broken fonts. */ | 172 /* This limits sanitizing time on really broken fonts. */ |
| 173 #ifndef HB_SANITIZE_MAX_EDITS | 173 #ifndef HB_SANITIZE_MAX_EDITS |
| 174 #define HB_SANITIZE_MAX_EDITS 100 | 174 #define HB_SANITIZE_MAX_EDITS 100 |
| 175 #endif | 175 #endif |
| 176 | 176 |
| 177 struct hb_sanitize_context_t | 177 struct hb_sanitize_context_t |
| 178 { | 178 { |
| 179 inline const char *get_name (void) { return "SANITIZE"; } | 179 inline const char *get_name (void) { return "SANITIZE"; } |
| 180 static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; | 180 static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; |
| 181 typedef bool return_t; | 181 typedef bool return_t; |
| 182 template <typename T, typename F> |
| 183 inline bool may_dispatch (const T *obj, const F *format) |
| 184 { return format->sanitize (this); } |
| 182 template <typename T> | 185 template <typename T> |
| 183 inline return_t dispatch (const T &obj) { return obj.sanitize (this); } | 186 inline return_t dispatch (const T &obj) { return obj.sanitize (this); } |
| 184 static return_t default_return_value (void) { return true; } | 187 static return_t default_return_value (void) { return true; } |
| 185 bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return fals
e; } | 188 bool stop_sublookup_iteration (const return_t r) const { return !r; } |
| 186 | 189 |
| 187 inline void init (hb_blob_t *b) | 190 inline void init (hb_blob_t *b) |
| 188 { | 191 { |
| 189 this->blob = hb_blob_reference (b); | 192 this->blob = hb_blob_reference (b); |
| 190 this->writable = false; | 193 this->writable = false; |
| 191 } | 194 } |
| 192 | 195 |
| 193 inline void start_processing (void) | 196 inline void start_processing (void) |
| 194 { | 197 { |
| 195 this->start = hb_blob_get_data (this->blob, NULL); | 198 this->start = hb_blob_get_data (this->blob, NULL); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s", | 266 "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s", |
| 264 this->edit_count, | 267 this->edit_count, |
| 265 p, p + len, len, | 268 p, p + len, len, |
| 266 this->start, this->end, | 269 this->start, this->end, |
| 267 this->writable ? "GRANTED" : "DENIED"); | 270 this->writable ? "GRANTED" : "DENIED"); |
| 268 | 271 |
| 269 return this->writable; | 272 return this->writable; |
| 270 } | 273 } |
| 271 | 274 |
| 272 template <typename Type, typename ValueType> | 275 template <typename Type, typename ValueType> |
| 273 inline bool try_set (Type *obj, const ValueType &v) { | 276 inline bool try_set (const Type *obj, const ValueType &v) { |
| 274 if (this->may_edit (obj, obj->static_size)) { | 277 if (this->may_edit (obj, obj->static_size)) { |
| 275 obj->set (v); | 278 const_cast<Type *> (obj)->set (v); |
| 276 return true; | 279 return true; |
| 277 } | 280 } |
| 278 return false; | 281 return false; |
| 279 } | 282 } |
| 280 | 283 |
| 281 mutable unsigned int debug_depth; | 284 mutable unsigned int debug_depth; |
| 282 const char *start, *end; | 285 const char *start, *end; |
| 283 bool writable; | 286 bool writable; |
| 284 unsigned int edit_count; | 287 unsigned int edit_count; |
| 285 hb_blob_t *blob; | 288 hb_blob_t *blob; |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 inline void set (Type V) | 542 inline void set (Type V) |
| 540 { | 543 { |
| 541 v[0] = (V >> 8) & 0xFF; | 544 v[0] = (V >> 8) & 0xFF; |
| 542 v[1] = (V ) & 0xFF; | 545 v[1] = (V ) & 0xFF; |
| 543 } | 546 } |
| 544 inline operator Type (void) const | 547 inline operator Type (void) const |
| 545 { | 548 { |
| 546 return (v[0] << 8) | 549 return (v[0] << 8) |
| 547 + (v[1] ); | 550 + (v[1] ); |
| 548 } | 551 } |
| 549 inline bool operator == (const BEInt<Type, 2>& o) const | |
| 550 { | |
| 551 return v[0] == o.v[0] | |
| 552 && v[1] == o.v[1]; | |
| 553 } | |
| 554 inline bool operator != (const BEInt<Type, 2>& o) const { return !(*this == o)
; } | |
| 555 private: uint8_t v[2]; | 552 private: uint8_t v[2]; |
| 556 }; | 553 }; |
| 557 template <typename Type> | 554 template <typename Type> |
| 558 struct BEInt<Type, 3> | 555 struct BEInt<Type, 3> |
| 559 { | 556 { |
| 560 public: | 557 public: |
| 561 inline void set (Type V) | 558 inline void set (Type V) |
| 562 { | 559 { |
| 563 v[0] = (V >> 16) & 0xFF; | 560 v[0] = (V >> 16) & 0xFF; |
| 564 v[1] = (V >> 8) & 0xFF; | 561 v[1] = (V >> 8) & 0xFF; |
| 565 v[2] = (V ) & 0xFF; | 562 v[2] = (V ) & 0xFF; |
| 566 } | 563 } |
| 567 inline operator Type (void) const | 564 inline operator Type (void) const |
| 568 { | 565 { |
| 569 return (v[0] << 16) | 566 return (v[0] << 16) |
| 570 + (v[1] << 8) | 567 + (v[1] << 8) |
| 571 + (v[2] ); | 568 + (v[2] ); |
| 572 } | 569 } |
| 573 inline bool operator == (const BEInt<Type, 3>& o) const | |
| 574 { | |
| 575 return v[0] == o.v[0] | |
| 576 && v[1] == o.v[1] | |
| 577 && v[2] == o.v[2]; | |
| 578 } | |
| 579 inline bool operator != (const BEInt<Type, 3>& o) const { return !(*this == o)
; } | |
| 580 private: uint8_t v[3]; | 570 private: uint8_t v[3]; |
| 581 }; | 571 }; |
| 582 template <typename Type> | 572 template <typename Type> |
| 583 struct BEInt<Type, 4> | 573 struct BEInt<Type, 4> |
| 584 { | 574 { |
| 585 public: | 575 public: |
| 586 inline void set (Type V) | 576 inline void set (Type V) |
| 587 { | 577 { |
| 588 v[0] = (V >> 24) & 0xFF; | 578 v[0] = (V >> 24) & 0xFF; |
| 589 v[1] = (V >> 16) & 0xFF; | 579 v[1] = (V >> 16) & 0xFF; |
| 590 v[2] = (V >> 8) & 0xFF; | 580 v[2] = (V >> 8) & 0xFF; |
| 591 v[3] = (V ) & 0xFF; | 581 v[3] = (V ) & 0xFF; |
| 592 } | 582 } |
| 593 inline operator Type (void) const | 583 inline operator Type (void) const |
| 594 { | 584 { |
| 595 return (v[0] << 24) | 585 return (v[0] << 24) |
| 596 + (v[1] << 16) | 586 + (v[1] << 16) |
| 597 + (v[2] << 8) | 587 + (v[2] << 8) |
| 598 + (v[3] ); | 588 + (v[3] ); |
| 599 } | 589 } |
| 600 inline bool operator == (const BEInt<Type, 4>& o) const | |
| 601 { | |
| 602 return v[0] == o.v[0] | |
| 603 && v[1] == o.v[1] | |
| 604 && v[2] == o.v[2] | |
| 605 && v[3] == o.v[3]; | |
| 606 } | |
| 607 inline bool operator != (const BEInt<Type, 4>& o) const { return !(*this == o)
; } | |
| 608 private: uint8_t v[4]; | 590 private: uint8_t v[4]; |
| 609 }; | 591 }; |
| 610 | 592 |
| 611 /* Integer types in big-endian order and no alignment requirement */ | 593 /* Integer types in big-endian order and no alignment requirement */ |
| 612 template <typename Type, unsigned int Size> | 594 template <typename Type, unsigned int Size> |
| 613 struct IntType | 595 struct IntType |
| 614 { | 596 { |
| 615 inline void set (Type i) { v.set (i); } | 597 inline void set (Type i) { v.set (i); } |
| 616 inline operator Type(void) const { return v; } | 598 inline operator Type(void) const { return v; } |
| 617 inline bool operator == (const IntType<Type,Size> &o) const { return v == o.v;
} | 599 inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v
== (Type) o.v; } |
| 618 inline bool operator != (const IntType<Type,Size> &o) const { return v != o.v;
} | 600 inline bool operator != (const IntType<Type,Size> &o) const { return !(*this =
= o); } |
| 619 static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *
b) { return b->cmp (*a); } | 601 static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *
b) { return b->cmp (*a); } |
| 620 inline int cmp (IntType<Type,Size> va) const { Type a = va; Type b = v; return
a < b ? -1 : a == b ? 0 : +1; } | 602 inline int cmp (Type a) const |
| 621 inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +
1; } | 603 { |
| 622 inline bool sanitize (hb_sanitize_context_t *c) { | 604 Type b = v; |
| 605 if (sizeof (Type) < sizeof (int)) |
| 606 return (int) a - (int) b; |
| 607 else |
| 608 return a < b ? -1 : a == b ? 0 : +1; |
| 609 } |
| 610 inline bool sanitize (hb_sanitize_context_t *c) const |
| 611 { |
| 623 TRACE_SANITIZE (this); | 612 TRACE_SANITIZE (this); |
| 624 return TRACE_RETURN (likely (c->check_struct (this))); | 613 return TRACE_RETURN (likely (c->check_struct (this))); |
| 625 } | 614 } |
| 626 protected: | 615 protected: |
| 627 BEInt<Type, Size> v; | 616 BEInt<Type, Size> v; |
| 628 public: | 617 public: |
| 629 DEFINE_SIZE_STATIC (Size); | 618 DEFINE_SIZE_STATIC (Size); |
| 630 }; | 619 }; |
| 631 | 620 |
| 632 typedef uint8_t BYTE; /* 8-bit unsigned integer. */ | 621 typedef uint8_t BYTE; /* 8-bit unsigned integer. */ |
| 633 typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ | 622 typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ |
| 634 typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ | 623 typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ |
| 635 typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */ | 624 typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */ |
| 636 typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */ | 625 typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */ |
| 637 typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */ | 626 typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */ |
| 638 | 627 |
| 639 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ | 628 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ |
| 640 typedef SHORT FWORD; | 629 typedef SHORT FWORD; |
| 641 | 630 |
| 642 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ | 631 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ |
| 643 typedef USHORT UFWORD; | 632 typedef USHORT UFWORD; |
| 644 | 633 |
| 645 /* Date represented in number of seconds since 12:00 midnight, January 1, | 634 /* Date represented in number of seconds since 12:00 midnight, January 1, |
| 646 * 1904. The value is represented as a signed 64-bit integer. */ | 635 * 1904. The value is represented as a signed 64-bit integer. */ |
| 647 struct LONGDATETIME | 636 struct LONGDATETIME |
| 648 { | 637 { |
| 649 inline bool sanitize (hb_sanitize_context_t *c) { | 638 inline bool sanitize (hb_sanitize_context_t *c) const |
| 639 { |
| 650 TRACE_SANITIZE (this); | 640 TRACE_SANITIZE (this); |
| 651 return TRACE_RETURN (likely (c->check_struct (this))); | 641 return TRACE_RETURN (likely (c->check_struct (this))); |
| 652 } | 642 } |
| 653 protected: | 643 protected: |
| 654 LONG major; | 644 LONG major; |
| 655 ULONG minor; | 645 ULONG minor; |
| 656 public: | 646 public: |
| 657 DEFINE_SIZE_STATIC (8); | 647 DEFINE_SIZE_STATIC (8); |
| 658 }; | 648 }; |
| 659 | 649 |
| 660 /* Array of four uint8s (length = 32 bits) used to identify a script, language | 650 /* Array of four uint8s (length = 32 bits) used to identify a script, language |
| 661 * system, feature, or baseline */ | 651 * system, feature, or baseline */ |
| 662 struct Tag : ULONG | 652 struct Tag : ULONG |
| 663 { | 653 { |
| 664 /* What the char* converters return is NOT nul-terminated. Print using "%.4s"
*/ | 654 /* What the char* converters return is NOT nul-terminated. Print using "%.4s"
*/ |
| 665 inline operator const char* (void) const { return reinterpret_cast<const char
*> (&this->v); } | 655 inline operator const char* (void) const { return reinterpret_cast<const char
*> (&this->v); } |
| 666 inline operator char* (void) { return reinterpret_cast<char *> (&this->v); } | 656 inline operator char* (void) { return reinterpret_cast<char *> (&this->v); } |
| 667 public: | 657 public: |
| 668 DEFINE_SIZE_STATIC (4); | 658 DEFINE_SIZE_STATIC (4); |
| 669 }; | 659 }; |
| 670 DEFINE_NULL_DATA (Tag, " "); | 660 DEFINE_NULL_DATA (Tag, " "); |
| 671 | 661 |
| 672 /* Glyph index number, same as uint16 (length = 16 bits) */ | 662 /* Glyph index number, same as uint16 (length = 16 bits) */ |
| 673 typedef USHORT GlyphID; | 663 struct GlyphID : USHORT { |
| 664 static inline int cmp (const GlyphID *a, const GlyphID *b) { return b->USHORT:
:cmp (*a); } |
| 665 inline int cmp (hb_codepoint_t a) const { return (int) a - (int) *this; } |
| 666 }; |
| 674 | 667 |
| 675 /* Script/language-system/feature index */ | 668 /* Script/language-system/feature index */ |
| 676 struct Index : USHORT { | 669 struct Index : USHORT { |
| 677 static const unsigned int NOT_FOUND_INDEX = 0xFFFFu; | 670 static const unsigned int NOT_FOUND_INDEX = 0xFFFFu; |
| 678 }; | 671 }; |
| 679 DEFINE_NULL_DATA (Index, "\xff\xff"); | 672 DEFINE_NULL_DATA (Index, "\xff\xff"); |
| 680 | 673 |
| 681 /* Offset, Null offset = 0 */ | 674 /* Offset, Null offset = 0 */ |
| 682 template <typename Type=USHORT> | 675 template <typename Type=USHORT> |
| 683 struct Offset : Type | 676 struct Offset : Type |
| (...skipping 28 matching lines...) Expand all Loading... |
| 712 | 705 |
| 713 | 706 |
| 714 /* | 707 /* |
| 715 * Version Numbers | 708 * Version Numbers |
| 716 */ | 709 */ |
| 717 | 710 |
| 718 struct FixedVersion | 711 struct FixedVersion |
| 719 { | 712 { |
| 720 inline uint32_t to_int (void) const { return (major << 16) + minor; } | 713 inline uint32_t to_int (void) const { return (major << 16) + minor; } |
| 721 | 714 |
| 722 inline bool sanitize (hb_sanitize_context_t *c) { | 715 inline bool sanitize (hb_sanitize_context_t *c) const |
| 716 { |
| 723 TRACE_SANITIZE (this); | 717 TRACE_SANITIZE (this); |
| 724 return TRACE_RETURN (c->check_struct (this)); | 718 return TRACE_RETURN (c->check_struct (this)); |
| 725 } | 719 } |
| 726 | 720 |
| 727 USHORT major; | 721 USHORT major; |
| 728 USHORT minor; | 722 USHORT minor; |
| 729 public: | 723 public: |
| 730 DEFINE_SIZE_STATIC (4); | 724 DEFINE_SIZE_STATIC (4); |
| 731 }; | 725 }; |
| 732 | 726 |
| 733 | 727 |
| 734 | 728 |
| 735 /* | 729 /* |
| 736 * Template subclasses of Offset that do the dereferencing. | 730 * Template subclasses of Offset that do the dereferencing. |
| 737 * Use: (base+offset) | 731 * Use: (base+offset) |
| 738 */ | 732 */ |
| 739 | 733 |
| 740 template <typename Type, typename OffsetType=USHORT> | 734 template <typename Type, typename OffsetType=USHORT> |
| 741 struct OffsetTo : Offset<OffsetType> | 735 struct OffsetTo : Offset<OffsetType> |
| 742 { | 736 { |
| 743 inline const Type& operator () (const void *base) const | 737 inline const Type& operator () (const void *base) const |
| 744 { | 738 { |
| 745 unsigned int offset = *this; | 739 unsigned int offset = *this; |
| 746 if (unlikely (!offset)) return Null(Type); | 740 if (unlikely (!offset)) return Null(Type); |
| 747 return StructAtOffset<Type> (base, offset); | 741 return StructAtOffset<Type> (base, offset); |
| 748 } | 742 } |
| 749 | 743 |
| 750 inline Type& serialize (hb_serialize_context_t *c, void *base) | 744 inline Type& serialize (hb_serialize_context_t *c, const void *base) |
| 751 { | 745 { |
| 752 Type *t = c->start_embed<Type> (); | 746 Type *t = c->start_embed<Type> (); |
| 753 this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ | 747 this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ |
| 754 return *t; | 748 return *t; |
| 755 } | 749 } |
| 756 | 750 |
| 757 inline bool sanitize (hb_sanitize_context_t *c, void *base) { | 751 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
| 752 { |
| 758 TRACE_SANITIZE (this); | 753 TRACE_SANITIZE (this); |
| 759 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); | 754 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); |
| 760 unsigned int offset = *this; | 755 unsigned int offset = *this; |
| 761 if (unlikely (!offset)) return TRACE_RETURN (true); | 756 if (unlikely (!offset)) return TRACE_RETURN (true); |
| 762 Type &obj = StructAtOffset<Type> (base, offset); | 757 const Type &obj = StructAtOffset<Type> (base, offset); |
| 763 return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c)); | 758 return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c)); |
| 764 } | 759 } |
| 765 template <typename T> | 760 template <typename T> |
| 766 inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) { | 761 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data)
const |
| 762 { |
| 767 TRACE_SANITIZE (this); | 763 TRACE_SANITIZE (this); |
| 768 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); | 764 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); |
| 769 unsigned int offset = *this; | 765 unsigned int offset = *this; |
| 770 if (unlikely (!offset)) return TRACE_RETURN (true); | 766 if (unlikely (!offset)) return TRACE_RETURN (true); |
| 771 Type &obj = StructAtOffset<Type> (base, offset); | 767 const Type &obj = StructAtOffset<Type> (base, offset); |
| 772 return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c)); | 768 return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c)); |
| 773 } | 769 } |
| 774 | 770 |
| 775 /* Set the offset to Null */ | 771 /* Set the offset to Null */ |
| 776 inline bool neuter (hb_sanitize_context_t *c) { | 772 inline bool neuter (hb_sanitize_context_t *c) const { |
| 777 return c->try_set (this, 0); | 773 return c->try_set (this, 0); |
| 778 } | 774 } |
| 779 DEFINE_SIZE_STATIC (sizeof(OffsetType)); | 775 DEFINE_SIZE_STATIC (sizeof(OffsetType)); |
| 780 }; | 776 }; |
| 781 template <typename Base, typename OffsetType, typename Type> | 777 template <typename Base, typename OffsetType, typename Type> |
| 782 static inline const Type& operator + (const Base &base, const OffsetTo<Type, Off
setType> &offset) { return offset (base); } | 778 static inline const Type& operator + (const Base &base, const OffsetTo<Type, Off
setType> &offset) { return offset (base); } |
| 783 template <typename Base, typename OffsetType, typename Type> | 779 template <typename Base, typename OffsetType, typename Type> |
| 784 static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset)
{ return offset (base); } | 780 static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset)
{ return offset (base); } |
| 785 | 781 |
| 786 | 782 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 unsigned int items_len) | 827 unsigned int items_len) |
| 832 { | 828 { |
| 833 TRACE_SERIALIZE (this); | 829 TRACE_SERIALIZE (this); |
| 834 if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false); | 830 if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false); |
| 835 for (unsigned int i = 0; i < items_len; i++) | 831 for (unsigned int i = 0; i < items_len; i++) |
| 836 array[i] = items[i]; | 832 array[i] = items[i]; |
| 837 items.advance (items_len); | 833 items.advance (items_len); |
| 838 return TRACE_RETURN (true); | 834 return TRACE_RETURN (true); |
| 839 } | 835 } |
| 840 | 836 |
| 841 inline bool sanitize (hb_sanitize_context_t *c) { | 837 inline bool sanitize (hb_sanitize_context_t *c) const |
| 838 { |
| 842 TRACE_SANITIZE (this); | 839 TRACE_SANITIZE (this); |
| 843 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 840 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); |
| 844 | 841 |
| 845 /* Note: for structs that do not reference other structs, | 842 /* Note: for structs that do not reference other structs, |
| 846 * we do not need to call their sanitize() as we already did | 843 * we do not need to call their sanitize() as we already did |
| 847 * a bound check on the aggregate array size. We just include | 844 * a bound check on the aggregate array size. We just include |
| 848 * a small unreachable expression to make sure the structs | 845 * a small unreachable expression to make sure the structs |
| 849 * pointed to do have a simple sanitize(), ie. they do not | 846 * pointed to do have a simple sanitize(), ie. they do not |
| 850 * reference other structs via offsets. | 847 * reference other structs via offsets. |
| 851 */ | 848 */ |
| 852 (void) (false && array[0].sanitize (c)); | 849 (void) (false && array[0].sanitize (c)); |
| 853 | 850 |
| 854 return TRACE_RETURN (true); | 851 return TRACE_RETURN (true); |
| 855 } | 852 } |
| 856 inline bool sanitize (hb_sanitize_context_t *c, void *base) { | 853 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
| 854 { |
| 857 TRACE_SANITIZE (this); | 855 TRACE_SANITIZE (this); |
| 858 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 856 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); |
| 859 unsigned int count = len; | 857 unsigned int count = len; |
| 860 for (unsigned int i = 0; i < count; i++) | 858 for (unsigned int i = 0; i < count; i++) |
| 861 if (unlikely (!array[i].sanitize (c, base))) | 859 if (unlikely (!array[i].sanitize (c, base))) |
| 862 return TRACE_RETURN (false); | 860 return TRACE_RETURN (false); |
| 863 return TRACE_RETURN (true); | 861 return TRACE_RETURN (true); |
| 864 } | 862 } |
| 865 template <typename T> | 863 template <typename T> |
| 866 inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) { | 864 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data)
const |
| 865 { |
| 867 TRACE_SANITIZE (this); | 866 TRACE_SANITIZE (this); |
| 868 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 867 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); |
| 869 unsigned int count = len; | 868 unsigned int count = len; |
| 870 for (unsigned int i = 0; i < count; i++) | 869 for (unsigned int i = 0; i < count; i++) |
| 871 if (unlikely (!array[i].sanitize (c, base, user_data))) | 870 if (unlikely (!array[i].sanitize (c, base, user_data))) |
| 872 return TRACE_RETURN (false); | 871 return TRACE_RETURN (false); |
| 873 return TRACE_RETURN (true); | 872 return TRACE_RETURN (true); |
| 874 } | 873 } |
| 875 | 874 |
| 876 template <typename SearchType> | 875 template <typename SearchType> |
| 877 inline int lsearch (const SearchType &x) const | 876 inline int lsearch (const SearchType &x) const |
| 878 { | 877 { |
| 879 unsigned int count = len; | 878 unsigned int count = len; |
| 880 for (unsigned int i = 0; i < count; i++) | 879 for (unsigned int i = 0; i < count; i++) |
| 881 if (!this->array[i].cmp (x)) | 880 if (!this->array[i].cmp (x)) |
| 882 return i; | 881 return i; |
| 883 return -1; | 882 return -1; |
| 884 } | 883 } |
| 885 | 884 |
| 886 private: | 885 private: |
| 887 inline bool sanitize_shallow (hb_sanitize_context_t *c) { | 886 inline bool sanitize_shallow (hb_sanitize_context_t *c) const |
| 887 { |
| 888 TRACE_SANITIZE (this); | 888 TRACE_SANITIZE (this); |
| 889 return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::s
tatic_size, len)); | 889 return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::s
tatic_size, len)); |
| 890 } | 890 } |
| 891 | 891 |
| 892 public: | 892 public: |
| 893 LenType len; | 893 LenType len; |
| 894 Type array[VAR]; | 894 Type array[VAR]; |
| 895 public: | 895 public: |
| 896 DEFINE_SIZE_ARRAY (sizeof (LenType), array); | 896 DEFINE_SIZE_ARRAY (sizeof (LenType), array); |
| 897 }; | 897 }; |
| 898 | 898 |
| 899 /* Array of Offset's */ | 899 /* Array of Offset's */ |
| 900 template <typename Type> | 900 template <typename Type> |
| 901 struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {}; | 901 struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {}; |
| 902 | 902 |
| 903 /* Array of offsets relative to the beginning of the array itself. */ | 903 /* Array of offsets relative to the beginning of the array itself. */ |
| 904 template <typename Type> | 904 template <typename Type> |
| 905 struct OffsetListOf : OffsetArrayOf<Type> | 905 struct OffsetListOf : OffsetArrayOf<Type> |
| 906 { | 906 { |
| 907 inline const Type& operator [] (unsigned int i) const | 907 inline const Type& operator [] (unsigned int i) const |
| 908 { | 908 { |
| 909 if (unlikely (i >= this->len)) return Null(Type); | 909 if (unlikely (i >= this->len)) return Null(Type); |
| 910 return this+this->array[i]; | 910 return this+this->array[i]; |
| 911 } | 911 } |
| 912 | 912 |
| 913 inline bool sanitize (hb_sanitize_context_t *c) { | 913 inline bool sanitize (hb_sanitize_context_t *c) const |
| 914 { |
| 914 TRACE_SANITIZE (this); | 915 TRACE_SANITIZE (this); |
| 915 return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this)); | 916 return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this)); |
| 916 } | 917 } |
| 917 template <typename T> | 918 template <typename T> |
| 918 inline bool sanitize (hb_sanitize_context_t *c, T user_data) { | 919 inline bool sanitize (hb_sanitize_context_t *c, T user_data) const |
| 920 { |
| 919 TRACE_SANITIZE (this); | 921 TRACE_SANITIZE (this); |
| 920 return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data)); | 922 return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data)); |
| 921 } | 923 } |
| 922 }; | 924 }; |
| 923 | 925 |
| 924 | 926 |
| 925 /* An array starting at second element. */ | 927 /* An array starting at second element. */ |
| 926 template <typename Type, typename LenType=USHORT> | 928 template <typename Type, typename LenType=USHORT> |
| 927 struct HeadlessArrayOf | 929 struct HeadlessArrayOf |
| 928 { | 930 { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 942 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 944 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); |
| 943 len.set (items_len); /* TODO(serialize) Overflow? */ | 945 len.set (items_len); /* TODO(serialize) Overflow? */ |
| 944 if (unlikely (!items_len)) return TRACE_RETURN (true); | 946 if (unlikely (!items_len)) return TRACE_RETURN (true); |
| 945 if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); | 947 if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); |
| 946 for (unsigned int i = 0; i < items_len - 1; i++) | 948 for (unsigned int i = 0; i < items_len - 1; i++) |
| 947 array[i] = items[i]; | 949 array[i] = items[i]; |
| 948 items.advance (items_len - 1); | 950 items.advance (items_len - 1); |
| 949 return TRACE_RETURN (true); | 951 return TRACE_RETURN (true); |
| 950 } | 952 } |
| 951 | 953 |
| 952 inline bool sanitize_shallow (hb_sanitize_context_t *c) { | 954 inline bool sanitize_shallow (hb_sanitize_context_t *c) const |
| 955 { |
| 953 return c->check_struct (this) | 956 return c->check_struct (this) |
| 954 && c->check_array (this, Type::static_size, len); | 957 && c->check_array (this, Type::static_size, len); |
| 955 } | 958 } |
| 956 | 959 |
| 957 inline bool sanitize (hb_sanitize_context_t *c) { | 960 inline bool sanitize (hb_sanitize_context_t *c) const |
| 961 { |
| 958 TRACE_SANITIZE (this); | 962 TRACE_SANITIZE (this); |
| 959 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 963 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); |
| 960 | 964 |
| 961 /* Note: for structs that do not reference other structs, | 965 /* Note: for structs that do not reference other structs, |
| 962 * we do not need to call their sanitize() as we already did | 966 * we do not need to call their sanitize() as we already did |
| 963 * a bound check on the aggregate array size. We just include | 967 * a bound check on the aggregate array size. We just include |
| 964 * a small unreachable expression to make sure the structs | 968 * a small unreachable expression to make sure the structs |
| 965 * pointed to do have a simple sanitize(), ie. they do not | 969 * pointed to do have a simple sanitize(), ie. they do not |
| 966 * reference other structs via offsets. | 970 * reference other structs via offsets. |
| 967 */ | 971 */ |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 } | 1003 } |
| 1000 return -1; | 1004 return -1; |
| 1001 } | 1005 } |
| 1002 }; | 1006 }; |
| 1003 | 1007 |
| 1004 | 1008 |
| 1005 } /* namespace OT */ | 1009 } /* namespace OT */ |
| 1006 | 1010 |
| 1007 | 1011 |
| 1008 #endif /* HB_OPEN_TYPE_PRIVATE_HH */ | 1012 #endif /* HB_OPEN_TYPE_PRIVATE_HH */ |
| OLD | NEW |