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