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