[repacker] create repacker output buffer after final length is known.

Don't rely on a buffer provided by the caller, as it may not be large enough.
diff --git a/src/hb-repacker.hh b/src/hb-repacker.hh
index 68438a9..200f256 100644
--- a/src/hb-repacker.hh
+++ b/src/hb-repacker.hh
@@ -204,27 +204,46 @@
   /*
    * serialize graph into the provided serialization buffer.
    */
-  void serialize (hb_serialize_context_t* c) const
+  hb_blob_t* serialize () const
   {
-    c->start_serialize<void> ();
+    hb_vector_t<char> buffer;
+    size_t size = serialized_length ();
+    if (!buffer.alloc (size)) {
+      DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer.");
+      return nullptr;
+    }
+    hb_serialize_context_t c((void *) buffer, size);
+
+    c.start_serialize<void> ();
     for (unsigned i = 0; i < vertices_.length; i++) {
-      c->push ();
+      c.push ();
 
       size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
-      char* start = c->allocate_size <char> (size);
-      if (!start) return;
+      char* start = c.allocate_size <char> (size);
+      if (!start) {
+        DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space.");
+        return nullptr;
+      }
 
       memcpy (start, vertices_[i].obj.head, size);
 
       // Only real links needs to be serialized.
       for (const auto& link : vertices_[i].obj.real_links)
-        serialize_link (link, start, c);
+        serialize_link (link, start, &c);
 
       // All duplications are already encoded in the graph, so don't
       // enable sharing during packing.
-      c->pop_pack (false);
+      c.pop_pack (false);
     }
-    c->end_serialize ();
+    c.end_serialize ();
+
+    if (c.in_error ()) {
+      DEBUG_MSG (SUBSET_REPACK, nullptr, "Error during serialization. Err flag: %d",
+                 c.errors);
+      return nullptr;
+    }
+
+    return c.copy_blob ();
   }
 
   /*
@@ -725,6 +744,15 @@
 
  private:
 
+  size_t serialized_length () const {
+    size_t total_size = 0;
+    for (unsigned i = 0; i < vertices_.length; i++) {
+      size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
+      total_size += size;
+    }
+    return total_size;
+  }
+
   /*
    * Returns the numbers of incoming edges that are 32bits wide.
    */
@@ -1135,10 +1163,9 @@
  * For a detailed writeup describing how the algorithm operates see:
  * docs/repacker.md
  */
-inline void
+inline hb_blob_t*
 hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& packed,
                       hb_tag_t table_tag,
-                      hb_serialize_context_t* c,
                       unsigned max_rounds = 10) {
   // Kahn sort is ~twice as fast as shortest distance sort and works for many fonts
   // so try it first to save time.
@@ -1146,8 +1173,7 @@
   sorted_graph.sort_kahn ();
   if (!sorted_graph.will_overflow ())
   {
-    sorted_graph.serialize (c);
-    return;
+    return sorted_graph.serialize ();
   }
 
   sorted_graph.sort_shortest_distance ();
@@ -1186,17 +1212,17 @@
 
   if (sorted_graph.in_error ())
   {
-    c->err (HB_SERIALIZE_ERROR_OTHER);
-    return;
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "Sorted graph in error state.");
+    return nullptr;
   }
 
   if (sorted_graph.will_overflow ())
   {
-    c->err (HB_SERIALIZE_ERROR_OFFSET_OVERFLOW);
     DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed.");
-    return;
+    return nullptr;
   }
-  sorted_graph.serialize (c);
+
+  return sorted_graph.serialize ();
 }
 
 #endif /* HB_REPACKER_HH */
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index 048bdf1..bb46e5b 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -104,20 +104,16 @@
   if (!c.offset_overflow ())
     return c.copy_blob ();
 
-  hb_vector_t<char> buf;
-  int buf_size = c.end - c.start;
-  if (unlikely (!buf.alloc (buf_size)))
+  hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag);
+
+  if (unlikely (!result))
+  {
+    DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.",
+               HB_UNTAG (tag));
     return nullptr;
+  }
 
-  hb_serialize_context_t repacked ((void *) buf, buf_size);
-  hb_resolve_overflows (c.object_graph (), tag, &repacked);
-
-  if (unlikely (repacked.in_error ()))
-    // TODO(garretrieger): refactor so we can share the resize/retry logic with the subset
-    //                     portion.
-    return nullptr;
-
-  return repacked.copy_blob ();
+  return result;
 }
 
 template<typename TableType>
diff --git a/src/test-repacker.cc b/src/test-repacker.cc
index 86ab2ff..7c18ba4 100644
--- a/src/test-repacker.cc
+++ b/src/test-repacker.cc
@@ -74,14 +74,13 @@
 
   graph_t graph (overflowing.object_graph ());
 
-  unsigned buffer_size = overflowing.end - overflowing.start;
-  void* out_buffer = malloc (buffer_size);
-  hb_serialize_context_t out (out_buffer, buffer_size);
 
   assert (overflowing.offset_overflow ());
-  hb_resolve_overflows (overflowing.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), &out, num_iterations);
-  assert (!out.offset_overflow ());
-  hb_bytes_t result = out.copy_bytes ();
+  hb_blob_t* out = hb_resolve_overflows (overflowing.object_graph (),
+                                         HB_TAG ('G', 'S', 'U', 'B'), num_iterations);
+  assert (out);
+
+  hb_bytes_t result = out->as_bytes ();
 
   assert (!expected.offset_overflow ());
   hb_bytes_t expected_result = expected.copy_bytes ();
