• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2020  Google, Inc.
3  *
4  *  This is part of HarfBuzz, a text shaping library.
5  *
6  * Permission is hereby granted, without written agreement and without
7  * license or royalty fees, to use, copy, modify, and distribute this
8  * software and its documentation for any purpose, provided that the
9  * above copyright notice and the following two paragraphs appear in
10  * all copies of this software.
11  *
12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16  * DAMAGE.
17  *
18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  *
24  * Google Author(s): Garret Rieger
25  */
26 
27 #include <string>
28 
29 #include "hb-repacker.hh"
30 #include "hb-open-type.hh"
31 #include "graph/serialize.hh"
32 
extend(const char * value,unsigned len,hb_serialize_context_t * c)33 static void extend (const char* value,
34                     unsigned len,
35                     hb_serialize_context_t* c)
36 {
37   char* obj = c->allocate_size<char> (len);
38   hb_memcpy (obj, value, len);
39 }
40 
start_object(const char * tag,unsigned len,hb_serialize_context_t * c)41 static void start_object(const char* tag,
42                          unsigned len,
43                          hb_serialize_context_t* c)
44 {
45   c->push ();
46   extend (tag, len, c);
47 }
48 
add_object(const char * tag,unsigned len,hb_serialize_context_t * c)49 static unsigned add_object(const char* tag,
50                            unsigned len,
51                            hb_serialize_context_t* c)
52 {
53   start_object (tag, len, c);
54   return c->pop_pack (false);
55 }
56 
57 
add_offset(unsigned id,hb_serialize_context_t * c)58 static void add_offset (unsigned id,
59                         hb_serialize_context_t* c)
60 {
61   OT::Offset16* offset = c->start_embed<OT::Offset16> ();
62   c->extend_min (offset);
63   c->add_link (*offset, id);
64 }
65 
add_24_offset(unsigned id,hb_serialize_context_t * c)66 static void add_24_offset (unsigned id,
67                            hb_serialize_context_t* c)
68 {
69   OT::Offset24* offset = c->start_embed<OT::Offset24> ();
70   c->extend_min (offset);
71   c->add_link (*offset, id);
72 }
73 
add_wide_offset(unsigned id,hb_serialize_context_t * c)74 static void add_wide_offset (unsigned id,
75                              hb_serialize_context_t* c)
76 {
77   OT::Offset32* offset = c->start_embed<OT::Offset32> ();
78   c->extend_min (offset);
79   c->add_link (*offset, id);
80 }
81 
add_gsubgpos_header(unsigned lookup_list,hb_serialize_context_t * c)82 static void add_gsubgpos_header (unsigned lookup_list,
83                                  hb_serialize_context_t* c)
84 {
85   char header[] = {
86     0, 1, // major
87     0, 0, // minor
88     0, 0, // script list
89     0, 0, // feature list
90   };
91 
92   start_object (header, 8, c);
93   add_offset (lookup_list, c);
94   c->pop_pack (false);
95 }
96 
add_lookup_list(const unsigned * lookups,char count,hb_serialize_context_t * c)97 static unsigned add_lookup_list (const unsigned* lookups,
98                                  char count,
99                                  hb_serialize_context_t* c)
100 {
101   char lookup_count[] = {0, count};
102   start_object  ((char *) &lookup_count, 2, c);
103 
104   for (int i = 0; i < count; i++)
105     add_offset (lookups[i], c);
106 
107   return c->pop_pack (false);
108 }
109 
start_lookup(int8_t type,int8_t num_subtables,hb_serialize_context_t * c)110 static void start_lookup (int8_t type,
111                           int8_t num_subtables,
112                           hb_serialize_context_t* c)
113 {
114   char lookup[] = {
115     0, (char)type, // type
116     0, 0, // flag
117     0, (char)num_subtables, // num subtables
118   };
119 
120   start_object (lookup, 6, c);
121 }
122 
finish_lookup(hb_serialize_context_t * c)123 static unsigned finish_lookup (hb_serialize_context_t* c)
124 {
125   char filter[] = {0, 0};
126   extend (filter, 2, c);
127   return c->pop_pack (false);
128 }
129 
add_extension(unsigned child,uint8_t type,hb_serialize_context_t * c)130 static unsigned add_extension (unsigned child,
131                                uint8_t type,
132                                hb_serialize_context_t* c)
133 {
134   char ext[] = {
135     0, 1,
136     0, (char) type,
137   };
138 
139   start_object (ext, 4, c);
140   add_wide_offset (child, c);
141 
142   return c->pop_pack (false);
143 
144 }
145 
146 // Adds coverage table fro [start, end]
add_coverage(unsigned start,unsigned end,hb_serialize_context_t * c)147 static unsigned add_coverage (unsigned start, unsigned end,
148                               hb_serialize_context_t* c)
149 {
150   if (end - start == 1)
151   {
152     uint8_t coverage[] = {
153       0, 1, // format
154       0, 2, // count
155 
156       (uint8_t) ((start >> 8) & 0xFF),
157       (uint8_t) (start & 0xFF), // glyph[0]
158 
159       (uint8_t) ((end >> 8) & 0xFF),
160       (uint8_t) (end & 0xFF), // glyph[1]
161     };
162     return add_object ((char*) coverage, 8, c);
163   }
164 
165   uint8_t coverage[] = {
166     0, 2, // format
167     0, 1, // range count
168 
169     (uint8_t) ((start >> 8) & 0xFF),
170     (uint8_t) (start & 0xFF), // start
171 
172     (uint8_t) ((end >> 8) & 0xFF),
173     (uint8_t) (end & 0xFF), // end
174 
175     0, 0,
176   };
177   return add_object ((char*) coverage, 10, c);
178 }
179 
180 
181 template<typename It>
add_coverage(It it,hb_serialize_context_t * c)182 static unsigned add_coverage (It it,
183                               hb_serialize_context_t* c)
184 {
185   c->push ();
186   OT::Layout::Common::Coverage_serialize (c, it);
187   return c->pop_pack (false);
188 }
189 
190 // Adds a class that maps glyphs from [start_glyph, end_glyph)
191 // to classes 1...n
add_class_def(uint16_t start_glyph,uint16_t end_glyph,hb_serialize_context_t * c)192 static unsigned add_class_def (uint16_t start_glyph,
193                                uint16_t end_glyph,
194                                hb_serialize_context_t* c)
195 {
196   unsigned count = end_glyph - start_glyph;
197   uint8_t header[] = {
198     0, 1, // format
199 
200     (uint8_t) ((start_glyph >> 8) & 0xFF),
201     (uint8_t) (start_glyph & 0xFF), // start_glyph
202 
203     (uint8_t) ((count >> 8) & 0xFF),
204     (uint8_t) (count & 0xFF), // count
205   };
206 
207   start_object ((char*) header, 6, c);
208   for (uint16_t i = 1; i <= count; i++)
209   {
210     uint8_t class_value[] = {
211       (uint8_t) ((i >> 8) & 0xFF),
212       (uint8_t) (i & 0xFF), // count
213     };
214     extend ((char*) class_value, 2, c);
215   }
216 
217   return c->pop_pack (false);
218 }
219 
add_pair_pos_1(unsigned * pair_sets,char count,unsigned coverage,hb_serialize_context_t * c)220 static unsigned add_pair_pos_1 (unsigned* pair_sets,
221                                 char count,
222                                 unsigned coverage,
223                                 hb_serialize_context_t* c)
224 {
225   char format[] = {
226     0, 1
227   };
228 
229   start_object (format, 2, c);
230   add_offset (coverage, c);
231 
232   char value_format[] = {
233     0, 0,
234     0, 0,
235     0, count,
236   };
237   extend (value_format, 6, c);
238 
239   for (char i = 0; i < count; i++)
240     add_offset (pair_sets[(unsigned) i], c);
241 
242   return c->pop_pack (false);
243 }
244 
add_pair_pos_2(unsigned starting_class,unsigned coverage,unsigned class_def_1,uint16_t class_def_1_count,unsigned class_def_2,uint16_t class_def_2_count,unsigned * device_tables,hb_serialize_context_t * c)245 static unsigned add_pair_pos_2 (unsigned starting_class,
246                                 unsigned coverage,
247                                 unsigned class_def_1, uint16_t class_def_1_count,
248                                 unsigned class_def_2, uint16_t class_def_2_count,
249                                 unsigned* device_tables,
250                                 hb_serialize_context_t* c)
251 {
252   uint8_t format[] = {
253     0, 2
254   };
255 
256   start_object ((char*) format, 2, c);
257   add_offset (coverage, c);
258 
259   unsigned num_values = 4;
260   uint8_t format1 = 0x01 | 0x02 | 0x08;
261   uint8_t format2 = 0x04;
262   if (device_tables) {
263     format2 |= 0x20;
264     num_values += 1;
265   }
266   uint8_t value_format[] = {
267     0, format1,
268     0, format2,
269   };
270 
271   extend ((char*) value_format, 4, c);
272 
273   add_offset (class_def_1, c);
274   add_offset (class_def_2, c);
275 
276   uint8_t class_counts[] = {
277     (uint8_t) ((class_def_1_count >> 8) & 0xFF),
278     (uint8_t) (class_def_1_count & 0xFF),
279     (uint8_t) ((class_def_2_count >> 8) & 0xFF),
280     (uint8_t) (class_def_2_count & 0xFF),
281   };
282   extend ((char*) class_counts, 4, c);
283 
284   unsigned num_bytes_per_record = class_def_2_count * num_values * 2;
285   uint8_t* record = (uint8_t*) calloc (1, num_bytes_per_record);
286   int device_index = 0;
287   for (uint16_t i = 0; i < class_def_1_count; i++)
288   {
289 
290     for (uint16_t j = 0; j < class_def_2_count; j++)
291     {
292       for (int k = 0; k < 4; k++) {
293         uint8_t value[] = {
294           (uint8_t) (i + starting_class),
295           (uint8_t) (i + starting_class),
296         };
297         extend ((char*) value, 2, c);
298       }
299 
300       if (device_tables) {
301         add_offset (device_tables[device_index++], c);
302       }
303     }
304   }
305   free (record);
306 
307   return c->pop_pack (false);
308 }
309 
add_mark_base_pos_1(unsigned mark_coverage,unsigned base_coverage,unsigned mark_array,unsigned base_array,unsigned class_count,hb_serialize_context_t * c)310 static unsigned add_mark_base_pos_1 (unsigned mark_coverage,
311                                      unsigned base_coverage,
312                                      unsigned mark_array,
313                                      unsigned base_array,
314                                      unsigned class_count,
315                                      hb_serialize_context_t* c)
316 {
317   uint8_t format[] = {
318     0, 1
319   };
320 
321   start_object ((char*) format, 2, c);
322   add_offset (mark_coverage, c);
323   add_offset (base_coverage, c);
324 
325   uint8_t count[] = {
326     (uint8_t) ((class_count >> 8) & 0xFF),
327     (uint8_t) (class_count & 0xFF),
328   };
329   extend ((char*) count, 2, c);
330 
331   add_offset (mark_array, c);
332   add_offset (base_array, c);
333 
334   return c->pop_pack (false);
335 }
336 
337 template<int mark_count,
338     int class_count,
339     int base_count,
340     int table_count>
341 struct MarkBasePosBuffers
342 {
343   unsigned base_anchors[class_count * base_count];
344   unsigned mark_anchors[mark_count];
345   uint8_t anchor_buffers[class_count * base_count + 100];
346   uint8_t class_buffer[class_count * 2];
347 
MarkBasePosBuffersMarkBasePosBuffers348   MarkBasePosBuffers(hb_serialize_context_t* c)
349   {
350     for (unsigned i = 0; i < sizeof(anchor_buffers) / 2; i++)
351     {
352       OT::HBUINT16* value = (OT::HBUINT16*) (&anchor_buffers[2*i]);
353       *value = i;
354     }
355 
356     for (unsigned i = 0; i < class_count * base_count; i++)
357     {
358       base_anchors[i] = add_object ((char*) &anchor_buffers[i], 100, c);
359       if (i < class_count) {
360         class_buffer[i*2] = (uint8_t) ((i >> 8) & 0xFF);
361         class_buffer[i*2 + 1] = (uint8_t) (i & 0xFF);
362       }
363     }
364 
365     for (unsigned i = 0; i < mark_count; i++)
366     {
367       mark_anchors[i] = add_object ((char*) &anchor_buffers[i], 4, c);
368     }
369   }
370 
create_mark_base_pos_1MarkBasePosBuffers371   unsigned create_mark_base_pos_1 (unsigned table_index, hb_serialize_context_t* c)
372   {
373     unsigned class_per_table = class_count / table_count;
374     unsigned mark_per_class = mark_count / class_count;
375     unsigned start_class = class_per_table * table_index;
376     unsigned end_class = class_per_table * (table_index + 1) - 1;
377 
378     // baseArray
379     uint8_t base_count_buffer[] = {
380       (uint8_t) ((base_count >> 8) & 0xFF),
381       (uint8_t) (base_count & 0xFF),
382 
383     };
384     start_object ((char*) base_count_buffer, 2, c);
385     for (unsigned base = 0; base < base_count; base++)
386     {
387       for (unsigned klass = start_class; klass <= end_class; klass++)
388       {
389         unsigned i = base * class_count + klass;
390         add_offset (base_anchors[i], c);
391       }
392     }
393     unsigned base_array = c->pop_pack (false);
394 
395     // markArray
396     unsigned num_marks = class_per_table * mark_per_class;
397     uint8_t mark_count_buffer[] = {
398       (uint8_t) ((num_marks >> 8) & 0xFF),
399       (uint8_t) (num_marks & 0xFF),
400     };
401     start_object ((char*) mark_count_buffer, 2, c);
402     for (unsigned mark = 0; mark < mark_count; mark++)
403     {
404       unsigned klass = mark % class_count;
405       if (klass < start_class || klass > end_class) continue;
406       klass -= start_class;
407 
408       extend ((char*) &class_buffer[2 * klass], 2, c);
409       add_offset (mark_anchors[mark], c);
410     }
411     unsigned mark_array = c->pop_pack (false);
412 
413     // markCoverage
414     auto it =
415         + hb_range ((hb_codepoint_t) mark_count)
416         | hb_filter ([&] (hb_codepoint_t mark) {
417           unsigned klass = mark % class_count;
418           return klass >= class_per_table * table_index &&
419               klass < class_per_table * (table_index + 1);
420         })
421         ;
422     unsigned mark_coverage = add_coverage (it, c);
423 
424     // baseCoverage
425     unsigned base_coverage = add_coverage (10, 10 + base_count - 1, c);
426 
427     return add_mark_base_pos_1 (mark_coverage,
428                                 base_coverage,
429                                 mark_array,
430                                 base_array,
431                                 class_per_table,
432                                 c);
433   }
434 };
435 
436 
437 
438 
439 
run_resolve_overflow_test(const char * name,hb_serialize_context_t & overflowing,hb_serialize_context_t & expected,unsigned num_iterations=0,bool recalculate_extensions=false,hb_tag_t tag=HB_TAG ('G','S','U','B'))440 static void run_resolve_overflow_test (const char* name,
441                                        hb_serialize_context_t& overflowing,
442                                        hb_serialize_context_t& expected,
443                                        unsigned num_iterations = 0,
444                                        bool recalculate_extensions = false,
445                                        hb_tag_t tag = HB_TAG ('G', 'S', 'U', 'B'))
446 {
447   printf (">>> Testing overflowing resolution for %s\n",
448           name);
449 
450   graph_t graph (overflowing.object_graph ());
451 
452   graph_t expected_graph (expected.object_graph ());
453   if (graph::will_overflow (expected_graph))
454   {
455     expected_graph.assign_spaces ();
456     expected_graph.sort_shortest_distance ();
457   }
458 
459   // Check that overflow resolution succeeds
460   assert (overflowing.offset_overflow ());
461   assert (hb_resolve_graph_overflows (tag,
462                                       num_iterations,
463                                       recalculate_extensions,
464                                       graph));
465 
466   // Check the graphs can be serialized.
467   hb_blob_t* out = graph::serialize (graph);
468   assert (out);
469   hb_blob_destroy (out);
470   out = graph::serialize (expected_graph);
471   assert (out);
472   hb_blob_destroy (out);
473 
474   // Check the graphs are equivalent
475   graph.normalize ();
476   expected_graph.normalize ();
477   if (!(graph == expected_graph)) {
478     printf("## Expected:\n");
479     expected_graph.print();
480     printf("## Result:\n");
481     graph.print();
482   }
483   assert (graph == expected_graph);
484 }
485 
add_virtual_offset(unsigned id,hb_serialize_context_t * c)486 static void add_virtual_offset (unsigned id,
487                                 hb_serialize_context_t* c)
488 {
489   c->add_virtual_link (id);
490 }
491 
492 static void
populate_serializer_simple(hb_serialize_context_t * c)493 populate_serializer_simple (hb_serialize_context_t* c)
494 {
495   c->start_serialize<char> ();
496 
497   unsigned obj_1 = add_object ("ghi", 3, c);
498   unsigned obj_2 = add_object ("def", 3, c);
499 
500   start_object ("abc", 3, c);
501   add_offset (obj_2, c);
502   add_offset (obj_1, c);
503   c->pop_pack (false);
504 
505   c->end_serialize();
506 }
507 
508 static void
populate_serializer_with_overflow(hb_serialize_context_t * c)509 populate_serializer_with_overflow (hb_serialize_context_t* c)
510 {
511   std::string large_string(50000, 'a');
512   c->start_serialize<char> ();
513 
514   unsigned obj_1 = add_object (large_string.c_str(), 10000, c);
515   unsigned obj_2 = add_object (large_string.c_str(), 20000, c);
516   unsigned obj_3 = add_object (large_string.c_str(), 50000, c);
517 
518   start_object ("abc", 3, c);
519   add_offset (obj_3, c);
520   add_offset (obj_2, c);
521   add_offset (obj_1, c);
522   c->pop_pack (false);
523 
524   c->end_serialize();
525 }
526 
527 static void
populate_serializer_with_priority_overflow(hb_serialize_context_t * c)528 populate_serializer_with_priority_overflow (hb_serialize_context_t* c)
529 {
530   std::string large_string(50000, 'a');
531   c->start_serialize<char> ();
532 
533   unsigned obj_e = add_object ("e", 1, c);
534   unsigned obj_d = add_object ("d", 1, c);
535 
536   start_object (large_string.c_str (), 50000, c);
537   add_offset (obj_e, c);
538   unsigned obj_c = c->pop_pack (false);
539 
540   start_object (large_string.c_str (), 20000, c);
541   add_offset (obj_d, c);
542   unsigned obj_b = c->pop_pack (false);
543 
544   start_object ("a", 1, c);
545   add_offset (obj_b, c);
546   add_offset (obj_c, c);
547   c->pop_pack (false);
548 
549   c->end_serialize();
550 }
551 
552 static void
populate_serializer_with_priority_overflow_expected(hb_serialize_context_t * c)553 populate_serializer_with_priority_overflow_expected (hb_serialize_context_t* c)
554 {
555   std::string large_string(50000, 'a');
556   c->start_serialize<char> ();
557 
558   unsigned obj_e = add_object ("e", 1, c);
559 
560   start_object (large_string.c_str (), 50000, c);
561   add_offset (obj_e, c);
562   unsigned obj_c = c->pop_pack (false);
563 
564   unsigned obj_d = add_object ("d", 1, c);
565 
566   start_object (large_string.c_str (), 20000, c);
567   add_offset (obj_d, c);
568   unsigned obj_b = c->pop_pack (false);
569 
570   start_object ("a", 1, c);
571   add_offset (obj_b, c);
572   add_offset (obj_c, c);
573   c->pop_pack (false);
574 
575   c->end_serialize();
576 }
577 
578 
579 static void
populate_serializer_with_dedup_overflow(hb_serialize_context_t * c)580 populate_serializer_with_dedup_overflow (hb_serialize_context_t* c)
581 {
582   std::string large_string(70000, 'a');
583   c->start_serialize<char> ();
584 
585   unsigned obj_1 = add_object ("def", 3, c);
586 
587   start_object (large_string.c_str(), 60000, c);
588   add_offset (obj_1, c);
589   unsigned obj_2 = c->pop_pack (false);
590 
591   start_object (large_string.c_str(), 10000, c);
592   add_offset (obj_2, c);
593   add_offset (obj_1, c);
594   c->pop_pack (false);
595 
596   c->end_serialize();
597 }
598 
599 static void
populate_serializer_with_isolation_overflow(hb_serialize_context_t * c)600 populate_serializer_with_isolation_overflow (hb_serialize_context_t* c)
601 {
602   std::string large_string(70000, 'a');
603   c->start_serialize<char> ();
604 
605   unsigned obj_4 = add_object ("4", 1, c);
606 
607   start_object (large_string.c_str(), 60000, c);
608   add_offset (obj_4, c);
609   unsigned obj_3 = c->pop_pack (false);
610 
611   start_object (large_string.c_str(), 10000, c);
612   add_offset (obj_4, c);
613   unsigned obj_2 = c->pop_pack (false);
614 
615   start_object ("1", 1, c);
616   add_wide_offset (obj_3, c);
617   add_offset (obj_2, c);
618   c->pop_pack (false);
619 
620   c->end_serialize();
621 }
622 
623 static void
populate_serializer_with_isolation_overflow_complex(hb_serialize_context_t * c)624 populate_serializer_with_isolation_overflow_complex (hb_serialize_context_t* c)
625 {
626   std::string large_string(70000, 'a');
627   c->start_serialize<char> ();
628 
629   unsigned obj_f = add_object ("f", 1, c);
630 
631   start_object ("e", 1, c);
632   add_offset (obj_f, c);
633   unsigned obj_e = c->pop_pack (false);
634 
635   start_object ("c", 1, c);
636   add_offset (obj_e, c);
637   unsigned obj_c = c->pop_pack (false);
638 
639   start_object ("d", 1, c);
640   add_offset (obj_e, c);
641   unsigned obj_d = c->pop_pack (false);
642 
643   start_object (large_string.c_str(), 60000, c);
644   add_offset (obj_d, c);
645   unsigned obj_h = c->pop_pack (false);
646 
647   start_object (large_string.c_str(), 60000, c);
648   add_offset (obj_c, c);
649   add_offset (obj_h, c);
650   unsigned obj_b = c->pop_pack (false);
651 
652   start_object (large_string.c_str(), 10000, c);
653   add_offset (obj_d, c);
654   unsigned obj_g = c->pop_pack (false);
655 
656   start_object (large_string.c_str(), 11000, c);
657   add_offset (obj_d, c);
658   unsigned obj_i = c->pop_pack (false);
659 
660   start_object ("a", 1, c);
661   add_wide_offset (obj_b, c);
662   add_offset (obj_g, c);
663   add_offset (obj_i, c);
664   c->pop_pack (false);
665 
666   c->end_serialize();
667 }
668 
669 static void
populate_serializer_with_isolation_overflow_complex_expected(hb_serialize_context_t * c)670 populate_serializer_with_isolation_overflow_complex_expected (hb_serialize_context_t* c)
671 {
672   std::string large_string(70000, 'a');
673   c->start_serialize<char> ();
674 
675 
676   // space 1
677 
678   unsigned obj_f_prime = add_object ("f", 1, c);
679 
680   start_object ("e", 1, c);
681   add_offset (obj_f_prime, c);
682   unsigned obj_e_prime = c->pop_pack (false);
683 
684   start_object ("d", 1, c);
685   add_offset (obj_e_prime, c);
686   unsigned obj_d_prime = c->pop_pack (false);
687 
688   start_object (large_string.c_str(), 60000, c);
689   add_offset (obj_d_prime, c);
690   unsigned obj_h = c->pop_pack (false);
691 
692   start_object ("c", 1, c);
693   add_offset (obj_e_prime, c);
694   unsigned obj_c = c->pop_pack (false);
695 
696   start_object (large_string.c_str(), 60000, c);
697   add_offset (obj_c, c);
698   add_offset (obj_h, c);
699   unsigned obj_b = c->pop_pack (false);
700 
701   // space 0
702 
703   unsigned obj_f = add_object ("f", 1, c);
704 
705   start_object ("e", 1, c);
706   add_offset (obj_f, c);
707   unsigned obj_e = c->pop_pack (false);
708 
709 
710   start_object ("d", 1, c);
711   add_offset (obj_e, c);
712   unsigned obj_d = c->pop_pack (false);
713 
714   start_object (large_string.c_str(), 11000, c);
715   add_offset (obj_d, c);
716   unsigned obj_i = c->pop_pack (false);
717 
718   start_object (large_string.c_str(), 10000, c);
719   add_offset (obj_d, c);
720   unsigned obj_g = c->pop_pack (false);
721 
722   start_object ("a", 1, c);
723   add_wide_offset (obj_b, c);
724   add_offset (obj_g, c);
725   add_offset (obj_i, c);
726   c->pop_pack (false);
727 
728   c->end_serialize();
729 }
730 
731 static void
populate_serializer_with_isolation_overflow_spaces(hb_serialize_context_t * c)732 populate_serializer_with_isolation_overflow_spaces (hb_serialize_context_t* c)
733 {
734   std::string large_string(70000, 'a');
735   c->start_serialize<char> ();
736 
737   unsigned obj_d = add_object ("f", 1, c);
738   unsigned obj_e = add_object ("f", 1, c);
739 
740   start_object (large_string.c_str(), 60000, c);
741   add_offset (obj_d, c);
742   unsigned obj_b = c->pop_pack ();
743 
744   start_object (large_string.c_str(), 60000, c);
745   add_offset (obj_e, c);
746   unsigned obj_c = c->pop_pack ();
747 
748 
749   start_object ("a", 1, c);
750   add_wide_offset (obj_b, c);
751   add_wide_offset (obj_c, c);
752   c->pop_pack ();
753 
754   c->end_serialize();
755 }
756 
757 static void
populate_serializer_spaces(hb_serialize_context_t * c,bool with_overflow)758 populate_serializer_spaces (hb_serialize_context_t* c, bool with_overflow)
759 {
760   std::string large_string(70000, 'a');
761   c->start_serialize<char> ();
762 
763   unsigned obj_i;
764 
765   if (with_overflow)
766     obj_i = add_object ("i", 1, c);
767 
768   // Space 2
769   unsigned obj_h = add_object ("h", 1, c);
770 
771   start_object (large_string.c_str(), 30000, c);
772   add_offset (obj_h, c);
773   unsigned obj_e = c->pop_pack (false);
774 
775   start_object ("b", 1, c);
776   add_offset (obj_e, c);
777   unsigned obj_b = c->pop_pack (false);
778 
779   // Space 1
780   if (!with_overflow)
781     obj_i = add_object ("i", 1, c);
782 
783   start_object (large_string.c_str(), 30000, c);
784   add_offset (obj_i, c);
785   unsigned obj_g = c->pop_pack (false);
786 
787   start_object (large_string.c_str(), 30000, c);
788   add_offset (obj_i, c);
789   unsigned obj_f = c->pop_pack (false);
790 
791   start_object ("d", 1, c);
792   add_offset (obj_g, c);
793   unsigned obj_d = c->pop_pack (false);
794 
795   start_object ("c", 1, c);
796   add_offset (obj_f, c);
797   unsigned obj_c = c->pop_pack (false);
798 
799   start_object ("a", 1, c);
800   add_wide_offset (obj_b, c);
801   add_wide_offset (obj_c, c);
802   add_wide_offset (obj_d, c);
803   c->pop_pack (false);
804 
805   c->end_serialize();
806 }
807 
808 static void
populate_serializer_spaces_16bit_connection(hb_serialize_context_t * c)809 populate_serializer_spaces_16bit_connection (hb_serialize_context_t* c)
810 {
811   std::string large_string(70000, 'a');
812   c->start_serialize<char> ();
813 
814   unsigned obj_g = add_object ("g", 1, c);
815   unsigned obj_h = add_object ("h", 1, c);
816 
817   start_object (large_string.c_str (), 40000, c);
818   add_offset (obj_g, c);
819   unsigned obj_e = c->pop_pack (false);
820 
821   start_object (large_string.c_str (), 40000, c);
822   add_offset (obj_h, c);
823   unsigned obj_f = c->pop_pack (false);
824 
825   start_object ("c", 1, c);
826   add_offset (obj_e, c);
827   unsigned obj_c = c->pop_pack (false);
828 
829   start_object ("d", 1, c);
830   add_offset (obj_f, c);
831   unsigned obj_d = c->pop_pack (false);
832 
833   start_object ("b", 1, c);
834   add_offset (obj_e, c);
835   add_offset (obj_h, c);
836   unsigned obj_b = c->pop_pack (false);
837 
838   start_object ("a", 1, c);
839   add_offset (obj_b, c);
840   add_wide_offset (obj_c, c);
841   add_wide_offset (obj_d, c);
842   c->pop_pack (false);
843 
844   c->end_serialize();
845 }
846 
847 static void
populate_serializer_spaces_16bit_connection_expected(hb_serialize_context_t * c)848 populate_serializer_spaces_16bit_connection_expected (hb_serialize_context_t* c)
849 {
850   std::string large_string(70000, 'a');
851   c->start_serialize<char> ();
852 
853   unsigned obj_g_prime = add_object ("g", 1, c);
854 
855   start_object (large_string.c_str (), 40000, c);
856   add_offset (obj_g_prime, c);
857   unsigned obj_e_prime = c->pop_pack (false);
858 
859   start_object ("c", 1, c);
860   add_offset (obj_e_prime, c);
861   unsigned obj_c = c->pop_pack (false);
862 
863   unsigned obj_h_prime = add_object ("h", 1, c);
864 
865   start_object (large_string.c_str (), 40000, c);
866   add_offset (obj_h_prime, c);
867   unsigned obj_f = c->pop_pack (false);
868 
869   start_object ("d", 1, c);
870   add_offset (obj_f, c);
871   unsigned obj_d = c->pop_pack (false);
872 
873   unsigned obj_g = add_object ("g", 1, c);
874 
875   start_object (large_string.c_str (), 40000, c);
876   add_offset (obj_g, c);
877   unsigned obj_e = c->pop_pack (false);
878 
879   unsigned obj_h = add_object ("h", 1, c);
880 
881   start_object ("b", 1, c);
882   add_offset (obj_e, c);
883   add_offset (obj_h, c);
884   unsigned obj_b = c->pop_pack (false);
885 
886   start_object ("a", 1, c);
887   add_offset (obj_b, c);
888   add_wide_offset (obj_c, c);
889   add_wide_offset (obj_d, c);
890   c->pop_pack (false);
891 
892   c->end_serialize ();
893 }
894 
895 static void
populate_serializer_short_and_wide_subgraph_root(hb_serialize_context_t * c)896 populate_serializer_short_and_wide_subgraph_root (hb_serialize_context_t* c)
897 {
898   std::string large_string(70000, 'a');
899   c->start_serialize<char> ();
900 
901   unsigned obj_e = add_object ("e", 1, c);
902 
903   start_object (large_string.c_str (), 40000, c);
904   add_offset (obj_e, c);
905   unsigned obj_c = c->pop_pack (false);
906 
907   start_object (large_string.c_str (), 40000, c);
908   add_offset (obj_c, c);
909   unsigned obj_d = c->pop_pack (false);
910 
911   start_object ("b", 1, c);
912   add_offset (obj_c, c);
913   add_offset (obj_e, c);
914   unsigned obj_b = c->pop_pack (false);
915 
916   start_object ("a", 1, c);
917   add_offset (obj_b, c);
918   add_wide_offset (obj_c, c);
919   add_wide_offset (obj_d, c);
920   c->pop_pack (false);
921 
922   c->end_serialize();
923 }
924 
925 static void
populate_serializer_short_and_wide_subgraph_root_expected(hb_serialize_context_t * c)926 populate_serializer_short_and_wide_subgraph_root_expected (hb_serialize_context_t* c)
927 {
928   std::string large_string(70000, 'a');
929   c->start_serialize<char> ();
930 
931   unsigned obj_e_prime = add_object ("e", 1, c);
932 
933   start_object (large_string.c_str (), 40000, c);
934   add_offset (obj_e_prime, c);
935   unsigned obj_c_prime = c->pop_pack (false);
936 
937   start_object (large_string.c_str (), 40000, c);
938   add_offset (obj_c_prime, c);
939   unsigned obj_d = c->pop_pack (false);
940 
941   unsigned obj_e = add_object ("e", 1, c);
942 
943   start_object (large_string.c_str (), 40000, c);
944   add_offset (obj_e, c);
945   unsigned obj_c = c->pop_pack (false);
946 
947 
948   start_object ("b", 1, c);
949   add_offset (obj_c, c);
950   add_offset (obj_e, c);
951   unsigned obj_b = c->pop_pack (false);
952 
953   start_object ("a", 1, c);
954   add_offset (obj_b, c);
955   add_wide_offset (obj_c_prime, c);
956   add_wide_offset (obj_d, c);
957   c->pop_pack (false);
958 
959   c->end_serialize();
960 }
961 
962 static void
populate_serializer_with_split_spaces(hb_serialize_context_t * c)963 populate_serializer_with_split_spaces (hb_serialize_context_t* c)
964 {
965   // Overflow needs to be resolved by splitting the single space
966   std::string large_string(70000, 'a');
967   c->start_serialize<char> ();
968 
969   unsigned obj_f = add_object ("f", 1, c);
970 
971   start_object (large_string.c_str(), 40000, c);
972   add_offset (obj_f, c);
973   unsigned obj_d = c->pop_pack (false);
974 
975   start_object (large_string.c_str(), 40000, c);
976   add_offset (obj_f, c);
977   unsigned obj_e = c->pop_pack (false);
978 
979   start_object ("b", 1, c);
980   add_offset (obj_d, c);
981   unsigned obj_b = c->pop_pack (false);
982 
983   start_object ("c", 1, c);
984   add_offset (obj_e, c);
985   unsigned obj_c = c->pop_pack (false);
986 
987   start_object ("a", 1, c);
988   add_wide_offset (obj_b, c);
989   add_wide_offset (obj_c, c);
990   c->pop_pack (false);
991 
992   c->end_serialize();
993 }
994 
995 static void
populate_serializer_with_split_spaces_2(hb_serialize_context_t * c)996 populate_serializer_with_split_spaces_2 (hb_serialize_context_t* c)
997 {
998   // Overflow needs to be resolved by splitting the single space
999   std::string large_string(70000, 'a');
1000   c->start_serialize<char> ();
1001 
1002   unsigned obj_f = add_object ("f", 1, c);
1003 
1004   start_object (large_string.c_str(), 40000, c);
1005   add_offset (obj_f, c);
1006   unsigned obj_d = c->pop_pack (false);
1007 
1008   start_object (large_string.c_str(), 40000, c);
1009   add_offset (obj_f, c);
1010   unsigned obj_e = c->pop_pack (false);
1011 
1012   start_object ("b", 1, c);
1013   add_offset (obj_d, c);
1014   unsigned obj_b = c->pop_pack (false);
1015 
1016   start_object ("c", 1, c);
1017   add_offset (obj_e, c);
1018   unsigned obj_c = c->pop_pack (false);
1019 
1020   start_object ("a", 1, c);
1021   add_offset (obj_b, c);
1022   add_wide_offset (obj_b, c);
1023   add_wide_offset (obj_c, c);
1024   c->pop_pack (false);
1025 
1026   c->end_serialize();
1027 }
1028 
1029 static void
populate_serializer_with_split_spaces_expected(hb_serialize_context_t * c)1030 populate_serializer_with_split_spaces_expected (hb_serialize_context_t* c)
1031 {
1032   // Overflow needs to be resolved by splitting the single space
1033 
1034   std::string large_string(70000, 'a');
1035   c->start_serialize<char> ();
1036 
1037   unsigned obj_f_prime = add_object ("f", 1, c);
1038 
1039   start_object (large_string.c_str(), 40000, c);
1040   add_offset (obj_f_prime, c);
1041   unsigned obj_d = c->pop_pack (false);
1042 
1043   start_object ("b", 1, c);
1044   add_offset (obj_d, c);
1045   unsigned obj_b = c->pop_pack (false);
1046 
1047   unsigned obj_f = add_object ("f", 1, c);
1048 
1049   start_object (large_string.c_str(), 40000, c);
1050   add_offset (obj_f, c);
1051   unsigned obj_e = c->pop_pack (false);
1052 
1053   start_object ("c", 1, c);
1054   add_offset (obj_e, c);
1055   unsigned obj_c = c->pop_pack (false);
1056 
1057   start_object ("a", 1, c);
1058   add_wide_offset (obj_b, c);
1059   add_wide_offset (obj_c, c);
1060   c->pop_pack (false);
1061 
1062   c->end_serialize();
1063 }
1064 
1065 static void
populate_serializer_with_split_spaces_expected_2(hb_serialize_context_t * c)1066 populate_serializer_with_split_spaces_expected_2 (hb_serialize_context_t* c)
1067 {
1068   // Overflow needs to be resolved by splitting the single space
1069 
1070   std::string large_string(70000, 'a');
1071   c->start_serialize<char> ();
1072 
1073   // Space 2
1074 
1075   unsigned obj_f_double_prime = add_object ("f", 1, c);
1076 
1077   start_object (large_string.c_str(), 40000, c);
1078   add_offset (obj_f_double_prime, c);
1079   unsigned obj_d_prime = c->pop_pack (false);
1080 
1081   start_object ("b", 1, c);
1082   add_offset (obj_d_prime, c);
1083   unsigned obj_b_prime = c->pop_pack (false);
1084 
1085   // Space 1
1086 
1087   unsigned obj_f_prime = add_object ("f", 1, c);
1088 
1089   start_object (large_string.c_str(), 40000, c);
1090   add_offset (obj_f_prime, c);
1091   unsigned obj_e = c->pop_pack (false);
1092 
1093   start_object ("c", 1, c);
1094   add_offset (obj_e, c);
1095   unsigned obj_c = c->pop_pack (false);
1096 
1097   // Space 0
1098 
1099   unsigned obj_f = add_object ("f", 1, c);
1100 
1101   start_object (large_string.c_str(), 40000, c);
1102   add_offset (obj_f, c);
1103   unsigned obj_d = c->pop_pack (false);
1104 
1105   start_object ("b", 1, c);
1106   add_offset (obj_d, c);
1107   unsigned obj_b = c->pop_pack (false);
1108 
1109   // Root
1110   start_object ("a", 1, c);
1111   add_offset (obj_b, c);
1112   add_wide_offset (obj_b_prime, c);
1113   add_wide_offset (obj_c, c);
1114   c->pop_pack (false);
1115 
1116   c->end_serialize();
1117 }
1118 
1119 static void
populate_serializer_complex_2(hb_serialize_context_t * c)1120 populate_serializer_complex_2 (hb_serialize_context_t* c)
1121 {
1122   c->start_serialize<char> ();
1123 
1124   unsigned obj_5 = add_object ("mn", 2, c);
1125 
1126   unsigned obj_4 = add_object ("jkl", 3, c);
1127 
1128   start_object ("ghi", 3, c);
1129   add_offset (obj_4, c);
1130   unsigned obj_3 = c->pop_pack (false);
1131 
1132   start_object ("def", 3, c);
1133   add_offset (obj_3, c);
1134   unsigned obj_2 = c->pop_pack (false);
1135 
1136   start_object ("abc", 3, c);
1137   add_offset (obj_2, c);
1138   add_offset (obj_4, c);
1139   add_offset (obj_5, c);
1140   c->pop_pack (false);
1141 
1142   c->end_serialize();
1143 }
1144 
1145 static void
populate_serializer_complex_3(hb_serialize_context_t * c)1146 populate_serializer_complex_3 (hb_serialize_context_t* c)
1147 {
1148   c->start_serialize<char> ();
1149 
1150   unsigned obj_6 = add_object ("opqrst", 6, c);
1151 
1152   unsigned obj_5 = add_object ("mn", 2, c);
1153 
1154   start_object ("jkl", 3, c);
1155   add_offset (obj_6, c);
1156   unsigned obj_4 = c->pop_pack (false);
1157 
1158   start_object ("ghi", 3, c);
1159   add_offset (obj_4, c);
1160   unsigned obj_3 = c->pop_pack (false);
1161 
1162   start_object ("def", 3, c);
1163   add_offset (obj_3, c);
1164   unsigned obj_2 = c->pop_pack (false);
1165 
1166   start_object ("abc", 3, c);
1167   add_offset (obj_2, c);
1168   add_offset (obj_4, c);
1169   add_offset (obj_5, c);
1170   c->pop_pack (false);
1171 
1172   c->end_serialize();
1173 }
1174 
1175 static void
populate_serializer_virtual_link(hb_serialize_context_t * c)1176 populate_serializer_virtual_link (hb_serialize_context_t* c)
1177 {
1178   c->start_serialize<char> ();
1179 
1180   unsigned obj_d = add_object ("d", 1, c);
1181 
1182   start_object ("b", 1, c);
1183   add_offset (obj_d, c);
1184   unsigned obj_b = c->pop_pack (false);
1185 
1186   start_object ("e", 1, c);
1187   add_virtual_offset (obj_b, c);
1188   unsigned obj_e = c->pop_pack (false);
1189 
1190   start_object ("c", 1, c);
1191   add_offset (obj_e, c);
1192   unsigned obj_c = c->pop_pack (false);
1193 
1194   start_object ("a", 1, c);
1195   add_offset (obj_b, c);
1196   add_offset (obj_c, c);
1197   c->pop_pack (false);
1198 
1199   c->end_serialize();
1200 }
1201 
1202 static void
populate_serializer_with_24_and_32_bit_offsets(hb_serialize_context_t * c)1203 populate_serializer_with_24_and_32_bit_offsets (hb_serialize_context_t* c)
1204 {
1205   std::string large_string(60000, 'a');
1206   c->start_serialize<char> ();
1207 
1208   unsigned obj_f = add_object ("f", 1, c);
1209   unsigned obj_g = add_object ("g", 1, c);
1210   unsigned obj_j = add_object ("j", 1, c);
1211   unsigned obj_k = add_object ("k", 1, c);
1212 
1213   start_object (large_string.c_str (), 40000, c);
1214   add_offset (obj_f, c);
1215   unsigned obj_c = c->pop_pack (false);
1216 
1217   start_object (large_string.c_str (), 40000, c);
1218   add_offset (obj_g, c);
1219   unsigned obj_d = c->pop_pack (false);
1220 
1221   start_object (large_string.c_str (), 40000, c);
1222   add_offset (obj_j, c);
1223   unsigned obj_h = c->pop_pack (false);
1224 
1225   start_object (large_string.c_str (), 40000, c);
1226   add_offset (obj_k, c);
1227   unsigned obj_i = c->pop_pack (false);
1228 
1229   start_object ("e", 1, c);
1230   add_wide_offset (obj_h, c);
1231   add_wide_offset (obj_i, c);
1232   unsigned obj_e = c->pop_pack (false);
1233 
1234   start_object ("b", 1, c);
1235   add_24_offset (obj_c, c);
1236   add_24_offset (obj_d, c);
1237   add_24_offset (obj_e, c);
1238   unsigned obj_b = c->pop_pack (false);
1239 
1240   start_object ("a", 1, c);
1241   add_24_offset (obj_b, c);
1242   c->pop_pack (false);
1243 
1244   c->end_serialize();
1245 }
1246 
1247 static void
populate_serializer_with_extension_promotion(hb_serialize_context_t * c,int num_extensions=0,bool shared_subtables=false)1248 populate_serializer_with_extension_promotion (hb_serialize_context_t* c,
1249                                               int num_extensions = 0,
1250                                               bool shared_subtables = false)
1251 {
1252   constexpr int num_lookups = 5;
1253   constexpr int num_subtables = num_lookups * 2;
1254   unsigned int lookups[num_lookups];
1255   unsigned int subtables[num_subtables];
1256   unsigned int extensions[num_subtables];
1257 
1258   std::string large_string(60000, 'a');
1259   c->start_serialize<char> ();
1260 
1261 
1262   for (int i = num_subtables - 1; i >= 0; i--)
1263     subtables[i] = add_object(large_string.c_str (), 15000 + i, c);
1264 
1265   for (int i = num_subtables - 1;
1266        i >= (num_lookups - num_extensions) * 2;
1267        i--)
1268   {
1269     extensions[i] = add_extension (subtables[i], 5, c);
1270   }
1271 
1272   for (int i = num_lookups - 1; i >= 0; i--)
1273   {
1274     bool is_ext = (i >= (num_lookups - num_extensions));
1275 
1276     start_lookup (is_ext ? (char) 7 : (char) 5,
1277                   shared_subtables && i > 2 ? 3 : 2,
1278                   c);
1279 
1280     if (is_ext) {
1281       if (shared_subtables && i > 2) {
1282         add_offset (extensions[i * 2 - 1], c);
1283       }
1284       add_offset (extensions[i * 2], c);
1285       add_offset (extensions[i * 2 + 1], c);
1286     } else {
1287       if (shared_subtables && i > 2) {
1288         add_offset (subtables[i * 2 - 1], c);
1289       }
1290       add_offset (subtables[i * 2], c);
1291       add_offset (subtables[i * 2 + 1], c);
1292     }
1293 
1294     lookups[i] = finish_lookup (c);
1295   }
1296 
1297   unsigned lookup_list = add_lookup_list (lookups, num_lookups, c);
1298 
1299   add_gsubgpos_header (lookup_list, c);
1300 
1301   c->end_serialize();
1302 }
1303 
1304 template<int num_pair_pos_1, int num_pair_set>
1305 static void
populate_serializer_with_large_pair_pos_1(hb_serialize_context_t * c,bool as_extension=false)1306 populate_serializer_with_large_pair_pos_1 (hb_serialize_context_t* c,
1307                                            bool as_extension = false)
1308 {
1309   std::string large_string(60000, 'a');
1310   c->start_serialize<char> ();
1311 
1312   constexpr int total_pair_set = num_pair_pos_1 * num_pair_set;
1313   unsigned pair_set[total_pair_set];
1314   unsigned coverage[num_pair_pos_1];
1315   unsigned pair_pos_1[num_pair_pos_1];
1316 
1317   for (int i = num_pair_pos_1 - 1; i >= 0; i--)
1318   {
1319     for (int j = (i + 1) * num_pair_set - 1; j >= i * num_pair_set; j--)
1320       pair_set[j] = add_object (large_string.c_str (), 30000 + j, c);
1321 
1322     coverage[i] = add_coverage (i * num_pair_set,
1323                                 (i + 1) * num_pair_set - 1, c);
1324 
1325     pair_pos_1[i] = add_pair_pos_1 (&pair_set[i * num_pair_set],
1326                                     num_pair_set,
1327                                     coverage[i],
1328                                     c);
1329   }
1330 
1331   unsigned pair_pos_2 = add_object (large_string.c_str(), 200, c);
1332 
1333   if (as_extension) {
1334     pair_pos_2 = add_extension (pair_pos_2, 2, c);
1335     for (int i = num_pair_pos_1 - 1; i >= 0; i--)
1336       pair_pos_1[i] = add_extension (pair_pos_1[i], 2, c);
1337   }
1338 
1339   start_lookup (as_extension ? 9 : 2, 1 + num_pair_pos_1, c);
1340 
1341   for (int i = 0; i < num_pair_pos_1; i++)
1342     add_offset (pair_pos_1[i], c);
1343   add_offset (pair_pos_2, c);
1344 
1345   unsigned lookup = finish_lookup (c);
1346 
1347   unsigned lookup_list = add_lookup_list (&lookup, 1, c);
1348 
1349   add_gsubgpos_header (lookup_list, c);
1350 
1351   c->end_serialize();
1352 }
1353 
1354 template<int num_pair_pos_2, int num_class_1, int num_class_2>
1355 static void
populate_serializer_with_large_pair_pos_2(hb_serialize_context_t * c,bool as_extension=false,bool with_device_tables=false,bool extra_table=true)1356 populate_serializer_with_large_pair_pos_2 (hb_serialize_context_t* c,
1357                                            bool as_extension = false,
1358                                            bool with_device_tables = false,
1359                                            bool extra_table = true)
1360 {
1361   std::string large_string(100000, 'a');
1362   c->start_serialize<char> ();
1363 
1364   unsigned coverage[num_pair_pos_2];
1365   unsigned class_def_1[num_pair_pos_2];
1366   unsigned class_def_2[num_pair_pos_2];
1367   unsigned pair_pos_2[num_pair_pos_2];
1368 
1369   unsigned* device_tables = (unsigned*) calloc (num_pair_pos_2 * num_class_1 * num_class_2,
1370                                                 sizeof(unsigned));
1371 
1372   // Total glyphs = num_class_1 * num_pair_pos_2
1373   for (int i = num_pair_pos_2 - 1; i >= 0; i--)
1374   {
1375     unsigned start_glyph = 5 + i * num_class_1;
1376     if (num_class_2 >= num_class_1)
1377     {
1378       class_def_2[i] = add_class_def (11,
1379                                       10 + num_class_2, c);
1380       class_def_1[i] = add_class_def (start_glyph + 1,
1381                                       start_glyph + num_class_1,
1382                                       c);
1383     } else {
1384       class_def_1[i] = add_class_def (start_glyph + 1,
1385                                       start_glyph + num_class_1,
1386                                       c);
1387       class_def_2[i] = add_class_def (11,
1388                                       10 + num_class_2, c);
1389     }
1390 
1391     coverage[i] = add_coverage (start_glyph,
1392                                 start_glyph + num_class_1 - 1,
1393                                 c);
1394 
1395     if (with_device_tables)
1396     {
1397       for(int j = (i + 1) * num_class_1 * num_class_2 - 1;
1398           j >= i * num_class_1 * num_class_2;
1399           j--)
1400       {
1401         uint8_t table[] = {
1402           (uint8_t) ((j >> 8) & 0xFF),
1403           (uint8_t) (j & 0xFF),
1404         };
1405         device_tables[j] = add_object ((char*) table, 2, c);
1406       }
1407     }
1408 
1409     pair_pos_2[i] = add_pair_pos_2 (1 + i * num_class_1,
1410                                     coverage[i],
1411                                     class_def_1[i], num_class_1,
1412                                     class_def_2[i], num_class_2,
1413                                     with_device_tables
1414                                     ? &device_tables[i * num_class_1 * num_class_2]
1415                                     : nullptr,
1416                                     c);
1417   }
1418 
1419 
1420   unsigned pair_pos_1 = 0;
1421   if (extra_table) pair_pos_1 = add_object (large_string.c_str(), 100000, c);
1422 
1423   if (as_extension) {
1424     for (int i = num_pair_pos_2 - 1; i >= 0; i--)
1425       pair_pos_2[i] = add_extension (pair_pos_2[i], 2, c);
1426 
1427     if (extra_table)
1428       pair_pos_1 = add_extension (pair_pos_1, 2, c);
1429   }
1430 
1431   start_lookup (as_extension ? 9 : 2, 1 + num_pair_pos_2, c);
1432 
1433   if (extra_table)
1434     add_offset (pair_pos_1, c);
1435 
1436   for (int i = 0; i < num_pair_pos_2; i++)
1437     add_offset (pair_pos_2[i], c);
1438 
1439   unsigned lookup = finish_lookup (c);
1440 
1441   unsigned lookup_list = add_lookup_list (&lookup, 1, c);
1442 
1443   add_gsubgpos_header (lookup_list, c);
1444 
1445   c->end_serialize();
1446 
1447   free (device_tables);
1448 }
1449 
1450 template<int mark_count,
1451     int class_count,
1452     int base_count,
1453     int table_count>
1454 static void
populate_serializer_with_large_mark_base_pos_1(hb_serialize_context_t * c)1455 populate_serializer_with_large_mark_base_pos_1 (hb_serialize_context_t* c)
1456 {
1457   c->start_serialize<char> ();
1458 
1459   MarkBasePosBuffers<mark_count, class_count, base_count, table_count> buffers (c);
1460 
1461   unsigned mark_base_pos[table_count];
1462   for (unsigned i = 0; i < table_count; i++)
1463     mark_base_pos[i] = buffers.create_mark_base_pos_1 (i, c);
1464 
1465   for (int i = 0; i < table_count; i++)
1466     mark_base_pos[i] = add_extension (mark_base_pos[i], 4, c);
1467 
1468   start_lookup (9, table_count, c);
1469 
1470   for (int i = 0; i < table_count; i++)
1471     add_offset (mark_base_pos[i], c);
1472 
1473   unsigned lookup = finish_lookup (c);
1474 
1475   unsigned lookup_list = add_lookup_list (&lookup, 1, c);
1476 
1477   add_gsubgpos_header (lookup_list, c);
1478 
1479   c->end_serialize();
1480 }
1481 
test_sort_shortest()1482 static void test_sort_shortest ()
1483 {
1484   size_t buffer_size = 100;
1485   void* buffer = malloc (buffer_size);
1486   hb_serialize_context_t c (buffer, buffer_size);
1487   populate_serializer_complex_2 (&c);
1488 
1489   graph_t graph (c.object_graph ());
1490   graph.sort_shortest_distance ();
1491   assert (!graph.in_error ());
1492 
1493   assert(strncmp (graph.object (4).head, "abc", 3) == 0);
1494   assert(graph.object (4).real_links.length == 3);
1495   assert(graph.object (4).real_links[0].objidx == 2);
1496   assert(graph.object (4).real_links[1].objidx == 0);
1497   assert(graph.object (4).real_links[2].objidx == 3);
1498 
1499   assert(strncmp (graph.object (3).head, "mn", 2) == 0);
1500   assert(graph.object (3).real_links.length == 0);
1501 
1502   assert(strncmp (graph.object (2).head, "def", 3) == 0);
1503   assert(graph.object (2).real_links.length == 1);
1504   assert(graph.object (2).real_links[0].objidx == 1);
1505 
1506   assert(strncmp (graph.object (1).head, "ghi", 3) == 0);
1507   assert(graph.object (1).real_links.length == 1);
1508   assert(graph.object (1).real_links[0].objidx == 0);
1509 
1510   assert(strncmp (graph.object (0).head, "jkl", 3) == 0);
1511   assert(graph.object (0).real_links.length == 0);
1512 
1513   free (buffer);
1514 }
1515 
test_duplicate_leaf()1516 static void test_duplicate_leaf ()
1517 {
1518   size_t buffer_size = 100;
1519   void* buffer = malloc (buffer_size);
1520   hb_serialize_context_t c (buffer, buffer_size);
1521   populate_serializer_complex_2 (&c);
1522 
1523   graph_t graph (c.object_graph ());
1524   graph.duplicate (4, 1);
1525 
1526   assert(strncmp (graph.object (5).head, "abc", 3) == 0);
1527   assert(graph.object (5).real_links.length == 3);
1528   assert(graph.object (5).real_links[0].objidx == 3);
1529   assert(graph.object (5).real_links[1].objidx == 4);
1530   assert(graph.object (5).real_links[2].objidx == 0);
1531 
1532   assert(strncmp (graph.object (4).head, "jkl", 3) == 0);
1533   assert(graph.object (4).real_links.length == 0);
1534 
1535   assert(strncmp (graph.object (3).head, "def", 3) == 0);
1536   assert(graph.object (3).real_links.length == 1);
1537   assert(graph.object (3).real_links[0].objidx == 2);
1538 
1539   assert(strncmp (graph.object (2).head, "ghi", 3) == 0);
1540   assert(graph.object (2).real_links.length == 1);
1541   assert(graph.object (2).real_links[0].objidx == 1);
1542 
1543   assert(strncmp (graph.object (1).head, "jkl", 3) == 0);
1544   assert(graph.object (1).real_links.length == 0);
1545 
1546   assert(strncmp (graph.object (0).head, "mn", 2) == 0);
1547   assert(graph.object (0).real_links.length == 0);
1548 
1549   free (buffer);
1550 }
1551 
test_duplicate_interior()1552 static void test_duplicate_interior ()
1553 {
1554   size_t buffer_size = 100;
1555   void* buffer = malloc (buffer_size);
1556   hb_serialize_context_t c (buffer, buffer_size);
1557   populate_serializer_complex_3 (&c);
1558 
1559   graph_t graph (c.object_graph ());
1560   graph.duplicate (3, 2);
1561 
1562   assert(strncmp (graph.object (6).head, "abc", 3) == 0);
1563   assert(graph.object (6).real_links.length == 3);
1564   assert(graph.object (6).real_links[0].objidx == 4);
1565   assert(graph.object (6).real_links[1].objidx == 2);
1566   assert(graph.object (6).real_links[2].objidx == 1);
1567 
1568   assert(strncmp (graph.object (5).head, "jkl", 3) == 0);
1569   assert(graph.object (5).real_links.length == 1);
1570   assert(graph.object (5).real_links[0].objidx == 0);
1571 
1572   assert(strncmp (graph.object (4).head, "def", 3) == 0);
1573   assert(graph.object (4).real_links.length == 1);
1574   assert(graph.object (4).real_links[0].objidx == 3);
1575 
1576   assert(strncmp (graph.object (3).head, "ghi", 3) == 0);
1577   assert(graph.object (3).real_links.length == 1);
1578   assert(graph.object (3).real_links[0].objidx == 5);
1579 
1580   assert(strncmp (graph.object (2).head, "jkl", 3) == 0);
1581   assert(graph.object (2).real_links.length == 1);
1582   assert(graph.object (2).real_links[0].objidx == 0);
1583 
1584   assert(strncmp (graph.object (1).head, "mn", 2) == 0);
1585   assert(graph.object (1).real_links.length == 0);
1586 
1587   assert(strncmp (graph.object (0).head, "opqrst", 6) == 0);
1588   assert(graph.object (0).real_links.length == 0);
1589 
1590   free (buffer);
1591 }
1592 
1593 static void
test_serialize()1594 test_serialize ()
1595 {
1596   size_t buffer_size = 100;
1597   void* buffer_1 = malloc (buffer_size);
1598   hb_serialize_context_t c1 (buffer_1, buffer_size);
1599   populate_serializer_simple (&c1);
1600   hb_bytes_t expected = c1.copy_bytes ();
1601 
1602   graph_t graph (c1.object_graph ());
1603   hb_blob_t* out = graph::serialize (graph);
1604   free (buffer_1);
1605 
1606   hb_bytes_t actual = out->as_bytes ();
1607   assert (actual == expected);
1608   expected.fini ();
1609   hb_blob_destroy (out);
1610 }
1611 
test_will_overflow_1()1612 static void test_will_overflow_1 ()
1613 {
1614   size_t buffer_size = 100;
1615   void* buffer = malloc (buffer_size);
1616   hb_serialize_context_t c (buffer, buffer_size);
1617   populate_serializer_complex_2 (&c);
1618   graph_t graph (c.object_graph ());
1619 
1620   assert (!graph::will_overflow (graph, nullptr));
1621 
1622   free (buffer);
1623 }
1624 
test_will_overflow_2()1625 static void test_will_overflow_2 ()
1626 {
1627   size_t buffer_size = 160000;
1628   void* buffer = malloc (buffer_size);
1629   hb_serialize_context_t c (buffer, buffer_size);
1630   populate_serializer_with_overflow (&c);
1631   graph_t graph (c.object_graph ());
1632 
1633   assert (graph::will_overflow (graph, nullptr));
1634 
1635   free (buffer);
1636 }
1637 
test_will_overflow_3()1638 static void test_will_overflow_3 ()
1639 {
1640   size_t buffer_size = 160000;
1641   void* buffer = malloc (buffer_size);
1642   hb_serialize_context_t c (buffer, buffer_size);
1643   populate_serializer_with_dedup_overflow (&c);
1644   graph_t graph (c.object_graph ());
1645 
1646   assert (graph::will_overflow (graph, nullptr));
1647 
1648   free (buffer);
1649 }
1650 
test_resolve_overflows_via_sort()1651 static void test_resolve_overflows_via_sort ()
1652 {
1653   size_t buffer_size = 160000;
1654   void* buffer = malloc (buffer_size);
1655   hb_serialize_context_t c (buffer, buffer_size);
1656   populate_serializer_with_overflow (&c);
1657   graph_t graph (c.object_graph ());
1658 
1659   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE);
1660   assert (out);
1661   hb_bytes_t result = out->as_bytes ();
1662   assert (result.length == (80000 + 3 + 3 * 2));
1663 
1664   free (buffer);
1665   hb_blob_destroy (out);
1666 }
1667 
test_resolve_overflows_via_duplication()1668 static void test_resolve_overflows_via_duplication ()
1669 {
1670   size_t buffer_size = 160000;
1671   void* buffer = malloc (buffer_size);
1672   hb_serialize_context_t c (buffer, buffer_size);
1673   populate_serializer_with_dedup_overflow (&c);
1674   graph_t graph (c.object_graph ());
1675 
1676   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE);
1677   assert (out);
1678   hb_bytes_t result = out->as_bytes ();
1679   assert (result.length == (10000 + 2 * 2 + 60000 + 2 + 3 * 2));
1680 
1681   free (buffer);
1682   hb_blob_destroy (out);
1683 }
1684 
test_resolve_overflows_via_space_assignment()1685 static void test_resolve_overflows_via_space_assignment ()
1686 {
1687   size_t buffer_size = 160000;
1688   void* buffer = malloc (buffer_size);
1689   hb_serialize_context_t c (buffer, buffer_size);
1690   populate_serializer_spaces (&c, true);
1691 
1692   void* expected_buffer = malloc (buffer_size);
1693   hb_serialize_context_t e (expected_buffer, buffer_size);
1694   populate_serializer_spaces (&e, false);
1695 
1696   run_resolve_overflow_test ("test_resolve_overflows_via_space_assignment",
1697                              c,
1698                              e);
1699 
1700   free (buffer);
1701   free (expected_buffer);
1702 }
1703 
test_resolve_overflows_via_isolation()1704 static void test_resolve_overflows_via_isolation ()
1705 {
1706   size_t buffer_size = 160000;
1707   void* buffer = malloc (buffer_size);
1708   hb_serialize_context_t c (buffer, buffer_size);
1709   populate_serializer_with_isolation_overflow (&c);
1710   graph_t graph (c.object_graph ());
1711 
1712   assert (c.offset_overflow ());
1713   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0);
1714   assert (out);
1715   hb_bytes_t result = out->as_bytes ();
1716   assert (result.length == (1 + 10000 + 60000 + 1 + 1
1717                             + 4 + 3 * 2));
1718 
1719   free (buffer);
1720   hb_blob_destroy (out);
1721 }
1722 
test_resolve_overflows_via_isolation_with_recursive_duplication()1723 static void test_resolve_overflows_via_isolation_with_recursive_duplication ()
1724 {
1725   size_t buffer_size = 160000;
1726   void* buffer = malloc (buffer_size);
1727   hb_serialize_context_t c (buffer, buffer_size);
1728   populate_serializer_with_isolation_overflow_complex (&c);
1729 
1730   void* expected_buffer = malloc (buffer_size);
1731   hb_serialize_context_t e (expected_buffer, buffer_size);
1732   populate_serializer_with_isolation_overflow_complex_expected (&e);
1733 
1734   run_resolve_overflow_test ("test_resolve_overflows_via_isolation_with_recursive_duplication",
1735                              c,
1736                              e);
1737   free (buffer);
1738   free (expected_buffer);
1739 }
1740 
test_resolve_overflows_via_isolating_16bit_space()1741 static void test_resolve_overflows_via_isolating_16bit_space ()
1742 {
1743   size_t buffer_size = 160000;
1744   void* buffer = malloc (buffer_size);
1745   hb_serialize_context_t c (buffer, buffer_size);
1746   populate_serializer_spaces_16bit_connection (&c);
1747 
1748   void* expected_buffer = malloc (buffer_size);
1749   hb_serialize_context_t e (expected_buffer, buffer_size);
1750   populate_serializer_spaces_16bit_connection_expected (&e);
1751 
1752   run_resolve_overflow_test ("test_resolve_overflows_via_isolating_16bit_space",
1753                              c,
1754                              e);
1755 
1756   free (buffer);
1757   free (expected_buffer);
1758 }
1759 
test_resolve_overflows_via_isolating_16bit_space_2()1760 static void test_resolve_overflows_via_isolating_16bit_space_2 ()
1761 {
1762   size_t buffer_size = 160000;
1763   void* buffer = malloc (buffer_size);
1764   hb_serialize_context_t c (buffer, buffer_size);
1765   populate_serializer_short_and_wide_subgraph_root (&c);
1766 
1767   void* expected_buffer = malloc (buffer_size);
1768   hb_serialize_context_t e (expected_buffer, buffer_size);
1769   populate_serializer_short_and_wide_subgraph_root_expected (&e);
1770 
1771   run_resolve_overflow_test ("test_resolve_overflows_via_isolating_16bit_space_2",
1772                              c,
1773                              e);
1774 
1775   free (buffer);
1776   free (expected_buffer);
1777 }
1778 
test_resolve_overflows_via_isolation_spaces()1779 static void test_resolve_overflows_via_isolation_spaces ()
1780 {
1781   size_t buffer_size = 160000;
1782   void* buffer = malloc (buffer_size);
1783   hb_serialize_context_t c (buffer, buffer_size);
1784   populate_serializer_with_isolation_overflow_spaces (&c);
1785   graph_t graph (c.object_graph ());
1786 
1787   assert (c.offset_overflow ());
1788   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0);
1789   assert (out);
1790   hb_bytes_t result = out->as_bytes ();
1791 
1792   unsigned expected_length = 3 + 2 * 60000; // objects
1793   expected_length += 2 * 4 + 2 * 2; // links
1794   assert (result.length == expected_length);
1795 
1796   free (buffer);
1797   hb_blob_destroy (out);
1798 }
1799 
test_resolve_mixed_overflows_via_isolation_spaces()1800 static void test_resolve_mixed_overflows_via_isolation_spaces ()
1801 {
1802   size_t buffer_size = 200000;
1803   void* buffer = malloc (buffer_size);
1804   hb_serialize_context_t c (buffer, buffer_size);
1805   populate_serializer_with_24_and_32_bit_offsets (&c);
1806   graph_t graph (c.object_graph ());
1807 
1808   assert (c.offset_overflow ());
1809   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0);
1810   assert (out);
1811   hb_bytes_t result = out->as_bytes ();
1812 
1813   unsigned expected_length =
1814       // Objects
1815       7 +
1816       4 * 40000;
1817 
1818   expected_length +=
1819       // Links
1820       2 * 4 +  // 32
1821       4 * 3 +  // 24
1822       4 * 2;   // 16
1823 
1824   assert (result.length == expected_length);
1825 
1826   free (buffer);
1827   hb_blob_destroy (out);
1828 }
1829 
test_resolve_with_extension_promotion()1830 static void test_resolve_with_extension_promotion ()
1831 {
1832   size_t buffer_size = 200000;
1833   void* buffer = malloc (buffer_size);
1834   assert (buffer);
1835   hb_serialize_context_t c (buffer, buffer_size);
1836   populate_serializer_with_extension_promotion (&c);
1837 
1838   void* expected_buffer = malloc (buffer_size);
1839   assert (expected_buffer);
1840   hb_serialize_context_t e (expected_buffer, buffer_size);
1841   populate_serializer_with_extension_promotion (&e, 3);
1842 
1843   run_resolve_overflow_test ("test_resolve_with_extension_promotion",
1844                              c,
1845                              e,
1846                              20,
1847                              true);
1848   free (buffer);
1849   free (expected_buffer);
1850 }
1851 
test_resolve_with_shared_extension_promotion()1852 static void test_resolve_with_shared_extension_promotion ()
1853 {
1854   size_t buffer_size = 200000;
1855   void* buffer = malloc (buffer_size);
1856   assert (buffer);
1857   hb_serialize_context_t c (buffer, buffer_size);
1858   populate_serializer_with_extension_promotion (&c, 0, true);
1859 
1860   void* expected_buffer = malloc (buffer_size);
1861   assert (expected_buffer);
1862   hb_serialize_context_t e (expected_buffer, buffer_size);
1863   populate_serializer_with_extension_promotion (&e, 3, true);
1864 
1865   run_resolve_overflow_test ("test_resolve_with_extension_promotion",
1866                              c,
1867                              e,
1868                              20,
1869                              true);
1870   free (buffer);
1871   free (expected_buffer);
1872 }
1873 
test_resolve_with_basic_pair_pos_1_split()1874 static void test_resolve_with_basic_pair_pos_1_split ()
1875 {
1876   size_t buffer_size = 200000;
1877   void* buffer = malloc (buffer_size);
1878   assert (buffer);
1879   hb_serialize_context_t c (buffer, buffer_size);
1880   populate_serializer_with_large_pair_pos_1 <1, 4>(&c);
1881 
1882   void* expected_buffer = malloc (buffer_size);
1883   assert (expected_buffer);
1884   hb_serialize_context_t e (expected_buffer, buffer_size);
1885   populate_serializer_with_large_pair_pos_1 <2, 2>(&e, true);
1886 
1887   run_resolve_overflow_test ("test_resolve_with_basic_pair_pos_1_split",
1888                              c,
1889                              e,
1890                              20,
1891                              true,
1892                              HB_TAG('G', 'P', 'O', 'S'));
1893   free (buffer);
1894   free (expected_buffer);
1895 }
1896 
test_resolve_with_extension_pair_pos_1_split()1897 static void test_resolve_with_extension_pair_pos_1_split ()
1898 {
1899   size_t buffer_size = 200000;
1900   void* buffer = malloc (buffer_size);
1901   assert (buffer);
1902   hb_serialize_context_t c (buffer, buffer_size);
1903   populate_serializer_with_large_pair_pos_1 <1, 4>(&c, true);
1904 
1905   void* expected_buffer = malloc (buffer_size);
1906   assert (expected_buffer);
1907   hb_serialize_context_t e (expected_buffer, buffer_size);
1908   populate_serializer_with_large_pair_pos_1 <2, 2>(&e, true);
1909 
1910   run_resolve_overflow_test ("test_resolve_with_extension_pair_pos_1_split",
1911                              c,
1912                              e,
1913                              20,
1914                              true,
1915                              HB_TAG('G', 'P', 'O', 'S'));
1916   free (buffer);
1917   free (expected_buffer);
1918 }
1919 
test_resolve_with_basic_pair_pos_2_split()1920 static void test_resolve_with_basic_pair_pos_2_split ()
1921 {
1922   size_t buffer_size = 300000;
1923   void* buffer = malloc (buffer_size);
1924   assert (buffer);
1925   hb_serialize_context_t c (buffer, buffer_size);
1926   populate_serializer_with_large_pair_pos_2 <1, 4, 3000>(&c);
1927 
1928   void* expected_buffer = malloc (buffer_size);
1929   assert (expected_buffer);
1930   hb_serialize_context_t e (expected_buffer, buffer_size);
1931   populate_serializer_with_large_pair_pos_2 <2, 2, 3000>(&e, true);
1932 
1933   run_resolve_overflow_test ("test_resolve_with_basic_pair_pos_2_split",
1934                              c,
1935                              e,
1936                              20,
1937                              true,
1938                              HB_TAG('G', 'P', 'O', 'S'));
1939   free (buffer);
1940   free (expected_buffer);
1941 }
1942 
test_resolve_with_close_to_limit_pair_pos_2_split()1943 static void test_resolve_with_close_to_limit_pair_pos_2_split ()
1944 {
1945   size_t buffer_size = 300000;
1946   void* buffer = malloc (buffer_size);
1947   assert (buffer);
1948   hb_serialize_context_t c (buffer, buffer_size);
1949   populate_serializer_with_large_pair_pos_2 <1, 1596, 10>(&c, true, false, false);
1950 
1951   void* expected_buffer = malloc (buffer_size);
1952   assert (expected_buffer);
1953   hb_serialize_context_t e (expected_buffer, buffer_size);
1954   populate_serializer_with_large_pair_pos_2 <2, 798, 10>(&e, true, false, false);
1955 
1956   run_resolve_overflow_test ("test_resolve_with_close_to_limit_pair_pos_2_split",
1957                              c,
1958                              e,
1959                              20,
1960                              true,
1961                              HB_TAG('G', 'P', 'O', 'S'));
1962   free (buffer);
1963   free (expected_buffer);
1964 }
1965 
test_resolve_with_pair_pos_2_split_with_device_tables()1966 static void test_resolve_with_pair_pos_2_split_with_device_tables ()
1967 {
1968   size_t buffer_size = 300000;
1969   void* buffer = malloc (buffer_size);
1970   assert (buffer);
1971   hb_serialize_context_t c (buffer, buffer_size);
1972   populate_serializer_with_large_pair_pos_2 <1, 4, 2000>(&c, false, true);
1973 
1974   void* expected_buffer = malloc (buffer_size);
1975   assert (expected_buffer);
1976   hb_serialize_context_t e (expected_buffer, buffer_size);
1977   populate_serializer_with_large_pair_pos_2 <2, 2, 2000>(&e, true, true);
1978 
1979   run_resolve_overflow_test ("test_resolve_with_pair_pos_2_split_with_device_tables",
1980                              c,
1981                              e,
1982                              20,
1983                              true,
1984                              HB_TAG('G', 'P', 'O', 'S'));
1985   free (buffer);
1986   free (expected_buffer);
1987 }
1988 
test_resolve_with_basic_mark_base_pos_1_split()1989 static void test_resolve_with_basic_mark_base_pos_1_split ()
1990 {
1991   size_t buffer_size = 200000;
1992   void* buffer = malloc (buffer_size);
1993   assert (buffer);
1994   hb_serialize_context_t c (buffer, buffer_size);
1995   populate_serializer_with_large_mark_base_pos_1 <40, 10, 110, 1>(&c);
1996 
1997   void* expected_buffer = malloc (buffer_size);
1998   assert (expected_buffer);
1999   hb_serialize_context_t e (expected_buffer, buffer_size);
2000   populate_serializer_with_large_mark_base_pos_1 <40, 10, 110, 2>(&e);
2001 
2002   run_resolve_overflow_test ("test_resolve_with_basic_mark_base_pos_1_split",
2003                              c,
2004                              e,
2005                              20,
2006                              true,
2007                              HB_TAG('G', 'P', 'O', 'S'));
2008   free (buffer);
2009   free (expected_buffer);
2010 }
2011 
test_resolve_overflows_via_splitting_spaces()2012 static void test_resolve_overflows_via_splitting_spaces ()
2013 {
2014   size_t buffer_size = 160000;
2015   void* buffer = malloc (buffer_size);
2016   hb_serialize_context_t c (buffer, buffer_size);
2017   populate_serializer_with_split_spaces (&c);
2018 
2019   void* expected_buffer = malloc (buffer_size);
2020   hb_serialize_context_t e (expected_buffer, buffer_size);
2021   populate_serializer_with_split_spaces_expected (&e);
2022 
2023   run_resolve_overflow_test ("test_resolve_overflows_via_splitting_spaces",
2024                              c,
2025                              e,
2026                              1);
2027 
2028   free (buffer);
2029   free (expected_buffer);
2030 
2031 }
2032 
test_resolve_overflows_via_splitting_spaces_2()2033 static void test_resolve_overflows_via_splitting_spaces_2 ()
2034 {
2035   size_t buffer_size = 160000;
2036   void* buffer = malloc (buffer_size);
2037   hb_serialize_context_t c (buffer, buffer_size);
2038   populate_serializer_with_split_spaces_2 (&c);
2039 
2040   void* expected_buffer = malloc (buffer_size);
2041   hb_serialize_context_t e (expected_buffer, buffer_size);
2042   populate_serializer_with_split_spaces_expected_2 (&e);
2043 
2044   run_resolve_overflow_test ("test_resolve_overflows_via_splitting_spaces_2",
2045                              c,
2046                              e,
2047                              1);
2048   free (buffer);
2049   free (expected_buffer);
2050 }
2051 
test_resolve_overflows_via_priority()2052 static void test_resolve_overflows_via_priority ()
2053 {
2054   size_t buffer_size = 160000;
2055   void* buffer = malloc (buffer_size);
2056   hb_serialize_context_t c (buffer, buffer_size);
2057   populate_serializer_with_priority_overflow (&c);
2058 
2059   void* expected_buffer = malloc (buffer_size);
2060   hb_serialize_context_t e (expected_buffer, buffer_size);
2061   populate_serializer_with_priority_overflow_expected (&e);
2062 
2063   run_resolve_overflow_test ("test_resolve_overflows_via_priority",
2064                              c,
2065                              e,
2066                              3);
2067   free (buffer);
2068   free (expected_buffer);
2069 }
2070 
2071 
test_virtual_link()2072 static void test_virtual_link ()
2073 {
2074   size_t buffer_size = 100;
2075   void* buffer = malloc (buffer_size);
2076   hb_serialize_context_t c (buffer, buffer_size);
2077   populate_serializer_virtual_link (&c);
2078 
2079   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE);
2080   assert (out);
2081 
2082   hb_bytes_t result = out->as_bytes ();
2083   assert (result.length == 5 + 4 * 2);
2084   assert (result[0]  == 'a');
2085   assert (result[5]  == 'c');
2086   assert (result[8]  == 'e');
2087   assert (result[9]  == 'b');
2088   assert (result[12] == 'd');
2089 
2090   free (buffer);
2091   hb_blob_destroy (out);
2092 }
2093 
2094 static void
test_shared_node_with_virtual_links()2095 test_shared_node_with_virtual_links ()
2096 {
2097   size_t buffer_size = 100;
2098   void* buffer = malloc (buffer_size);
2099   hb_serialize_context_t c (buffer, buffer_size);
2100 
2101   c.start_serialize<char> ();
2102 
2103   unsigned obj_b = add_object ("b", 1, &c);
2104   unsigned obj_c = add_object ("c", 1, &c);
2105 
2106   start_object ("d", 1, &c);
2107   add_virtual_offset (obj_b, &c);
2108   unsigned obj_d_1 = c.pop_pack ();
2109 
2110   start_object ("d", 1, &c);
2111   add_virtual_offset (obj_c, &c);
2112   unsigned obj_d_2 = c.pop_pack ();
2113 
2114   assert (obj_d_1 == obj_d_2);
2115 
2116   start_object ("a", 1, &c);
2117   add_offset (obj_b, &c);
2118   add_offset (obj_c, &c);
2119   add_offset (obj_d_1, &c);
2120   add_offset (obj_d_2, &c);
2121   c.pop_pack ();
2122   c.end_serialize ();
2123 
2124   assert(c.object_graph() [obj_d_1]->virtual_links.length == 2);
2125   assert(c.object_graph() [obj_d_1]->virtual_links[0].objidx == obj_b);
2126   assert(c.object_graph() [obj_d_1]->virtual_links[1].objidx == obj_c);
2127   free(buffer);
2128 }
2129 
2130 
2131 // TODO(garretrieger): update will_overflow tests to check the overflows array.
2132 // TODO(garretrieger): add tests for priority raising.
2133 
2134 int
main(int argc,char ** argv)2135 main (int argc, char **argv)
2136 {
2137   test_serialize ();
2138   test_sort_shortest ();
2139   test_will_overflow_1 ();
2140   test_will_overflow_2 ();
2141   test_will_overflow_3 ();
2142   test_resolve_overflows_via_sort ();
2143   test_resolve_overflows_via_duplication ();
2144   test_resolve_overflows_via_priority ();
2145   test_resolve_overflows_via_space_assignment ();
2146   test_resolve_overflows_via_isolation ();
2147   test_resolve_overflows_via_isolation_with_recursive_duplication ();
2148   test_resolve_overflows_via_isolation_spaces ();
2149   test_resolve_overflows_via_isolating_16bit_space ();
2150   test_resolve_overflows_via_isolating_16bit_space_2 ();
2151   test_resolve_overflows_via_splitting_spaces ();
2152   test_resolve_overflows_via_splitting_spaces_2 ();
2153   test_resolve_mixed_overflows_via_isolation_spaces ();
2154   test_duplicate_leaf ();
2155   test_duplicate_interior ();
2156   test_virtual_link ();
2157   test_shared_node_with_virtual_links ();
2158   test_resolve_with_extension_promotion ();
2159   test_resolve_with_shared_extension_promotion ();
2160   test_resolve_with_basic_pair_pos_1_split ();
2161   test_resolve_with_extension_pair_pos_1_split ();
2162   test_resolve_with_basic_pair_pos_2_split ();
2163   test_resolve_with_pair_pos_2_split_with_device_tables ();
2164   test_resolve_with_close_to_limit_pair_pos_2_split ();
2165   test_resolve_with_basic_mark_base_pos_1_split ();
2166 
2167   // TODO(grieger): have run overflow tests compare graph equality not final packed binary.
2168   // TODO(grieger): split test where multiple subtables in one lookup are split to test link ordering.
2169   // TODO(grieger): split test where coverage table in subtable that is being split is shared.
2170   // TODO(grieger): test with extensions already mixed in as well.
2171   // TODO(grieger): test two layer ext promotion setup.
2172   // TODO(grieger): test sorting by subtables per byte in ext. promotion.
2173 }
2174