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 |