xref: /aosp_15_r20/external/harfbuzz_ng/src/test-repacker.cc (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
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 
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'),bool check_binary_equivalence=false)436 static void run_resolve_overflow_test (const char* name,
437                                        hb_serialize_context_t& overflowing,
438                                        hb_serialize_context_t& expected,
439                                        unsigned num_iterations = 0,
440                                        bool recalculate_extensions = false,
441                                        hb_tag_t tag = HB_TAG ('G', 'S', 'U', 'B'),
442                                        bool check_binary_equivalence = false)
443 {
444   printf (">>> Testing overflowing resolution for %s\n",
445           name);
446 
447   graph_t graph (overflowing.object_graph ());
448 
449   graph_t expected_graph (expected.object_graph ());
450   if (graph::will_overflow (expected_graph))
451   {
452     if (check_binary_equivalence) {
453       printf("when binary equivalence checking is enabled, the expected graph cannot overflow.");
454       assert(!check_binary_equivalence);
455     }
456     expected_graph.assign_spaces ();
457     expected_graph.sort_shortest_distance ();
458   }
459 
460   // Check that overflow resolution succeeds
461   assert (overflowing.offset_overflow ());
462   assert (hb_resolve_graph_overflows (tag,
463                                       num_iterations,
464                                       recalculate_extensions,
465                                       graph));
466 
467   // Check the graphs can be serialized.
468   hb_blob_t* out1 = graph::serialize (graph);
469   assert (out1);
470   hb_blob_t* out2 = graph::serialize (expected_graph);
471   assert (out2);
472   if (check_binary_equivalence) {
473     unsigned l1, l2;
474     const char* d1 = hb_blob_get_data(out1, &l1);
475     const char* d2 = hb_blob_get_data(out2, &l2);
476 
477     bool match = (l1 == l2) && (memcmp(d1, d2, l1) == 0);
478     if (!match) {
479       printf("## Result:\n");
480       graph.print();
481       printf("## Expected:\n");
482       expected_graph.print();
483       assert(match);
484     }
485   }
486 
487   hb_blob_destroy (out1);
488   hb_blob_destroy (out2);
489 
490   // Check the graphs are equivalent
491   graph.normalize ();
492   expected_graph.normalize ();
493   if (!(graph == expected_graph)) {
494     printf("## Expected:\n");
495     expected_graph.print();
496     printf("## Result:\n");
497     graph.print();
498   }
499   assert (graph == expected_graph);
500 }
501 
add_virtual_offset(unsigned id,hb_serialize_context_t * c)502 static void add_virtual_offset (unsigned id,
503                                 hb_serialize_context_t* c)
504 {
505   c->add_virtual_link (id);
506 }
507 
508 static void
populate_serializer_simple(hb_serialize_context_t * c)509 populate_serializer_simple (hb_serialize_context_t* c)
510 {
511   c->start_serialize<char> ();
512 
513   unsigned obj_1 = add_object ("ghi", 3, c);
514   unsigned obj_2 = add_object ("def", 3, c);
515 
516   start_object ("abc", 3, c);
517   add_offset (obj_2, c);
518   add_offset (obj_1, c);
519   c->pop_pack (false);
520 
521   c->end_serialize();
522 }
523 
524 static void
populate_serializer_with_overflow(hb_serialize_context_t * c)525 populate_serializer_with_overflow (hb_serialize_context_t* c)
526 {
527   std::string large_string(50000, 'a');
528   c->start_serialize<char> ();
529 
530   unsigned obj_1 = add_object (large_string.c_str(), 10000, c);
531   unsigned obj_2 = add_object (large_string.c_str(), 20000, c);
532   unsigned obj_3 = add_object (large_string.c_str(), 50000, c);
533 
534   start_object ("abc", 3, c);
535   add_offset (obj_3, c);
536   add_offset (obj_2, c);
537   add_offset (obj_1, c);
538   c->pop_pack (false);
539 
540   c->end_serialize();
541 }
542 
543 static void
populate_serializer_with_priority_overflow(hb_serialize_context_t * c)544 populate_serializer_with_priority_overflow (hb_serialize_context_t* c)
545 {
546   std::string large_string(50000, 'a');
547   c->start_serialize<char> ();
548 
549   unsigned obj_e = add_object ("e", 1, c);
550   unsigned obj_d = add_object ("d", 1, c);
551 
552   start_object (large_string.c_str (), 50000, c);
553   add_offset (obj_e, c);
554   unsigned obj_c = c->pop_pack (false);
555 
556   start_object (large_string.c_str (), 20000, c);
557   add_offset (obj_d, c);
558   unsigned obj_b = c->pop_pack (false);
559 
560   start_object ("a", 1, c);
561   add_offset (obj_b, c);
562   add_offset (obj_c, c);
563   c->pop_pack (false);
564 
565   c->end_serialize();
566 }
567 
568 static void
populate_serializer_with_priority_overflow_expected(hb_serialize_context_t * c)569 populate_serializer_with_priority_overflow_expected (hb_serialize_context_t* c)
570 {
571   std::string large_string(50000, 'a');
572   c->start_serialize<char> ();
573 
574   unsigned obj_e = add_object ("e", 1, c);
575 
576   start_object (large_string.c_str (), 50000, c);
577   add_offset (obj_e, c);
578   unsigned obj_c = c->pop_pack (false);
579 
580   unsigned obj_d = add_object ("d", 1, c);
581 
582   start_object (large_string.c_str (), 20000, c);
583   add_offset (obj_d, c);
584   unsigned obj_b = c->pop_pack (false);
585 
586   start_object ("a", 1, c);
587   add_offset (obj_b, c);
588   add_offset (obj_c, c);
589   c->pop_pack (false);
590 
591   c->end_serialize();
592 }
593 
594 
595 static void
populate_serializer_with_dedup_overflow(hb_serialize_context_t * c)596 populate_serializer_with_dedup_overflow (hb_serialize_context_t* c)
597 {
598   std::string large_string(70000, 'a');
599   c->start_serialize<char> ();
600 
601   unsigned obj_1 = add_object ("def", 3, c);
602 
603   start_object (large_string.c_str(), 60000, c);
604   add_offset (obj_1, c);
605   unsigned obj_2 = c->pop_pack (false);
606 
607   start_object (large_string.c_str(), 10000, c);
608   add_offset (obj_2, c);
609   add_offset (obj_1, c);
610   c->pop_pack (false);
611 
612   c->end_serialize();
613 }
614 
615 static void
populate_serializer_with_multiple_dedup_overflow(hb_serialize_context_t * c)616 populate_serializer_with_multiple_dedup_overflow (hb_serialize_context_t* c)
617 {
618   std::string large_string(70000, 'a');
619   c->start_serialize<char> ();
620 
621   unsigned leaf = add_object("def", 3, c);
622 
623   constexpr unsigned num_mid_nodes = 20;
624   unsigned mid_nodes[num_mid_nodes];
625   for (unsigned i = 0; i < num_mid_nodes; i++) {
626     start_object(large_string.c_str(), 10000 + i, c);
627     add_offset(leaf, c);
628     mid_nodes[i] = c->pop_pack(false);
629   }
630 
631   start_object("abc", 3, c);
632   for (unsigned i = 0; i < num_mid_nodes; i++) {
633     add_wide_offset(mid_nodes[i], c);
634   }
635   c->pop_pack(false);
636 
637   c->end_serialize();
638 }
639 
640 static void
populate_serializer_with_isolation_overflow(hb_serialize_context_t * c)641 populate_serializer_with_isolation_overflow (hb_serialize_context_t* c)
642 {
643   std::string large_string(70000, 'a');
644   c->start_serialize<char> ();
645 
646   unsigned obj_4 = add_object ("4", 1, c);
647 
648   start_object (large_string.c_str(), 60000, c);
649   add_offset (obj_4, c);
650   unsigned obj_3 = c->pop_pack (false);
651 
652   start_object (large_string.c_str(), 10000, c);
653   add_offset (obj_4, c);
654   unsigned obj_2 = c->pop_pack (false);
655 
656   start_object ("1", 1, c);
657   add_wide_offset (obj_3, c);
658   add_offset (obj_2, c);
659   c->pop_pack (false);
660 
661   c->end_serialize();
662 }
663 
664 static void
populate_serializer_with_isolation_overflow_complex(hb_serialize_context_t * c)665 populate_serializer_with_isolation_overflow_complex (hb_serialize_context_t* c)
666 {
667   std::string large_string(70000, 'a');
668   c->start_serialize<char> ();
669 
670   unsigned obj_f = add_object ("f", 1, c);
671 
672   start_object ("e", 1, c);
673   add_offset (obj_f, c);
674   unsigned obj_e = c->pop_pack (false);
675 
676   start_object ("c", 1, c);
677   add_offset (obj_e, c);
678   unsigned obj_c = c->pop_pack (false);
679 
680   start_object ("d", 1, c);
681   add_offset (obj_e, c);
682   unsigned obj_d = c->pop_pack (false);
683 
684   start_object (large_string.c_str(), 60000, c);
685   add_offset (obj_d, c);
686   unsigned obj_h = c->pop_pack (false);
687 
688   start_object (large_string.c_str(), 60000, c);
689   add_offset (obj_c, c);
690   add_offset (obj_h, c);
691   unsigned obj_b = c->pop_pack (false);
692 
693   start_object (large_string.c_str(), 10000, c);
694   add_offset (obj_d, c);
695   unsigned obj_g = c->pop_pack (false);
696 
697   start_object (large_string.c_str(), 11000, c);
698   add_offset (obj_d, c);
699   unsigned obj_i = c->pop_pack (false);
700 
701   start_object ("a", 1, c);
702   add_wide_offset (obj_b, c);
703   add_offset (obj_g, c);
704   add_offset (obj_i, c);
705   c->pop_pack (false);
706 
707   c->end_serialize();
708 }
709 
710 static void
populate_serializer_with_isolation_overflow_complex_expected(hb_serialize_context_t * c)711 populate_serializer_with_isolation_overflow_complex_expected (hb_serialize_context_t* c)
712 {
713   std::string large_string(70000, 'a');
714   c->start_serialize<char> ();
715 
716 
717   // space 1
718 
719   unsigned obj_f_prime = add_object ("f", 1, c);
720 
721   start_object ("e", 1, c);
722   add_offset (obj_f_prime, c);
723   unsigned obj_e_prime = c->pop_pack (false);
724 
725   start_object ("d", 1, c);
726   add_offset (obj_e_prime, c);
727   unsigned obj_d_prime = c->pop_pack (false);
728 
729   start_object (large_string.c_str(), 60000, c);
730   add_offset (obj_d_prime, c);
731   unsigned obj_h = c->pop_pack (false);
732 
733   start_object ("c", 1, c);
734   add_offset (obj_e_prime, c);
735   unsigned obj_c = c->pop_pack (false);
736 
737   start_object (large_string.c_str(), 60000, c);
738   add_offset (obj_c, c);
739   add_offset (obj_h, c);
740   unsigned obj_b = c->pop_pack (false);
741 
742   // space 0
743 
744   unsigned obj_f = add_object ("f", 1, c);
745 
746   start_object ("e", 1, c);
747   add_offset (obj_f, c);
748   unsigned obj_e = c->pop_pack (false);
749 
750 
751   start_object ("d", 1, c);
752   add_offset (obj_e, c);
753   unsigned obj_d = c->pop_pack (false);
754 
755   start_object (large_string.c_str(), 11000, c);
756   add_offset (obj_d, c);
757   unsigned obj_i = c->pop_pack (false);
758 
759   start_object (large_string.c_str(), 10000, c);
760   add_offset (obj_d, c);
761   unsigned obj_g = c->pop_pack (false);
762 
763   start_object ("a", 1, c);
764   add_wide_offset (obj_b, c);
765   add_offset (obj_g, c);
766   add_offset (obj_i, c);
767   c->pop_pack (false);
768 
769   c->end_serialize();
770 }
771 
772 static void
populate_serializer_with_isolation_overflow_spaces(hb_serialize_context_t * c)773 populate_serializer_with_isolation_overflow_spaces (hb_serialize_context_t* c)
774 {
775   std::string large_string(70000, 'a');
776   c->start_serialize<char> ();
777 
778   unsigned obj_d = add_object ("f", 1, c);
779   unsigned obj_e = add_object ("f", 1, c);
780 
781   start_object (large_string.c_str(), 60000, c);
782   add_offset (obj_d, c);
783   unsigned obj_b = c->pop_pack ();
784 
785   start_object (large_string.c_str(), 60000, c);
786   add_offset (obj_e, c);
787   unsigned obj_c = c->pop_pack ();
788 
789 
790   start_object ("a", 1, c);
791   add_wide_offset (obj_b, c);
792   add_wide_offset (obj_c, c);
793   c->pop_pack ();
794 
795   c->end_serialize();
796 }
797 
798 static void
populate_serializer_with_repack_last(hb_serialize_context_t * c,bool with_overflow)799 populate_serializer_with_repack_last (hb_serialize_context_t* c, bool with_overflow)
800 {
801   std::string large_string(70000, 'c');
802   c->start_serialize<char> ();
803   c->push();
804 
805   // Obj E
806   unsigned obj_e_1, obj_e_2;
807   if (with_overflow) {
808     obj_e_1 = add_object("a", 1, c);
809     obj_e_2 = obj_e_1;
810   } else {
811     obj_e_2 = add_object("a", 1, c);
812   }
813 
814   // Obj D
815   c->push();
816   add_offset(obj_e_2, c);
817   extend(large_string.c_str(), 30000, c);
818   unsigned obj_d = c->pop_pack(false);
819 
820   add_offset(obj_d, c);
821   assert(c->last_added_child_index() == obj_d);
822 
823   if (!with_overflow) {
824     obj_e_1 = add_object("a", 1, c);
825   }
826 
827   // Obj C
828   c->push();
829   add_offset(obj_e_1, c);
830   extend(large_string.c_str(), 40000, c);
831   unsigned obj_c = c->pop_pack(false);
832 
833   add_offset(obj_c, c);
834 
835   // Obj B
836   unsigned obj_b = add_object("b", 1, c);
837   add_offset(obj_b, c);
838 
839   // Obj A
840   c->repack_last(obj_d);
841   c->pop_pack(false);
842 
843   c->end_serialize();
844 }
845 
846 static void
populate_serializer_spaces(hb_serialize_context_t * c,bool with_overflow)847 populate_serializer_spaces (hb_serialize_context_t* c, bool with_overflow)
848 {
849   std::string large_string(70000, 'a');
850   c->start_serialize<char> ();
851 
852   unsigned obj_i;
853 
854   if (with_overflow)
855     obj_i = add_object ("i", 1, c);
856 
857   // Space 2
858   unsigned obj_h = add_object ("h", 1, c);
859 
860   start_object (large_string.c_str(), 30000, c);
861   add_offset (obj_h, c);
862   unsigned obj_e = c->pop_pack (false);
863 
864   start_object ("b", 1, c);
865   add_offset (obj_e, c);
866   unsigned obj_b = c->pop_pack (false);
867 
868   // Space 1
869   if (!with_overflow)
870     obj_i = add_object ("i", 1, c);
871 
872   start_object (large_string.c_str(), 30000, c);
873   add_offset (obj_i, c);
874   unsigned obj_g = c->pop_pack (false);
875 
876   start_object (large_string.c_str(), 30000, c);
877   add_offset (obj_i, c);
878   unsigned obj_f = c->pop_pack (false);
879 
880   start_object ("d", 1, c);
881   add_offset (obj_g, c);
882   unsigned obj_d = c->pop_pack (false);
883 
884   start_object ("c", 1, c);
885   add_offset (obj_f, c);
886   unsigned obj_c = c->pop_pack (false);
887 
888   start_object ("a", 1, c);
889   add_wide_offset (obj_b, c);
890   add_wide_offset (obj_c, c);
891   add_wide_offset (obj_d, c);
892   c->pop_pack (false);
893 
894   c->end_serialize();
895 }
896 
897 static void
populate_serializer_spaces_16bit_connection(hb_serialize_context_t * c)898 populate_serializer_spaces_16bit_connection (hb_serialize_context_t* c)
899 {
900   std::string large_string(70000, 'a');
901   c->start_serialize<char> ();
902 
903   unsigned obj_g = add_object ("g", 1, c);
904   unsigned obj_h = add_object ("h", 1, c);
905 
906   start_object (large_string.c_str (), 40000, c);
907   add_offset (obj_g, c);
908   unsigned obj_e = c->pop_pack (false);
909 
910   start_object (large_string.c_str (), 40000, c);
911   add_offset (obj_h, c);
912   unsigned obj_f = c->pop_pack (false);
913 
914   start_object ("c", 1, c);
915   add_offset (obj_e, c);
916   unsigned obj_c = c->pop_pack (false);
917 
918   start_object ("d", 1, c);
919   add_offset (obj_f, c);
920   unsigned obj_d = c->pop_pack (false);
921 
922   start_object ("b", 1, c);
923   add_offset (obj_e, c);
924   add_offset (obj_h, c);
925   unsigned obj_b = c->pop_pack (false);
926 
927   start_object ("a", 1, c);
928   add_offset (obj_b, c);
929   add_wide_offset (obj_c, c);
930   add_wide_offset (obj_d, c);
931   c->pop_pack (false);
932 
933   c->end_serialize();
934 }
935 
936 static void
populate_serializer_spaces_16bit_connection_expected(hb_serialize_context_t * c)937 populate_serializer_spaces_16bit_connection_expected (hb_serialize_context_t* c)
938 {
939   std::string large_string(70000, 'a');
940   c->start_serialize<char> ();
941 
942   unsigned obj_g_prime = add_object ("g", 1, c);
943 
944   start_object (large_string.c_str (), 40000, c);
945   add_offset (obj_g_prime, c);
946   unsigned obj_e_prime = c->pop_pack (false);
947 
948   start_object ("c", 1, c);
949   add_offset (obj_e_prime, c);
950   unsigned obj_c = c->pop_pack (false);
951 
952   unsigned obj_h_prime = add_object ("h", 1, c);
953 
954   start_object (large_string.c_str (), 40000, c);
955   add_offset (obj_h_prime, c);
956   unsigned obj_f = c->pop_pack (false);
957 
958   start_object ("d", 1, c);
959   add_offset (obj_f, c);
960   unsigned obj_d = c->pop_pack (false);
961 
962   unsigned obj_g = add_object ("g", 1, c);
963 
964   start_object (large_string.c_str (), 40000, c);
965   add_offset (obj_g, c);
966   unsigned obj_e = c->pop_pack (false);
967 
968   unsigned obj_h = add_object ("h", 1, c);
969 
970   start_object ("b", 1, c);
971   add_offset (obj_e, c);
972   add_offset (obj_h, c);
973   unsigned obj_b = c->pop_pack (false);
974 
975   start_object ("a", 1, c);
976   add_offset (obj_b, c);
977   add_wide_offset (obj_c, c);
978   add_wide_offset (obj_d, c);
979   c->pop_pack (false);
980 
981   c->end_serialize ();
982 }
983 
984 static void
populate_serializer_short_and_wide_subgraph_root(hb_serialize_context_t * c)985 populate_serializer_short_and_wide_subgraph_root (hb_serialize_context_t* c)
986 {
987   std::string large_string(70000, 'a');
988   c->start_serialize<char> ();
989 
990   unsigned obj_e = add_object ("e", 1, c);
991 
992   start_object (large_string.c_str (), 40000, c);
993   add_offset (obj_e, c);
994   unsigned obj_c = c->pop_pack (false);
995 
996   start_object (large_string.c_str (), 40000, c);
997   add_offset (obj_c, c);
998   unsigned obj_d = c->pop_pack (false);
999 
1000   start_object ("b", 1, c);
1001   add_offset (obj_c, c);
1002   add_offset (obj_e, c);
1003   unsigned obj_b = c->pop_pack (false);
1004 
1005   start_object ("a", 1, c);
1006   add_offset (obj_b, c);
1007   add_wide_offset (obj_c, c);
1008   add_wide_offset (obj_d, c);
1009   c->pop_pack (false);
1010 
1011   c->end_serialize();
1012 }
1013 
1014 static void
populate_serializer_short_and_wide_subgraph_root_expected(hb_serialize_context_t * c)1015 populate_serializer_short_and_wide_subgraph_root_expected (hb_serialize_context_t* c)
1016 {
1017   std::string large_string(70000, 'a');
1018   c->start_serialize<char> ();
1019 
1020   unsigned obj_e_prime = add_object ("e", 1, c);
1021 
1022   start_object (large_string.c_str (), 40000, c);
1023   add_offset (obj_e_prime, c);
1024   unsigned obj_c_prime = c->pop_pack (false);
1025 
1026   start_object (large_string.c_str (), 40000, c);
1027   add_offset (obj_c_prime, c);
1028   unsigned obj_d = c->pop_pack (false);
1029 
1030   unsigned obj_e = add_object ("e", 1, c);
1031 
1032   start_object (large_string.c_str (), 40000, c);
1033   add_offset (obj_e, c);
1034   unsigned obj_c = c->pop_pack (false);
1035 
1036 
1037   start_object ("b", 1, c);
1038   add_offset (obj_c, c);
1039   add_offset (obj_e, c);
1040   unsigned obj_b = c->pop_pack (false);
1041 
1042   start_object ("a", 1, c);
1043   add_offset (obj_b, c);
1044   add_wide_offset (obj_c_prime, c);
1045   add_wide_offset (obj_d, c);
1046   c->pop_pack (false);
1047 
1048   c->end_serialize();
1049 }
1050 
1051 static void
populate_serializer_with_split_spaces(hb_serialize_context_t * c)1052 populate_serializer_with_split_spaces (hb_serialize_context_t* c)
1053 {
1054   // Overflow needs to be resolved by splitting the single space
1055   std::string large_string(70000, 'a');
1056   c->start_serialize<char> ();
1057 
1058   unsigned obj_f = add_object ("f", 1, c);
1059 
1060   start_object (large_string.c_str(), 40000, c);
1061   add_offset (obj_f, c);
1062   unsigned obj_d = c->pop_pack (false);
1063 
1064   start_object (large_string.c_str(), 40000, c);
1065   add_offset (obj_f, c);
1066   unsigned obj_e = c->pop_pack (false);
1067 
1068   start_object ("b", 1, c);
1069   add_offset (obj_d, c);
1070   unsigned obj_b = c->pop_pack (false);
1071 
1072   start_object ("c", 1, c);
1073   add_offset (obj_e, c);
1074   unsigned obj_c = c->pop_pack (false);
1075 
1076   start_object ("a", 1, c);
1077   add_wide_offset (obj_b, c);
1078   add_wide_offset (obj_c, c);
1079   c->pop_pack (false);
1080 
1081   c->end_serialize();
1082 }
1083 
1084 static void
populate_serializer_with_split_spaces_2(hb_serialize_context_t * c)1085 populate_serializer_with_split_spaces_2 (hb_serialize_context_t* c)
1086 {
1087   // Overflow needs to be resolved by splitting the single space
1088   std::string large_string(70000, 'a');
1089   c->start_serialize<char> ();
1090 
1091   unsigned obj_f = add_object ("f", 1, c);
1092 
1093   start_object (large_string.c_str(), 40000, c);
1094   add_offset (obj_f, c);
1095   unsigned obj_d = c->pop_pack (false);
1096 
1097   start_object (large_string.c_str(), 40000, c);
1098   add_offset (obj_f, c);
1099   unsigned obj_e = c->pop_pack (false);
1100 
1101   start_object ("b", 1, c);
1102   add_offset (obj_d, c);
1103   unsigned obj_b = c->pop_pack (false);
1104 
1105   start_object ("c", 1, c);
1106   add_offset (obj_e, c);
1107   unsigned obj_c = c->pop_pack (false);
1108 
1109   start_object ("a", 1, c);
1110   add_offset (obj_b, c);
1111   add_wide_offset (obj_b, c);
1112   add_wide_offset (obj_c, c);
1113   c->pop_pack (false);
1114 
1115   c->end_serialize();
1116 }
1117 
1118 static void
populate_serializer_with_split_spaces_expected(hb_serialize_context_t * c)1119 populate_serializer_with_split_spaces_expected (hb_serialize_context_t* c)
1120 {
1121   // Overflow needs to be resolved by splitting the single space
1122 
1123   std::string large_string(70000, 'a');
1124   c->start_serialize<char> ();
1125 
1126   unsigned obj_f_prime = add_object ("f", 1, c);
1127 
1128   start_object (large_string.c_str(), 40000, c);
1129   add_offset (obj_f_prime, c);
1130   unsigned obj_d = c->pop_pack (false);
1131 
1132   start_object ("b", 1, c);
1133   add_offset (obj_d, c);
1134   unsigned obj_b = c->pop_pack (false);
1135 
1136   unsigned obj_f = add_object ("f", 1, c);
1137 
1138   start_object (large_string.c_str(), 40000, c);
1139   add_offset (obj_f, c);
1140   unsigned obj_e = c->pop_pack (false);
1141 
1142   start_object ("c", 1, c);
1143   add_offset (obj_e, c);
1144   unsigned obj_c = c->pop_pack (false);
1145 
1146   start_object ("a", 1, c);
1147   add_wide_offset (obj_b, c);
1148   add_wide_offset (obj_c, c);
1149   c->pop_pack (false);
1150 
1151   c->end_serialize();
1152 }
1153 
1154 static void
populate_serializer_with_split_spaces_expected_2(hb_serialize_context_t * c)1155 populate_serializer_with_split_spaces_expected_2 (hb_serialize_context_t* c)
1156 {
1157   // Overflow needs to be resolved by splitting the single space
1158 
1159   std::string large_string(70000, 'a');
1160   c->start_serialize<char> ();
1161 
1162   // Space 2
1163 
1164   unsigned obj_f_double_prime = add_object ("f", 1, c);
1165 
1166   start_object (large_string.c_str(), 40000, c);
1167   add_offset (obj_f_double_prime, c);
1168   unsigned obj_d_prime = c->pop_pack (false);
1169 
1170   start_object ("b", 1, c);
1171   add_offset (obj_d_prime, c);
1172   unsigned obj_b_prime = c->pop_pack (false);
1173 
1174   // Space 1
1175 
1176   unsigned obj_f_prime = add_object ("f", 1, c);
1177 
1178   start_object (large_string.c_str(), 40000, c);
1179   add_offset (obj_f_prime, c);
1180   unsigned obj_e = c->pop_pack (false);
1181 
1182   start_object ("c", 1, c);
1183   add_offset (obj_e, c);
1184   unsigned obj_c = c->pop_pack (false);
1185 
1186   // Space 0
1187 
1188   unsigned obj_f = add_object ("f", 1, c);
1189 
1190   start_object (large_string.c_str(), 40000, c);
1191   add_offset (obj_f, c);
1192   unsigned obj_d = c->pop_pack (false);
1193 
1194   start_object ("b", 1, c);
1195   add_offset (obj_d, c);
1196   unsigned obj_b = c->pop_pack (false);
1197 
1198   // Root
1199   start_object ("a", 1, c);
1200   add_offset (obj_b, c);
1201   add_wide_offset (obj_b_prime, c);
1202   add_wide_offset (obj_c, c);
1203   c->pop_pack (false);
1204 
1205   c->end_serialize();
1206 }
1207 
1208 static void
populate_serializer_complex_2(hb_serialize_context_t * c)1209 populate_serializer_complex_2 (hb_serialize_context_t* c)
1210 {
1211   c->start_serialize<char> ();
1212 
1213   unsigned obj_5 = add_object ("mn", 2, c);
1214 
1215   unsigned obj_4 = add_object ("jkl", 3, c);
1216 
1217   start_object ("ghi", 3, c);
1218   add_offset (obj_4, c);
1219   unsigned obj_3 = c->pop_pack (false);
1220 
1221   start_object ("def", 3, c);
1222   add_offset (obj_3, c);
1223   unsigned obj_2 = c->pop_pack (false);
1224 
1225   start_object ("abc", 3, c);
1226   add_offset (obj_2, c);
1227   add_offset (obj_4, c);
1228   add_offset (obj_5, c);
1229   c->pop_pack (false);
1230 
1231   c->end_serialize();
1232 }
1233 
1234 static void
populate_serializer_complex_3(hb_serialize_context_t * c)1235 populate_serializer_complex_3 (hb_serialize_context_t* c)
1236 {
1237   c->start_serialize<char> ();
1238 
1239   unsigned obj_6 = add_object ("opqrst", 6, c);
1240 
1241   unsigned obj_5 = add_object ("mn", 2, c);
1242 
1243   start_object ("jkl", 3, c);
1244   add_offset (obj_6, c);
1245   unsigned obj_4 = c->pop_pack (false);
1246 
1247   start_object ("ghi", 3, c);
1248   add_offset (obj_4, c);
1249   unsigned obj_3 = c->pop_pack (false);
1250 
1251   start_object ("def", 3, c);
1252   add_offset (obj_3, c);
1253   unsigned obj_2 = c->pop_pack (false);
1254 
1255   start_object ("abc", 3, c);
1256   add_offset (obj_2, c);
1257   add_offset (obj_4, c);
1258   add_offset (obj_5, c);
1259   c->pop_pack (false);
1260 
1261   c->end_serialize();
1262 }
1263 
1264 static void
populate_serializer_virtual_link(hb_serialize_context_t * c)1265 populate_serializer_virtual_link (hb_serialize_context_t* c)
1266 {
1267   c->start_serialize<char> ();
1268 
1269   unsigned obj_d = add_object ("d", 1, c);
1270 
1271   start_object ("b", 1, c);
1272   add_offset (obj_d, c);
1273   unsigned obj_b = c->pop_pack (false);
1274 
1275   start_object ("e", 1, c);
1276   add_virtual_offset (obj_b, c);
1277   unsigned obj_e = c->pop_pack (false);
1278 
1279   start_object ("c", 1, c);
1280   add_offset (obj_e, c);
1281   unsigned obj_c = c->pop_pack (false);
1282 
1283   start_object ("a", 1, c);
1284   add_offset (obj_b, c);
1285   add_offset (obj_c, c);
1286   c->pop_pack (false);
1287 
1288   c->end_serialize();
1289 }
1290 
1291 static void
populate_serializer_with_24_and_32_bit_offsets(hb_serialize_context_t * c)1292 populate_serializer_with_24_and_32_bit_offsets (hb_serialize_context_t* c)
1293 {
1294   std::string large_string(60000, 'a');
1295   c->start_serialize<char> ();
1296 
1297   unsigned obj_f = add_object ("f", 1, c);
1298   unsigned obj_g = add_object ("g", 1, c);
1299   unsigned obj_j = add_object ("j", 1, c);
1300   unsigned obj_k = add_object ("k", 1, c);
1301 
1302   start_object (large_string.c_str (), 40000, c);
1303   add_offset (obj_f, c);
1304   unsigned obj_c = c->pop_pack (false);
1305 
1306   start_object (large_string.c_str (), 40000, c);
1307   add_offset (obj_g, c);
1308   unsigned obj_d = c->pop_pack (false);
1309 
1310   start_object (large_string.c_str (), 40000, c);
1311   add_offset (obj_j, c);
1312   unsigned obj_h = c->pop_pack (false);
1313 
1314   start_object (large_string.c_str (), 40000, c);
1315   add_offset (obj_k, c);
1316   unsigned obj_i = c->pop_pack (false);
1317 
1318   start_object ("e", 1, c);
1319   add_wide_offset (obj_h, c);
1320   add_wide_offset (obj_i, c);
1321   unsigned obj_e = c->pop_pack (false);
1322 
1323   start_object ("b", 1, c);
1324   add_24_offset (obj_c, c);
1325   add_24_offset (obj_d, c);
1326   add_24_offset (obj_e, c);
1327   unsigned obj_b = c->pop_pack (false);
1328 
1329   start_object ("a", 1, c);
1330   add_24_offset (obj_b, c);
1331   c->pop_pack (false);
1332 
1333   c->end_serialize();
1334 }
1335 
1336 static void
populate_serializer_with_extension_promotion(hb_serialize_context_t * c,int num_extensions=0,bool shared_subtables=false)1337 populate_serializer_with_extension_promotion (hb_serialize_context_t* c,
1338                                               int num_extensions = 0,
1339                                               bool shared_subtables = false)
1340 {
1341   constexpr int num_lookups = 5;
1342   constexpr int num_subtables = num_lookups * 2;
1343   unsigned int lookups[num_lookups];
1344   unsigned int subtables[num_subtables];
1345   unsigned int extensions[num_subtables];
1346 
1347   std::string large_string(60000, 'a');
1348   c->start_serialize<char> ();
1349 
1350 
1351   for (int i = num_subtables - 1; i >= 0; i--)
1352     subtables[i] = add_object(large_string.c_str (), 15000 + i, c);
1353 
1354   for (int i = num_subtables - 1;
1355        i >= (num_lookups - num_extensions) * 2;
1356        i--)
1357   {
1358     extensions[i] = add_extension (subtables[i], 5, c);
1359   }
1360 
1361   for (int i = num_lookups - 1; i >= 0; i--)
1362   {
1363     bool is_ext = (i >= (num_lookups - num_extensions));
1364 
1365     start_lookup (is_ext ? (char) 7 : (char) 5,
1366                   shared_subtables && i > 2 ? 3 : 2,
1367                   c);
1368 
1369     if (is_ext) {
1370       if (shared_subtables && i > 2) {
1371         add_offset (extensions[i * 2 - 1], c);
1372       }
1373       add_offset (extensions[i * 2], c);
1374       add_offset (extensions[i * 2 + 1], c);
1375     } else {
1376       if (shared_subtables && i > 2) {
1377         add_offset (subtables[i * 2 - 1], c);
1378       }
1379       add_offset (subtables[i * 2], c);
1380       add_offset (subtables[i * 2 + 1], c);
1381     }
1382 
1383     lookups[i] = finish_lookup (c);
1384   }
1385 
1386   unsigned lookup_list = add_lookup_list (lookups, num_lookups, c);
1387 
1388   add_gsubgpos_header (lookup_list, c);
1389 
1390   c->end_serialize();
1391 }
1392 
1393 template<int num_pair_pos_1, int num_pair_set>
1394 static void
populate_serializer_with_large_pair_pos_1(hb_serialize_context_t * c,bool as_extension=false)1395 populate_serializer_with_large_pair_pos_1 (hb_serialize_context_t* c,
1396                                            bool as_extension = false)
1397 {
1398   std::string large_string(60000, 'a');
1399   c->start_serialize<char> ();
1400 
1401   constexpr int total_pair_set = num_pair_pos_1 * num_pair_set;
1402   unsigned pair_set[total_pair_set];
1403   unsigned coverage[num_pair_pos_1];
1404   unsigned pair_pos_1[num_pair_pos_1];
1405 
1406   for (int i = num_pair_pos_1 - 1; i >= 0; i--)
1407   {
1408     for (int j = (i + 1) * num_pair_set - 1; j >= i * num_pair_set; j--)
1409       pair_set[j] = add_object (large_string.c_str (), 30000 + j, c);
1410 
1411     coverage[i] = add_coverage (i * num_pair_set,
1412                                 (i + 1) * num_pair_set - 1, c);
1413 
1414     pair_pos_1[i] = add_pair_pos_1 (&pair_set[i * num_pair_set],
1415                                     num_pair_set,
1416                                     coverage[i],
1417                                     c);
1418   }
1419 
1420   unsigned pair_pos_2 = add_object (large_string.c_str(), 200, c);
1421 
1422   if (as_extension) {
1423     pair_pos_2 = add_extension (pair_pos_2, 2, c);
1424     for (int i = num_pair_pos_1 - 1; i >= 0; i--)
1425       pair_pos_1[i] = add_extension (pair_pos_1[i], 2, c);
1426   }
1427 
1428   start_lookup (as_extension ? 9 : 2, 1 + num_pair_pos_1, c);
1429 
1430   for (int i = 0; i < num_pair_pos_1; i++)
1431     add_offset (pair_pos_1[i], c);
1432   add_offset (pair_pos_2, c);
1433 
1434   unsigned lookup = finish_lookup (c);
1435 
1436   unsigned lookup_list = add_lookup_list (&lookup, 1, c);
1437 
1438   add_gsubgpos_header (lookup_list, c);
1439 
1440   c->end_serialize();
1441 }
1442 
1443 template<int num_pair_pos_2, int num_class_1, int num_class_2>
1444 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)1445 populate_serializer_with_large_pair_pos_2 (hb_serialize_context_t* c,
1446                                            bool as_extension = false,
1447                                            bool with_device_tables = false,
1448                                            bool extra_table = true)
1449 {
1450   std::string large_string(100000, 'a');
1451   c->start_serialize<char> ();
1452 
1453   unsigned coverage[num_pair_pos_2];
1454   unsigned class_def_1[num_pair_pos_2];
1455   unsigned class_def_2[num_pair_pos_2];
1456   unsigned pair_pos_2[num_pair_pos_2];
1457 
1458   unsigned* device_tables = (unsigned*) calloc (num_pair_pos_2 * num_class_1 * num_class_2,
1459                                                 sizeof(unsigned));
1460 
1461   // Total glyphs = num_class_1 * num_pair_pos_2
1462   for (int i = num_pair_pos_2 - 1; i >= 0; i--)
1463   {
1464     unsigned start_glyph = 5 + i * num_class_1;
1465     if (num_class_2 >= num_class_1)
1466     {
1467       class_def_2[i] = add_class_def (11,
1468                                       10 + num_class_2, c);
1469       class_def_1[i] = add_class_def (start_glyph + 1,
1470                                       start_glyph + num_class_1,
1471                                       c);
1472     } else {
1473       class_def_1[i] = add_class_def (start_glyph + 1,
1474                                       start_glyph + num_class_1,
1475                                       c);
1476       class_def_2[i] = add_class_def (11,
1477                                       10 + num_class_2, c);
1478     }
1479 
1480     coverage[i] = add_coverage (start_glyph,
1481                                 start_glyph + num_class_1 - 1,
1482                                 c);
1483 
1484     if (with_device_tables)
1485     {
1486       for(int j = (i + 1) * num_class_1 * num_class_2 - 1;
1487           j >= i * num_class_1 * num_class_2;
1488           j--)
1489       {
1490         uint8_t table[] = {
1491           (uint8_t) ((j >> 8) & 0xFF),
1492           (uint8_t) (j & 0xFF),
1493         };
1494         device_tables[j] = add_object ((char*) table, 2, c);
1495       }
1496     }
1497 
1498     pair_pos_2[i] = add_pair_pos_2 (1 + i * num_class_1,
1499                                     coverage[i],
1500                                     class_def_1[i], num_class_1,
1501                                     class_def_2[i], num_class_2,
1502                                     with_device_tables
1503                                     ? &device_tables[i * num_class_1 * num_class_2]
1504                                     : nullptr,
1505                                     c);
1506   }
1507 
1508 
1509   unsigned pair_pos_1 = 0;
1510   if (extra_table) pair_pos_1 = add_object (large_string.c_str(), 100000, c);
1511 
1512   if (as_extension) {
1513     for (int i = num_pair_pos_2 - 1; i >= 0; i--)
1514       pair_pos_2[i] = add_extension (pair_pos_2[i], 2, c);
1515 
1516     if (extra_table)
1517       pair_pos_1 = add_extension (pair_pos_1, 2, c);
1518   }
1519 
1520   start_lookup (as_extension ? 9 : 2, 1 + num_pair_pos_2, c);
1521 
1522   if (extra_table)
1523     add_offset (pair_pos_1, c);
1524 
1525   for (int i = 0; i < num_pair_pos_2; i++)
1526     add_offset (pair_pos_2[i], c);
1527 
1528   unsigned lookup = finish_lookup (c);
1529 
1530   unsigned lookup_list = add_lookup_list (&lookup, 1, c);
1531 
1532   add_gsubgpos_header (lookup_list, c);
1533 
1534   c->end_serialize();
1535 
1536   free (device_tables);
1537 }
1538 
1539 template<int mark_count,
1540     int class_count,
1541     int base_count,
1542     int table_count>
1543 static void
populate_serializer_with_large_mark_base_pos_1(hb_serialize_context_t * c)1544 populate_serializer_with_large_mark_base_pos_1 (hb_serialize_context_t* c)
1545 {
1546   c->start_serialize<char> ();
1547 
1548   MarkBasePosBuffers<mark_count, class_count, base_count, table_count> buffers (c);
1549 
1550   unsigned mark_base_pos[table_count];
1551   for (unsigned i = 0; i < table_count; i++)
1552     mark_base_pos[i] = buffers.create_mark_base_pos_1 (i, c);
1553 
1554   for (int i = 0; i < table_count; i++)
1555     mark_base_pos[i] = add_extension (mark_base_pos[i], 4, c);
1556 
1557   start_lookup (9, table_count, c);
1558 
1559   for (int i = 0; i < table_count; i++)
1560     add_offset (mark_base_pos[i], c);
1561 
1562   unsigned lookup = finish_lookup (c);
1563 
1564   unsigned lookup_list = add_lookup_list (&lookup, 1, c);
1565 
1566   add_gsubgpos_header (lookup_list, c);
1567 
1568   c->end_serialize();
1569 }
1570 
test_sort_shortest()1571 static void test_sort_shortest ()
1572 {
1573   size_t buffer_size = 100;
1574   void* buffer = malloc (buffer_size);
1575   hb_serialize_context_t c (buffer, buffer_size);
1576   populate_serializer_complex_2 (&c);
1577 
1578   graph_t graph (c.object_graph ());
1579   graph.sort_shortest_distance ();
1580   assert (!graph.in_error ());
1581 
1582   assert(strncmp (graph.object (4).head, "abc", 3) == 0);
1583   assert(graph.object (4).real_links.length == 3);
1584   assert(graph.object (4).real_links[0].objidx == 2);
1585   assert(graph.object (4).real_links[1].objidx == 0);
1586   assert(graph.object (4).real_links[2].objidx == 3);
1587 
1588   assert(strncmp (graph.object (3).head, "mn", 2) == 0);
1589   assert(graph.object (3).real_links.length == 0);
1590 
1591   assert(strncmp (graph.object (2).head, "def", 3) == 0);
1592   assert(graph.object (2).real_links.length == 1);
1593   assert(graph.object (2).real_links[0].objidx == 1);
1594 
1595   assert(strncmp (graph.object (1).head, "ghi", 3) == 0);
1596   assert(graph.object (1).real_links.length == 1);
1597   assert(graph.object (1).real_links[0].objidx == 0);
1598 
1599   assert(strncmp (graph.object (0).head, "jkl", 3) == 0);
1600   assert(graph.object (0).real_links.length == 0);
1601 
1602   free (buffer);
1603 }
1604 
test_duplicate_leaf()1605 static void test_duplicate_leaf ()
1606 {
1607   size_t buffer_size = 100;
1608   void* buffer = malloc (buffer_size);
1609   hb_serialize_context_t c (buffer, buffer_size);
1610   populate_serializer_complex_2 (&c);
1611 
1612   graph_t graph (c.object_graph ());
1613   graph.duplicate (4, 1);
1614 
1615   assert(strncmp (graph.object (5).head, "abc", 3) == 0);
1616   assert(graph.object (5).real_links.length == 3);
1617   assert(graph.object (5).real_links[0].objidx == 3);
1618   assert(graph.object (5).real_links[1].objidx == 4);
1619   assert(graph.object (5).real_links[2].objidx == 0);
1620 
1621   assert(strncmp (graph.object (4).head, "jkl", 3) == 0);
1622   assert(graph.object (4).real_links.length == 0);
1623 
1624   assert(strncmp (graph.object (3).head, "def", 3) == 0);
1625   assert(graph.object (3).real_links.length == 1);
1626   assert(graph.object (3).real_links[0].objidx == 2);
1627 
1628   assert(strncmp (graph.object (2).head, "ghi", 3) == 0);
1629   assert(graph.object (2).real_links.length == 1);
1630   assert(graph.object (2).real_links[0].objidx == 1);
1631 
1632   assert(strncmp (graph.object (1).head, "jkl", 3) == 0);
1633   assert(graph.object (1).real_links.length == 0);
1634 
1635   assert(strncmp (graph.object (0).head, "mn", 2) == 0);
1636   assert(graph.object (0).real_links.length == 0);
1637 
1638   free (buffer);
1639 }
1640 
test_duplicate_interior()1641 static void test_duplicate_interior ()
1642 {
1643   size_t buffer_size = 100;
1644   void* buffer = malloc (buffer_size);
1645   hb_serialize_context_t c (buffer, buffer_size);
1646   populate_serializer_complex_3 (&c);
1647 
1648   graph_t graph (c.object_graph ());
1649   graph.duplicate (3, 2);
1650 
1651   assert(strncmp (graph.object (6).head, "abc", 3) == 0);
1652   assert(graph.object (6).real_links.length == 3);
1653   assert(graph.object (6).real_links[0].objidx == 4);
1654   assert(graph.object (6).real_links[1].objidx == 2);
1655   assert(graph.object (6).real_links[2].objidx == 1);
1656 
1657   assert(strncmp (graph.object (5).head, "jkl", 3) == 0);
1658   assert(graph.object (5).real_links.length == 1);
1659   assert(graph.object (5).real_links[0].objidx == 0);
1660 
1661   assert(strncmp (graph.object (4).head, "def", 3) == 0);
1662   assert(graph.object (4).real_links.length == 1);
1663   assert(graph.object (4).real_links[0].objidx == 3);
1664 
1665   assert(strncmp (graph.object (3).head, "ghi", 3) == 0);
1666   assert(graph.object (3).real_links.length == 1);
1667   assert(graph.object (3).real_links[0].objidx == 5);
1668 
1669   assert(strncmp (graph.object (2).head, "jkl", 3) == 0);
1670   assert(graph.object (2).real_links.length == 1);
1671   assert(graph.object (2).real_links[0].objidx == 0);
1672 
1673   assert(strncmp (graph.object (1).head, "mn", 2) == 0);
1674   assert(graph.object (1).real_links.length == 0);
1675 
1676   assert(strncmp (graph.object (0).head, "opqrst", 6) == 0);
1677   assert(graph.object (0).real_links.length == 0);
1678 
1679   free (buffer);
1680 }
1681 
1682 static void
test_serialize()1683 test_serialize ()
1684 {
1685   size_t buffer_size = 100;
1686   void* buffer_1 = malloc (buffer_size);
1687   hb_serialize_context_t c1 (buffer_1, buffer_size);
1688   populate_serializer_simple (&c1);
1689   hb_bytes_t expected = c1.copy_bytes ();
1690 
1691   graph_t graph (c1.object_graph ());
1692   hb_blob_t* out = graph::serialize (graph);
1693   free (buffer_1);
1694 
1695   hb_bytes_t actual = out->as_bytes ();
1696   assert (actual == expected);
1697   expected.fini ();
1698   hb_blob_destroy (out);
1699 }
1700 
test_will_overflow_1()1701 static void test_will_overflow_1 ()
1702 {
1703   size_t buffer_size = 100;
1704   void* buffer = malloc (buffer_size);
1705   hb_serialize_context_t c (buffer, buffer_size);
1706   populate_serializer_complex_2 (&c);
1707   graph_t graph (c.object_graph ());
1708 
1709   assert (!graph::will_overflow (graph, nullptr));
1710 
1711   free (buffer);
1712 }
1713 
test_will_overflow_2()1714 static void test_will_overflow_2 ()
1715 {
1716   size_t buffer_size = 160000;
1717   void* buffer = malloc (buffer_size);
1718   hb_serialize_context_t c (buffer, buffer_size);
1719   populate_serializer_with_overflow (&c);
1720   graph_t graph (c.object_graph ());
1721 
1722   assert (graph::will_overflow (graph, nullptr));
1723 
1724   free (buffer);
1725 }
1726 
test_will_overflow_3()1727 static void test_will_overflow_3 ()
1728 {
1729   size_t buffer_size = 160000;
1730   void* buffer = malloc (buffer_size);
1731   hb_serialize_context_t c (buffer, buffer_size);
1732   populate_serializer_with_dedup_overflow (&c);
1733   graph_t graph (c.object_graph ());
1734 
1735   assert (graph::will_overflow (graph, nullptr));
1736 
1737   free (buffer);
1738 }
1739 
test_resolve_overflows_via_sort()1740 static void test_resolve_overflows_via_sort ()
1741 {
1742   size_t buffer_size = 160000;
1743   void* buffer = malloc (buffer_size);
1744   hb_serialize_context_t c (buffer, buffer_size);
1745   populate_serializer_with_overflow (&c);
1746   graph_t graph (c.object_graph ());
1747 
1748   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE);
1749   assert (out);
1750   hb_bytes_t result = out->as_bytes ();
1751   assert (result.length == (80000 + 3 + 3 * 2));
1752 
1753   free (buffer);
1754   hb_blob_destroy (out);
1755 }
1756 
test_resolve_overflows_via_duplication()1757 static void test_resolve_overflows_via_duplication ()
1758 {
1759   size_t buffer_size = 160000;
1760   void* buffer = malloc (buffer_size);
1761   hb_serialize_context_t c (buffer, buffer_size);
1762   populate_serializer_with_dedup_overflow (&c);
1763   graph_t graph (c.object_graph ());
1764 
1765   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE);
1766   assert (out);
1767   hb_bytes_t result = out->as_bytes ();
1768   assert (result.length == (10000 + 2 * 2 + 60000 + 2 + 3 * 2));
1769 
1770   free (buffer);
1771   hb_blob_destroy (out);
1772 }
1773 
test_resolve_overflows_via_multiple_duplications()1774 static void test_resolve_overflows_via_multiple_duplications ()
1775 {
1776   size_t buffer_size = 300000;
1777   void* buffer = malloc (buffer_size);
1778   hb_serialize_context_t c (buffer, buffer_size);
1779   populate_serializer_with_multiple_dedup_overflow (&c);
1780   graph_t graph (c.object_graph ());
1781 
1782   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, 5);
1783   assert (out);
1784 
1785   free (buffer);
1786   hb_blob_destroy (out);
1787 }
1788 
test_resolve_overflows_via_space_assignment()1789 static void test_resolve_overflows_via_space_assignment ()
1790 {
1791   size_t buffer_size = 160000;
1792   void* buffer = malloc (buffer_size);
1793   hb_serialize_context_t c (buffer, buffer_size);
1794   populate_serializer_spaces (&c, true);
1795 
1796   void* expected_buffer = malloc (buffer_size);
1797   hb_serialize_context_t e (expected_buffer, buffer_size);
1798   populate_serializer_spaces (&e, false);
1799 
1800   run_resolve_overflow_test ("test_resolve_overflows_via_space_assignment",
1801                              c,
1802                              e);
1803 
1804   free (buffer);
1805   free (expected_buffer);
1806 }
1807 
test_resolve_overflows_via_isolation()1808 static void test_resolve_overflows_via_isolation ()
1809 {
1810   size_t buffer_size = 160000;
1811   void* buffer = malloc (buffer_size);
1812   hb_serialize_context_t c (buffer, buffer_size);
1813   populate_serializer_with_isolation_overflow (&c);
1814   graph_t graph (c.object_graph ());
1815 
1816   assert (c.offset_overflow ());
1817   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0);
1818   assert (out);
1819   hb_bytes_t result = out->as_bytes ();
1820   assert (result.length == (1 + 10000 + 60000 + 1 + 1
1821                             + 4 + 3 * 2));
1822 
1823   free (buffer);
1824   hb_blob_destroy (out);
1825 }
1826 
test_resolve_overflows_via_isolation_with_recursive_duplication()1827 static void test_resolve_overflows_via_isolation_with_recursive_duplication ()
1828 {
1829   size_t buffer_size = 160000;
1830   void* buffer = malloc (buffer_size);
1831   hb_serialize_context_t c (buffer, buffer_size);
1832   populate_serializer_with_isolation_overflow_complex (&c);
1833 
1834   void* expected_buffer = malloc (buffer_size);
1835   hb_serialize_context_t e (expected_buffer, buffer_size);
1836   populate_serializer_with_isolation_overflow_complex_expected (&e);
1837 
1838   run_resolve_overflow_test ("test_resolve_overflows_via_isolation_with_recursive_duplication",
1839                              c,
1840                              e);
1841   free (buffer);
1842   free (expected_buffer);
1843 }
1844 
test_resolve_overflows_via_isolating_16bit_space()1845 static void test_resolve_overflows_via_isolating_16bit_space ()
1846 {
1847   size_t buffer_size = 160000;
1848   void* buffer = malloc (buffer_size);
1849   hb_serialize_context_t c (buffer, buffer_size);
1850   populate_serializer_spaces_16bit_connection (&c);
1851 
1852   void* expected_buffer = malloc (buffer_size);
1853   hb_serialize_context_t e (expected_buffer, buffer_size);
1854   populate_serializer_spaces_16bit_connection_expected (&e);
1855 
1856   run_resolve_overflow_test ("test_resolve_overflows_via_isolating_16bit_space",
1857                              c,
1858                              e);
1859 
1860   free (buffer);
1861   free (expected_buffer);
1862 }
1863 
test_resolve_overflows_via_isolating_16bit_space_2()1864 static void test_resolve_overflows_via_isolating_16bit_space_2 ()
1865 {
1866   size_t buffer_size = 160000;
1867   void* buffer = malloc (buffer_size);
1868   hb_serialize_context_t c (buffer, buffer_size);
1869   populate_serializer_short_and_wide_subgraph_root (&c);
1870 
1871   void* expected_buffer = malloc (buffer_size);
1872   hb_serialize_context_t e (expected_buffer, buffer_size);
1873   populate_serializer_short_and_wide_subgraph_root_expected (&e);
1874 
1875   run_resolve_overflow_test ("test_resolve_overflows_via_isolating_16bit_space_2",
1876                              c,
1877                              e);
1878 
1879   free (buffer);
1880   free (expected_buffer);
1881 }
1882 
test_resolve_overflows_via_isolation_spaces()1883 static void test_resolve_overflows_via_isolation_spaces ()
1884 {
1885   size_t buffer_size = 160000;
1886   void* buffer = malloc (buffer_size);
1887   hb_serialize_context_t c (buffer, buffer_size);
1888   populate_serializer_with_isolation_overflow_spaces (&c);
1889   graph_t graph (c.object_graph ());
1890 
1891   assert (c.offset_overflow ());
1892   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0);
1893   assert (out);
1894   hb_bytes_t result = out->as_bytes ();
1895 
1896   unsigned expected_length = 3 + 2 * 60000; // objects
1897   expected_length += 2 * 4 + 2 * 2; // links
1898   assert (result.length == expected_length);
1899 
1900   free (buffer);
1901   hb_blob_destroy (out);
1902 }
1903 
test_resolve_mixed_overflows_via_isolation_spaces()1904 static void test_resolve_mixed_overflows_via_isolation_spaces ()
1905 {
1906   size_t buffer_size = 200000;
1907   void* buffer = malloc (buffer_size);
1908   hb_serialize_context_t c (buffer, buffer_size);
1909   populate_serializer_with_24_and_32_bit_offsets (&c);
1910   graph_t graph (c.object_graph ());
1911 
1912   assert (c.offset_overflow ());
1913   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0);
1914   assert (out);
1915   hb_bytes_t result = out->as_bytes ();
1916 
1917   unsigned expected_length =
1918       // Objects
1919       7 +
1920       4 * 40000;
1921 
1922   expected_length +=
1923       // Links
1924       2 * 4 +  // 32
1925       4 * 3 +  // 24
1926       4 * 2;   // 16
1927 
1928   assert (result.length == expected_length);
1929 
1930   free (buffer);
1931   hb_blob_destroy (out);
1932 }
1933 
test_resolve_with_extension_promotion()1934 static void test_resolve_with_extension_promotion ()
1935 {
1936   size_t buffer_size = 200000;
1937   void* buffer = malloc (buffer_size);
1938   assert (buffer);
1939   hb_serialize_context_t c (buffer, buffer_size);
1940   populate_serializer_with_extension_promotion (&c);
1941 
1942   void* expected_buffer = malloc (buffer_size);
1943   assert (expected_buffer);
1944   hb_serialize_context_t e (expected_buffer, buffer_size);
1945   populate_serializer_with_extension_promotion (&e, 3);
1946 
1947   run_resolve_overflow_test ("test_resolve_with_extension_promotion",
1948                              c,
1949                              e,
1950                              20,
1951                              true);
1952   free (buffer);
1953   free (expected_buffer);
1954 }
1955 
test_resolve_with_shared_extension_promotion()1956 static void test_resolve_with_shared_extension_promotion ()
1957 {
1958   size_t buffer_size = 200000;
1959   void* buffer = malloc (buffer_size);
1960   assert (buffer);
1961   hb_serialize_context_t c (buffer, buffer_size);
1962   populate_serializer_with_extension_promotion (&c, 0, true);
1963 
1964   void* expected_buffer = malloc (buffer_size);
1965   assert (expected_buffer);
1966   hb_serialize_context_t e (expected_buffer, buffer_size);
1967   populate_serializer_with_extension_promotion (&e, 3, true);
1968 
1969   run_resolve_overflow_test ("test_resolve_with_extension_promotion",
1970                              c,
1971                              e,
1972                              20,
1973                              true);
1974   free (buffer);
1975   free (expected_buffer);
1976 }
1977 
test_resolve_with_basic_pair_pos_1_split()1978 static void test_resolve_with_basic_pair_pos_1_split ()
1979 {
1980   size_t buffer_size = 200000;
1981   void* buffer = malloc (buffer_size);
1982   assert (buffer);
1983   hb_serialize_context_t c (buffer, buffer_size);
1984   populate_serializer_with_large_pair_pos_1 <1, 4>(&c);
1985 
1986   void* expected_buffer = malloc (buffer_size);
1987   assert (expected_buffer);
1988   hb_serialize_context_t e (expected_buffer, buffer_size);
1989   populate_serializer_with_large_pair_pos_1 <2, 2>(&e, true);
1990 
1991   run_resolve_overflow_test ("test_resolve_with_basic_pair_pos_1_split",
1992                              c,
1993                              e,
1994                              20,
1995                              true,
1996                              HB_TAG('G', 'P', 'O', 'S'));
1997   free (buffer);
1998   free (expected_buffer);
1999 }
2000 
test_resolve_with_extension_pair_pos_1_split()2001 static void test_resolve_with_extension_pair_pos_1_split ()
2002 {
2003   size_t buffer_size = 200000;
2004   void* buffer = malloc (buffer_size);
2005   assert (buffer);
2006   hb_serialize_context_t c (buffer, buffer_size);
2007   populate_serializer_with_large_pair_pos_1 <1, 4>(&c, true);
2008 
2009   void* expected_buffer = malloc (buffer_size);
2010   assert (expected_buffer);
2011   hb_serialize_context_t e (expected_buffer, buffer_size);
2012   populate_serializer_with_large_pair_pos_1 <2, 2>(&e, true);
2013 
2014   run_resolve_overflow_test ("test_resolve_with_extension_pair_pos_1_split",
2015                              c,
2016                              e,
2017                              20,
2018                              true,
2019                              HB_TAG('G', 'P', 'O', 'S'));
2020   free (buffer);
2021   free (expected_buffer);
2022 }
2023 
test_resolve_with_basic_pair_pos_2_split()2024 static void test_resolve_with_basic_pair_pos_2_split ()
2025 {
2026   size_t buffer_size = 300000;
2027   void* buffer = malloc (buffer_size);
2028   assert (buffer);
2029   hb_serialize_context_t c (buffer, buffer_size);
2030   populate_serializer_with_large_pair_pos_2 <1, 4, 3000>(&c);
2031 
2032   void* expected_buffer = malloc (buffer_size);
2033   assert (expected_buffer);
2034   hb_serialize_context_t e (expected_buffer, buffer_size);
2035   populate_serializer_with_large_pair_pos_2 <2, 2, 3000>(&e, true);
2036 
2037   run_resolve_overflow_test ("test_resolve_with_basic_pair_pos_2_split",
2038                              c,
2039                              e,
2040                              20,
2041                              true,
2042                              HB_TAG('G', 'P', 'O', 'S'));
2043   free (buffer);
2044   free (expected_buffer);
2045 }
2046 
test_resolve_with_close_to_limit_pair_pos_2_split()2047 static void test_resolve_with_close_to_limit_pair_pos_2_split ()
2048 {
2049   size_t buffer_size = 300000;
2050   void* buffer = malloc (buffer_size);
2051   assert (buffer);
2052   hb_serialize_context_t c (buffer, buffer_size);
2053   populate_serializer_with_large_pair_pos_2 <1, 1636, 10>(&c, true, false, false);
2054 
2055   void* expected_buffer = malloc (buffer_size);
2056   assert (expected_buffer);
2057   hb_serialize_context_t e (expected_buffer, buffer_size);
2058   populate_serializer_with_large_pair_pos_2 <2, 818, 10>(&e, true, false, false);
2059 
2060   run_resolve_overflow_test ("test_resolve_with_close_to_limit_pair_pos_2_split",
2061                              c,
2062                              e,
2063                              20,
2064                              true,
2065                              HB_TAG('G', 'P', 'O', 'S'));
2066   free (buffer);
2067   free (expected_buffer);
2068 }
2069 
test_resolve_with_pair_pos_2_split_with_device_tables()2070 static void test_resolve_with_pair_pos_2_split_with_device_tables ()
2071 {
2072   size_t buffer_size = 300000;
2073   void* buffer = malloc (buffer_size);
2074   assert (buffer);
2075   hb_serialize_context_t c (buffer, buffer_size);
2076   populate_serializer_with_large_pair_pos_2 <1, 4, 2000>(&c, false, true);
2077 
2078   void* expected_buffer = malloc (buffer_size);
2079   assert (expected_buffer);
2080   hb_serialize_context_t e (expected_buffer, buffer_size);
2081   populate_serializer_with_large_pair_pos_2 <2, 2, 2000>(&e, true, true);
2082 
2083   run_resolve_overflow_test ("test_resolve_with_pair_pos_2_split_with_device_tables",
2084                              c,
2085                              e,
2086                              20,
2087                              true,
2088                              HB_TAG('G', 'P', 'O', 'S'));
2089   free (buffer);
2090   free (expected_buffer);
2091 }
2092 
test_resolve_with_basic_mark_base_pos_1_split()2093 static void test_resolve_with_basic_mark_base_pos_1_split ()
2094 {
2095   size_t buffer_size = 200000;
2096   void* buffer = malloc (buffer_size);
2097   assert (buffer);
2098   hb_serialize_context_t c (buffer, buffer_size);
2099   populate_serializer_with_large_mark_base_pos_1 <40, 10, 110, 1>(&c);
2100 
2101   void* expected_buffer = malloc (buffer_size);
2102   assert (expected_buffer);
2103   hb_serialize_context_t e (expected_buffer, buffer_size);
2104   populate_serializer_with_large_mark_base_pos_1 <40, 10, 110, 2>(&e);
2105 
2106   run_resolve_overflow_test ("test_resolve_with_basic_mark_base_pos_1_split",
2107                              c,
2108                              e,
2109                              20,
2110                              true,
2111                              HB_TAG('G', 'P', 'O', 'S'));
2112   free (buffer);
2113   free (expected_buffer);
2114 }
2115 
test_resolve_overflows_via_splitting_spaces()2116 static void test_resolve_overflows_via_splitting_spaces ()
2117 {
2118   size_t buffer_size = 160000;
2119   void* buffer = malloc (buffer_size);
2120   hb_serialize_context_t c (buffer, buffer_size);
2121   populate_serializer_with_split_spaces (&c);
2122 
2123   void* expected_buffer = malloc (buffer_size);
2124   hb_serialize_context_t e (expected_buffer, buffer_size);
2125   populate_serializer_with_split_spaces_expected (&e);
2126 
2127   run_resolve_overflow_test ("test_resolve_overflows_via_splitting_spaces",
2128                              c,
2129                              e,
2130                              1);
2131 
2132   free (buffer);
2133   free (expected_buffer);
2134 
2135 }
2136 
test_resolve_overflows_via_splitting_spaces_2()2137 static void test_resolve_overflows_via_splitting_spaces_2 ()
2138 {
2139   size_t buffer_size = 160000;
2140   void* buffer = malloc (buffer_size);
2141   hb_serialize_context_t c (buffer, buffer_size);
2142   populate_serializer_with_split_spaces_2 (&c);
2143 
2144   void* expected_buffer = malloc (buffer_size);
2145   hb_serialize_context_t e (expected_buffer, buffer_size);
2146   populate_serializer_with_split_spaces_expected_2 (&e);
2147 
2148   run_resolve_overflow_test ("test_resolve_overflows_via_splitting_spaces_2",
2149                              c,
2150                              e,
2151                              1);
2152   free (buffer);
2153   free (expected_buffer);
2154 }
2155 
test_resolve_overflows_via_priority()2156 static void test_resolve_overflows_via_priority ()
2157 {
2158   size_t buffer_size = 160000;
2159   void* buffer = malloc (buffer_size);
2160   hb_serialize_context_t c (buffer, buffer_size);
2161   populate_serializer_with_priority_overflow (&c);
2162 
2163   void* expected_buffer = malloc (buffer_size);
2164   hb_serialize_context_t e (expected_buffer, buffer_size);
2165   populate_serializer_with_priority_overflow_expected (&e);
2166 
2167   run_resolve_overflow_test ("test_resolve_overflows_via_priority",
2168                              c,
2169                              e,
2170                              3);
2171   free (buffer);
2172   free (expected_buffer);
2173 }
2174 
2175 
test_virtual_link()2176 static void test_virtual_link ()
2177 {
2178   size_t buffer_size = 100;
2179   void* buffer = malloc (buffer_size);
2180   hb_serialize_context_t c (buffer, buffer_size);
2181   populate_serializer_virtual_link (&c);
2182 
2183   hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE);
2184   assert (out);
2185 
2186   hb_bytes_t result = out->as_bytes ();
2187   assert (result.length == 5 + 4 * 2);
2188   assert (result[0]  == 'a');
2189   assert (result[5]  == 'c');
2190   assert (result[8]  == 'e');
2191   assert (result[9]  == 'b');
2192   assert (result[12] == 'd');
2193 
2194   free (buffer);
2195   hb_blob_destroy (out);
2196 }
2197 
2198 static void
test_shared_node_with_virtual_links()2199 test_shared_node_with_virtual_links ()
2200 {
2201   size_t buffer_size = 100;
2202   void* buffer = malloc (buffer_size);
2203   hb_serialize_context_t c (buffer, buffer_size);
2204 
2205   c.start_serialize<char> ();
2206 
2207   unsigned obj_b = add_object ("b", 1, &c);
2208   unsigned obj_c = add_object ("c", 1, &c);
2209 
2210   start_object ("d", 1, &c);
2211   add_virtual_offset (obj_b, &c);
2212   unsigned obj_d_1 = c.pop_pack ();
2213 
2214   start_object ("d", 1, &c);
2215   add_virtual_offset (obj_c, &c);
2216   unsigned obj_d_2 = c.pop_pack ();
2217 
2218   assert (obj_d_1 == obj_d_2);
2219 
2220   start_object ("a", 1, &c);
2221   add_offset (obj_b, &c);
2222   add_offset (obj_c, &c);
2223   add_offset (obj_d_1, &c);
2224   add_offset (obj_d_2, &c);
2225   c.pop_pack ();
2226   c.end_serialize ();
2227 
2228   assert(c.object_graph() [obj_d_1]->virtual_links.length == 2);
2229   assert(c.object_graph() [obj_d_1]->virtual_links[0].objidx == obj_b);
2230   assert(c.object_graph() [obj_d_1]->virtual_links[1].objidx == obj_c);
2231   free(buffer);
2232 }
2233 
2234 static void
test_repack_last()2235 test_repack_last ()
2236 {
2237   size_t buffer_size = 200000;
2238   void* buffer = malloc (buffer_size);
2239   assert (buffer);
2240   hb_serialize_context_t c (buffer, buffer_size);
2241   populate_serializer_with_repack_last (&c, true);
2242 
2243   void* expected_buffer = malloc (buffer_size);
2244   assert (expected_buffer);
2245   hb_serialize_context_t e (expected_buffer, buffer_size);
2246   populate_serializer_with_repack_last (&e, false);
2247 
2248   run_resolve_overflow_test ("test_repack_last",
2249                              c,
2250                              e,
2251                              20,
2252                              false,
2253                              HB_TAG('a', 'b', 'c', 'd'),
2254                              true);
2255 
2256   free (buffer);
2257   free (expected_buffer);
2258 }
2259 
2260 // TODO(garretrieger): update will_overflow tests to check the overflows array.
2261 // TODO(garretrieger): add tests for priority raising.
2262 
2263 int
main(int argc,char ** argv)2264 main (int argc, char **argv)
2265 {
2266   test_serialize ();
2267   test_sort_shortest ();
2268   test_will_overflow_1 ();
2269   test_will_overflow_2 ();
2270   test_will_overflow_3 ();
2271   test_resolve_overflows_via_sort ();
2272   test_resolve_overflows_via_duplication ();
2273   test_resolve_overflows_via_multiple_duplications ();
2274   test_resolve_overflows_via_priority ();
2275   test_resolve_overflows_via_space_assignment ();
2276   test_resolve_overflows_via_isolation ();
2277   test_resolve_overflows_via_isolation_with_recursive_duplication ();
2278   test_resolve_overflows_via_isolation_spaces ();
2279   test_resolve_overflows_via_isolating_16bit_space ();
2280   test_resolve_overflows_via_isolating_16bit_space_2 ();
2281   test_resolve_overflows_via_splitting_spaces ();
2282   test_resolve_overflows_via_splitting_spaces_2 ();
2283   test_resolve_mixed_overflows_via_isolation_spaces ();
2284   test_duplicate_leaf ();
2285   test_duplicate_interior ();
2286   test_virtual_link ();
2287   test_repack_last();
2288   test_shared_node_with_virtual_links ();
2289   test_resolve_with_extension_promotion ();
2290   test_resolve_with_shared_extension_promotion ();
2291   test_resolve_with_basic_pair_pos_1_split ();
2292   test_resolve_with_extension_pair_pos_1_split ();
2293   test_resolve_with_basic_pair_pos_2_split ();
2294   test_resolve_with_pair_pos_2_split_with_device_tables ();
2295   test_resolve_with_close_to_limit_pair_pos_2_split ();
2296   test_resolve_with_basic_mark_base_pos_1_split ();
2297 
2298   // TODO(grieger): have run overflow tests compare graph equality not final packed binary.
2299   // TODO(grieger): split test where multiple subtables in one lookup are split to test link ordering.
2300   // TODO(grieger): split test where coverage table in subtable that is being split is shared.
2301   // TODO(grieger): test with extensions already mixed in as well.
2302   // TODO(grieger): test two layer ext promotion setup.
2303   // TODO(grieger): test sorting by subtables per byte in ext. promotion.
2304 }
2305