Fixing 2 typo bugs

This CL fixes two typo bugs reported at Chromium bug tracker:

- [OTS] font sanitizer incorrectly drops GDEF table in LinLibertine_Re-4.7.5.ttf
- [OTS] error in 'cmap' parser can crash the process using OTS

And, this CL modifies several boundary calculations to avoid overflow.

This CL also updates BLACKLIST.txt; some fonts have wrong offset in MarkAttachClassDef field of GDEF header table.

R=yusukes@chromium.org,agl@chromium.org
BUG=80797,93654
TEST=ran test_{un,}malicious_fonts.sh



git-svn-id: http://ots.googlecode.com/svn/trunk@71 a4e77c2c-9104-11de-800e-5b313e0d2bf3
diff --git a/src/layout.cc b/src/layout.cc
index 9877e6c..8dea164 100644
--- a/src/layout.cc
+++ b/src/layout.cc
@@ -97,8 +97,8 @@
     return OTS_FAILURE();
   }
 
-  const unsigned lang_sys_record_end = static_cast<unsigned>(4) +
-      lang_sys_count * 6;
+  const unsigned lang_sys_record_end =
+      6 * static_cast<unsigned>(lang_sys_count) + 4;
   if (lang_sys_record_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -146,8 +146,8 @@
     return OTS_FAILURE();
   }
 
-  const unsigned feature_table_end = static_cast<unsigned>(4) +
-      num_lookups * 2;
+  const unsigned feature_table_end =
+      2 * static_cast<unsigned>(num_lookups) + 4;
   if (feature_table_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -210,9 +210,8 @@
   subtables.reserve(subtable_count);
   // If the |kUseMarkFilteringSetBit| of |lookup_flag| is set,
   // extra 2 bytes will follow after subtable offset array.
-  const unsigned lookup_table_end =
-      static_cast<unsigned>(use_mark_filtering_set ? 8 : 6) +
-      subtable_count * 2;
+  const unsigned lookup_table_end = 2 * static_cast<unsigned>(subtable_count) +
+      (use_mark_filtering_set ? 8 : 6);
   if (lookup_table_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -471,8 +470,7 @@
   if (!subtable.ReadU16(&rule_count)) {
     return OTS_FAILURE();
   }
-  const unsigned rule_end = static_cast<unsigned>(2) +
-      rule_count * 2;
+  const unsigned rule_end = 2 * static_cast<unsigned>(rule_count) + 2;
   if (rule_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -578,8 +576,8 @@
   if (!subtable.ReadU16(&class_rule_count)) {
     return OTS_FAILURE();
   }
-  const unsigned class_rule_end = static_cast<unsigned>(2) +
-      class_rule_count * 2;
+  const unsigned class_rule_end =
+      2 * static_cast<unsigned>(class_rule_count) + 2;
   if (class_rule_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -617,8 +615,7 @@
     return OTS_FAILURE();
   }
 
-  const unsigned class_set_end = static_cast<unsigned>(8) +
-      class_set_cnt * 2;
+  const unsigned class_set_end = 2 * static_cast<unsigned>(class_set_cnt) + 8;
   if (class_set_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -676,8 +673,8 @@
   if (glyph_count >= num_glyphs) {
     return OTS_FAILURE();
   }
-  const unsigned lookup_record_end = static_cast<unsigned>(6) +
-      glyph_count * 2 + lookup_count * 4;
+  const unsigned lookup_record_end = 2 * static_cast<unsigned>(glyph_count) +
+      4 * static_cast<unsigned>(lookup_count) + 6;
   if (lookup_record_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -784,8 +781,8 @@
   if (!subtable.ReadU16(&chain_rule_count)) {
     return OTS_FAILURE();
   }
-  const unsigned chain_rule_end = static_cast<unsigned>(2) +
-      chain_rule_count * 2;
+  const unsigned chain_rule_end =
+      2 * static_cast<unsigned>(chain_rule_count) + 2;
   if (chain_rule_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -821,8 +818,8 @@
     return OTS_FAILURE();
   }
 
-  const unsigned chain_rule_set_end = static_cast<unsigned>(6) +
-      chain_rule_set_count * 2;
+  const unsigned chain_rule_set_end =
+      2 * static_cast<unsigned>(chain_rule_set_count) + 6;
   if (chain_rule_set_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -916,8 +913,8 @@
   if (!subtable.ReadU16(&chain_class_rule_count)) {
     return OTS_FAILURE();
   }
-  const unsigned chain_class_rule_end = static_cast<unsigned>(2) +
-      chain_class_rule_count * 2;
+  const unsigned chain_class_rule_end =
+      2 * static_cast<unsigned>(chain_class_rule_count) + 2;
   if (chain_class_rule_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -960,8 +957,8 @@
     return OTS_FAILURE();
   }
 
-  const unsigned chain_class_set_end = static_cast<unsigned>(12) +
-      chain_class_set_count * 2;
+  const unsigned chain_class_set_end =
+      2 * static_cast<unsigned>(chain_class_set_count) + 12;
   if (chain_class_set_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -1108,8 +1105,11 @@
     }
   }
 
-  const unsigned lookup_record_end = static_cast<unsigned>(10) +
-      (backtrack_count + input_count + lookahead_count) * 2 + lookup_count * 4;
+  const unsigned lookup_record_end =
+      2 * (static_cast<unsigned>(backtrack_count) +
+           static_cast<unsigned>(input_count) +
+           static_cast<unsigned>(lookahead_count)) +
+      4 * static_cast<unsigned>(lookup_count) + 10;
   if (lookup_record_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -1175,8 +1175,8 @@
     return OTS_FAILURE();
   }
 
-  const unsigned script_record_end = static_cast<unsigned>(2) +
-      script_count * 6;
+  const unsigned script_record_end =
+      6 * static_cast<unsigned>(script_count) + 2;
   if (script_record_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -1232,8 +1232,8 @@
 
   std::vector<FeatureRecord> feature_records;
   feature_records.resize(feature_count);
-  const unsigned feature_record_end = static_cast<unsigned>(2) +
-      feature_count * 6;
+  const unsigned feature_record_end =
+      6 * static_cast<unsigned>(feature_count) + 2;
   if (feature_record_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }
@@ -1282,8 +1282,8 @@
 
   std::vector<uint16_t> lookups;
   lookups.reserve(*num_lookups);
-  const unsigned lookup_end = static_cast<unsigned>(2) +
-      (*num_lookups) * 2;
+  const unsigned lookup_end =
+      2 * static_cast<unsigned>(*num_lookups) + 2;
   if (lookup_end > std::numeric_limits<uint16_t>::max()) {
     return OTS_FAILURE();
   }