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