@@ -92,9 +91,8 @@
     assert (result[i] == expected_result[i]);
   }
 
-  result.fini ();
   expected_result.fini ();
-  free (out_buffer);
+  hb_blob_destroy (out);
 }
 
 static void add_virtual_offset (unsigned id,
@@ -962,19 +960,14 @@
   populate_serializer_simple (&c1);
   hb_bytes_t expected = c1.copy_bytes ();
 
-  void* buffer_2 = malloc (buffer_size);
-  hb_serialize_context_t c2 (buffer_2, buffer_size);
-
   graph_t graph (c1.object_graph ());
-  graph.serialize (&c2);
-  hb_bytes_t actual = c2.copy_bytes ();
-
-  assert (actual == expected);
-
-  actual.fini ();
-  expected.fini ();
+  hb_blob_t* out = graph.serialize ();
   free (buffer_1);
-  free (buffer_2);
+
+  hb_bytes_t actual = out->as_bytes ();
+  assert (actual == expected);
+  expected.fini ();
+  hb_blob_destroy (out);
 }
 
 static void test_will_overflow_1 ()
@@ -1024,17 +1017,13 @@
   populate_serializer_with_overflow (&c);
   graph_t graph (c.object_graph ());
 
-  void* out_buffer = malloc (buffer_size);
-  hb_serialize_context_t out (out_buffer, buffer_size);
-
-  hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, &out);
-  assert (!out.offset_overflow ());
-  hb_bytes_t result = out.copy_bytes ();
+  hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE);
+  assert (out);
+  hb_bytes_t result = out->as_bytes ();
   assert (result.length == (80000 + 3 + 3 * 2));
 
-  result.fini ();
   free (buffer);
-  free (out_buffer);
+  hb_blob_destroy (out);
 }
 
 static void test_resolve_overflows_via_duplication ()
@@ -1045,17 +1034,13 @@
   populate_serializer_with_dedup_overflow (&c);
   graph_t graph (c.object_graph ());
 
-  void* out_buffer = malloc (buffer_size);
-  hb_serialize_context_t out (out_buffer, buffer_size);
-
-  hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, &out);
-  assert (!out.offset_overflow ());
-  hb_bytes_t result = out.copy_bytes ();
+  hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE);
+  assert (out);
+  hb_bytes_t result = out->as_bytes ();
   assert (result.length == (10000 + 2 * 2 + 60000 + 2 + 3 * 2));
 
-  result.fini ();
   free (buffer);
-  free (out_buffer);
+  hb_blob_destroy (out);
 }
 
 static void test_resolve_overflows_via_space_assignment ()
@@ -1085,19 +1070,15 @@
   populate_serializer_with_isolation_overflow (&c);
   graph_t graph (c.object_graph ());
 
-  void* out_buffer = malloc (buffer_size);
-  hb_serialize_context_t out (out_buffer, buffer_size);
-
   assert (c.offset_overflow ());
-  hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), &out, 0);
-  assert (!out.offset_overflow ());
-  hb_bytes_t result = out.copy_bytes ();
+  hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0);
+  assert (out);
+  hb_bytes_t result = out->as_bytes ();
   assert (result.length == (1 + 10000 + 60000 + 1 + 1
                             + 4 + 3 * 2));
 
-  result.fini ();
   free (buffer);
-  free (out_buffer);
+  hb_blob_destroy (out);
 }
 
 static void test_resolve_overflows_via_isolation_with_recursive_duplication ()
@@ -1164,21 +1145,17 @@
   populate_serializer_with_isolation_overflow_spaces (&c);
   graph_t graph (c.object_graph ());
 
-  void* out_buffer = malloc (buffer_size);
-  hb_serialize_context_t out (out_buffer, buffer_size);
-
   assert (c.offset_overflow ());
-  hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), &out, 0);
-  assert (!out.offset_overflow ());
-  hb_bytes_t result = out.copy_bytes ();
+  hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0);
+  assert (out);
+  hb_bytes_t result = out->as_bytes ();
 
   unsigned expected_length = 3 + 2 * 60000; // objects
   expected_length += 2 * 4 + 2 * 2; // links
   assert (result.length == expected_length);
 
-  result.fini ();
   free (buffer);
-  free (out_buffer);
+  hb_blob_destroy (out);
 }
 
 static void test_resolve_overflows_via_splitting_spaces ()
@@ -1228,13 +1205,10 @@
   hb_serialize_context_t c (buffer, buffer_size);
   populate_serializer_virtual_link (&c);
 
-  void* out_buffer = malloc (buffer_size);
-  hb_serialize_context_t out (out_buffer, buffer_size);
+  hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE);
+  assert (out);
 
-  hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, &out);
-  assert (!out.offset_overflow ());
-
-  hb_bytes_t result = out.copy_bytes ();
+  hb_bytes_t result = out->as_bytes ();
   assert (result.length == 5 + 4 * 2);
   assert (result[0]  == 'a');
   assert (result[5]  == 'c');
@@ -1242,9 +1216,8 @@
   assert (result[9]  == 'b');
   assert (result[12] == 'd');
 
-  result.fini ();
   free (buffer);
-  free (out_buffer);
+  hb_blob_destroy (out);
 }
 
 static void