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