| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpos.h" | 5 #include "gpos.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "layout.h" | 10 #include "layout.h" |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 // Lookup Type 9: | 668 // Lookup Type 9: |
| 669 // Extension Positioning | 669 // Extension Positioning |
| 670 bool ParseExtensionPositioning(const ots::Font *font, | 670 bool ParseExtensionPositioning(const ots::Font *font, |
| 671 const uint8_t *data, const size_t length) { | 671 const uint8_t *data, const size_t length) { |
| 672 return ots::ParseExtensionSubtable(font, data, length, | 672 return ots::ParseExtensionSubtable(font, data, length, |
| 673 &kGposLookupSubtableParser); | 673 &kGposLookupSubtableParser); |
| 674 } | 674 } |
| 675 | 675 |
| 676 } // namespace | 676 } // namespace |
| 677 | 677 |
| 678 #define DROP_THIS_TABLE(msg_) \ | |
| 679 do { \ | |
| 680 OTS_FAILURE_MSG(msg_ ", table discarded"); \ | |
| 681 font->gpos->data = 0; \ | |
| 682 font->gpos->length = 0; \ | |
| 683 } while (0) | |
| 684 | |
| 685 namespace ots { | 678 namespace ots { |
| 686 | 679 |
| 687 // As far as I checked, following fonts contain invalid GPOS table and | 680 // As far as I checked, following fonts contain invalid GPOS table and |
| 688 // OTS will drop their GPOS table. | 681 // OTS will drop their GPOS table. |
| 689 // | 682 // |
| 690 // # invalid delta format in device table | 683 // # invalid delta format in device table |
| 691 // samanata.ttf | 684 // samanata.ttf |
| 692 // | 685 // |
| 693 // # bad size range in device table | 686 // # bad size range in device table |
| 694 // Sarai_07.ttf | 687 // Sarai_07.ttf |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 font->gpos = gpos; | 735 font->gpos = gpos; |
| 743 | 736 |
| 744 uint32_t version = 0; | 737 uint32_t version = 0; |
| 745 uint16_t offset_script_list = 0; | 738 uint16_t offset_script_list = 0; |
| 746 uint16_t offset_feature_list = 0; | 739 uint16_t offset_feature_list = 0; |
| 747 uint16_t offset_lookup_list = 0; | 740 uint16_t offset_lookup_list = 0; |
| 748 if (!table.ReadU32(&version) || | 741 if (!table.ReadU32(&version) || |
| 749 !table.ReadU16(&offset_script_list) || | 742 !table.ReadU16(&offset_script_list) || |
| 750 !table.ReadU16(&offset_feature_list) || | 743 !table.ReadU16(&offset_feature_list) || |
| 751 !table.ReadU16(&offset_lookup_list)) { | 744 !table.ReadU16(&offset_lookup_list)) { |
| 752 DROP_THIS_TABLE("Incomplete table"); | 745 return OTS_FAILURE_MSG("Incomplete table"); |
| 753 return true; | |
| 754 } | 746 } |
| 755 | 747 |
| 756 if (version != 0x00010000) { | 748 if (version != 0x00010000) { |
| 757 DROP_THIS_TABLE("Bad version"); | 749 return OTS_FAILURE_MSG("Bad version"); |
| 758 return true; | |
| 759 } | 750 } |
| 760 | 751 |
| 761 if (offset_lookup_list) { | 752 if (offset_lookup_list) { |
| 762 if (offset_lookup_list < kGposHeaderSize || offset_lookup_list >= length) { | 753 if (offset_lookup_list < kGposHeaderSize || offset_lookup_list >= length) { |
| 763 DROP_THIS_TABLE("Bad lookup list offset in table header"); | 754 return OTS_FAILURE_MSG("Bad lookup list offset in table header"); |
| 764 return true; | |
| 765 } | 755 } |
| 766 | 756 |
| 767 if (!ParseLookupListTable(font, data + offset_lookup_list, | 757 if (!ParseLookupListTable(font, data + offset_lookup_list, |
| 768 length - offset_lookup_list, | 758 length - offset_lookup_list, |
| 769 &kGposLookupSubtableParser, | 759 &kGposLookupSubtableParser, |
| 770 &gpos->num_lookups)) { | 760 &gpos->num_lookups)) { |
| 771 DROP_THIS_TABLE("Failed to parse lookup list table"); | 761 return OTS_FAILURE_MSG("Failed to parse lookup list table"); |
| 772 return true; | |
| 773 } | 762 } |
| 774 } | 763 } |
| 775 | 764 |
| 776 uint16_t num_features = 0; | 765 uint16_t num_features = 0; |
| 777 if (offset_feature_list) { | 766 if (offset_feature_list) { |
| 778 if (offset_feature_list < kGposHeaderSize || offset_feature_list >= length)
{ | 767 if (offset_feature_list < kGposHeaderSize || offset_feature_list >= length)
{ |
| 779 DROP_THIS_TABLE("Bad feature list offset in table header"); | 768 return OTS_FAILURE_MSG("Bad feature list offset in table header"); |
| 780 return true; | |
| 781 } | 769 } |
| 782 | 770 |
| 783 if (!ParseFeatureListTable(font, data + offset_feature_list, | 771 if (!ParseFeatureListTable(font, data + offset_feature_list, |
| 784 length - offset_feature_list, gpos->num_lookups, | 772 length - offset_feature_list, gpos->num_lookups, |
| 785 &num_features)) { | 773 &num_features)) { |
| 786 DROP_THIS_TABLE("Failed to parse feature list table"); | 774 return OTS_FAILURE_MSG("Failed to parse feature list table"); |
| 787 return true; | |
| 788 } | 775 } |
| 789 } | 776 } |
| 790 | 777 |
| 791 if (offset_script_list) { | 778 if (offset_script_list) { |
| 792 if (offset_script_list < kGposHeaderSize || offset_script_list >= length) { | 779 if (offset_script_list < kGposHeaderSize || offset_script_list >= length) { |
| 793 DROP_THIS_TABLE("Bad script list offset in table header"); | 780 return OTS_FAILURE_MSG("Bad script list offset in table header"); |
| 794 return true; | |
| 795 } | 781 } |
| 796 | 782 |
| 797 if (!ParseScriptListTable(font, data + offset_script_list, | 783 if (!ParseScriptListTable(font, data + offset_script_list, |
| 798 length - offset_script_list, num_features)) { | 784 length - offset_script_list, num_features)) { |
| 799 DROP_THIS_TABLE("Failed to parse script list table"); | 785 return OTS_FAILURE_MSG("Failed to parse script list table"); |
| 800 return true; | |
| 801 } | 786 } |
| 802 } | 787 } |
| 803 | 788 |
| 804 gpos->data = data; | 789 gpos->data = data; |
| 805 gpos->length = length; | 790 gpos->length = length; |
| 806 return true; | 791 return true; |
| 807 } | 792 } |
| 808 | 793 |
| 809 bool ots_gpos_should_serialise(Font *font) { | 794 bool ots_gpos_should_serialise(Font *font) { |
| 810 return font->gpos != NULL && font->gpos->data != NULL; | 795 return font->gpos != NULL && font->gpos->data != NULL; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 823 font->gpos_reused = true; | 808 font->gpos_reused = true; |
| 824 } | 809 } |
| 825 | 810 |
| 826 void ots_gpos_free(Font *font) { | 811 void ots_gpos_free(Font *font) { |
| 827 delete font->gpos; | 812 delete font->gpos; |
| 828 } | 813 } |
| 829 | 814 |
| 830 } // namespace ots | 815 } // namespace ots |
| 831 | 816 |
| 832 #undef TABLE_NAME | 817 #undef TABLE_NAME |
| 833 #undef DROP_THIS_TABLE | |
| OLD | NEW |