Commit 09f3737202198ddb5367be1ce0e22c7833be8355

Authored by Jay Berkenbilt
1 parent c5708e91

Split qpdf-ctest test 24 into multiple tests

Thanks for the nudge from m-holger!
qpdf/qpdf-ctest.c
... ... @@ -500,16 +500,23 @@ static void test24(char const* infile,
500 500 char const* outfile,
501 501 char const* outfile2)
502 502 {
503   - /* This test case is designed for minimal.pdf. */
  503 + /* This test case is designed for minimal.pdf. Pull objects out of
  504 + * minimal.pdf to make sure all our accessors work as expected.
  505 + */
  506 +
504 507 qpdf_read(qpdf, infile, password);
505 508 qpdf_oh trailer = qpdf_get_trailer(qpdf);
506 509 /* The library never returns 0 */
507 510 assert(trailer == 1);
  511 +
  512 + /* Get root two different ways */
508 513 qpdf_oh root = qpdf_get_root(qpdf);
509 514 assert(qpdf_oh_get_generation(qpdf, root) == 0);
510 515 qpdf_oh root_from_trailer = qpdf_oh_get_key(qpdf, trailer, "/Root");
511 516 assert(qpdf_oh_get_object_id(qpdf, root) ==
512 517 qpdf_oh_get_object_id(qpdf, root_from_trailer));
  518 +
  519 + /* Go to the first page and look at all the keys */
513 520 qpdf_oh pages = qpdf_oh_get_key(qpdf, root, "/Pages");
514 521 assert(qpdf_oh_is_dictionary(qpdf, pages));
515 522 assert(qpdf_oh_is_initialized(qpdf, pages));
... ... @@ -522,6 +529,8 @@ static void test24(char const* infile,
522 529 {
523 530 printf("page dictionary key: %s\n", qpdf_oh_dict_next_key(qpdf));
524 531 }
  532 +
  533 + /* Inspect the first page */
525 534 qpdf_oh type = qpdf_oh_get_key(qpdf, page1, "/Type");
526 535 assert(qpdf_oh_is_name(qpdf, type));
527 536 assert(strcmp(qpdf_oh_get_name(qpdf, type), "/Page") == 0);
... ... @@ -531,32 +540,24 @@ static void test24(char const* infile,
531 540 assert(! qpdf_oh_is_scalar(qpdf, mediabox));
532 541 assert(qpdf_oh_is_array(qpdf, mediabox));
533 542 assert(qpdf_oh_get_array_n_items(qpdf, mediabox) == 4);
534   - qpdf_oh wrapped_mediabox = qpdf_oh_wrap_in_array(qpdf, mediabox);
535   - qpdf_oh cloned_mediabox = qpdf_oh_new_object(qpdf, mediabox);
536   - assert(wrapped_mediabox != mediabox);
537   - assert(cloned_mediabox != mediabox);
538   - assert(qpdf_oh_get_array_n_items(qpdf, wrapped_mediabox) == 4);
539 543 for (int i = 0; i < 4; ++i)
540 544 {
541 545 qpdf_oh item = qpdf_oh_get_array_item(qpdf, mediabox, i);
542   - qpdf_oh item2 = qpdf_oh_get_array_item(qpdf, wrapped_mediabox, i);
543   - qpdf_oh item3 = qpdf_oh_get_array_item(qpdf, cloned_mediabox, i);
544   - assert(qpdf_oh_get_int_value_as_int(qpdf, item) ==
545   - qpdf_oh_get_int_value_as_int(qpdf, item2));
546   - assert(qpdf_oh_get_int_value_as_int(qpdf, item) ==
547   - qpdf_oh_get_int_value_as_int(qpdf, item3));
548 546 printf("item %d: %d %.2f\n",
549 547 i, qpdf_oh_get_int_value_as_int(qpdf, item),
550 548 qpdf_oh_get_numeric_value(qpdf, item));
551   - qpdf_oh_release(qpdf, item);
552 549 }
  550 +
  551 + /* Exercise different ways of looking at integers */
553 552 qpdf_oh i2 = qpdf_oh_get_array_item(qpdf, mediabox, 2);
554 553 assert(qpdf_oh_get_int_value_as_int(qpdf, i2) == 612);
555 554 assert(qpdf_oh_get_int_value(qpdf, i2) == 612ll);
556 555 assert(qpdf_oh_get_uint_value_as_uint(qpdf, i2) == 612u);
557 556 assert(qpdf_oh_get_uint_value(qpdf, i2) == 612ull);
  557 + /* Exercise accessors of other object types */
558 558 assert(! qpdf_oh_is_operator(qpdf, i2));
559 559 assert(! qpdf_oh_is_inline_image(qpdf, i2));
  560 + /* Chain calls. */
560 561 qpdf_oh encoding = qpdf_oh_get_key(
561 562 qpdf, qpdf_oh_get_key(
562 563 qpdf, qpdf_oh_get_key(
... ... @@ -566,6 +567,8 @@ static void test24(char const* infile,
566 567 "/F1"),
567 568 "/Encoding");
568 569 assert(strcmp(qpdf_oh_get_name(qpdf, encoding), "/WinAnsiEncoding") == 0);
  570 +
  571 + /* Look at page contents to exercise stream functions */
569 572 qpdf_oh contents = qpdf_oh_get_key(qpdf, page1, "/Contents");
570 573 assert(qpdf_oh_is_stream(qpdf, contents));
571 574 qpdf_oh contents_dict = qpdf_oh_get_dict(qpdf, contents);
... ... @@ -580,12 +583,15 @@ static void test24(char const* infile,
580 583 assert(qpdf_oh_get_object_id(
581 584 qpdf, qpdf_oh_get_array_item(qpdf, contents_array, 0)) ==
582 585 qpdf_oh_get_object_id(qpdf, contents));
  586 + /* Wrap in array for a non-trivial case */
583 587 qpdf_oh wrapped_contents_array =
584 588 qpdf_oh_wrap_in_array(qpdf, contents_array);
585 589 assert(qpdf_oh_get_array_n_items(qpdf, wrapped_contents_array) == 1);
586 590 assert(qpdf_oh_get_object_id(
587 591 qpdf, qpdf_oh_get_array_item(qpdf, wrapped_contents_array, 0)) ==
588 592 qpdf_oh_get_object_id(qpdf, contents));
  593 +
  594 + /* Exercise functions that work with indirect objects */
589 595 qpdf_oh resources = qpdf_oh_get_key(qpdf, page1, "/Resources");
590 596 qpdf_oh procset = qpdf_oh_get_key(qpdf, resources, "/ProcSet");
591 597 assert(strcmp(qpdf_oh_unparse(qpdf, procset),
... ... @@ -595,8 +601,44 @@ static void test24(char const* infile,
595 601 qpdf_oh_make_direct(qpdf, procset);
596 602 assert(strcmp(qpdf_oh_unparse(qpdf, procset),
597 603 "[ /PDF /Text ]") == 0);
  604 + /* The replaced /ProcSet can be seen to be a direct object in the
  605 + * expected output PDF.
  606 + */
598 607 qpdf_oh_replace_key(qpdf, resources, "/ProcSet", procset);
599 608  
  609 + /* Release and access to exercise warnings and to show that write
  610 + * still works after releasing.
  611 + */
  612 + qpdf_oh_release(qpdf, page1);
  613 + contents = qpdf_oh_get_key(qpdf, page1, "/Contents");
  614 + assert(qpdf_oh_is_null(qpdf, contents));
  615 + assert(qpdf_oh_is_array(qpdf, mediabox));
  616 + qpdf_oh_release_all(qpdf);
  617 + assert(! qpdf_oh_is_null(qpdf, mediabox));
  618 + assert(! qpdf_oh_is_array(qpdf, mediabox));
  619 + /* Make sure something is assigned when we exit so we check that
  620 + * it gets properly freed.
  621 + */
  622 + qpdf_get_root(qpdf);
  623 +
  624 + qpdf_init_write(qpdf, outfile);
  625 + qpdf_set_static_ID(qpdf, QPDF_TRUE);
  626 + qpdf_set_qdf_mode(qpdf, QPDF_TRUE);
  627 + qpdf_set_suppress_original_object_IDs(qpdf, QPDF_TRUE);
  628 + qpdf_write(qpdf);
  629 + report_errors();
  630 +}
  631 +
  632 +static void test25(char const* infile,
  633 + char const* password,
  634 + char const* outfile,
  635 + char const* outfile2)
  636 +{
  637 + /* This test case is designed for minimal.pdf. */
  638 + qpdf_read(qpdf, infile, password);
  639 + qpdf_oh root = qpdf_get_root(qpdf);
  640 +
  641 + /* Parse objects from a string */
600 642 qpdf_oh parsed = qpdf_oh_parse(
601 643 qpdf, "[ 1 2.0 (3\xf7) << /Four [/Five] >> null true ]");
602 644 qpdf_oh p_int = qpdf_oh_get_array_item(qpdf, parsed, 0);
... ... @@ -614,13 +656,6 @@ static void test24(char const* infile,
614 656 (strcmp(qpdf_oh_get_string_value(qpdf, p_string), "3\xf7") == 0) &&
615 657 (strcmp(qpdf_oh_get_utf8_value(qpdf, p_string), "3\xc3\xb7") == 0) &&
616 658 (strcmp(qpdf_oh_unparse_binary(qpdf, p_string), "<33f7>") == 0));
617   - qpdf_oh p_string_with_null = qpdf_oh_parse(qpdf, "<6f6e650074776f>");
618   - assert(qpdf_oh_is_string(qpdf, p_string_with_null) &&
619   - (strcmp(qpdf_oh_get_string_value(qpdf, p_string_with_null),
620   - "one") == 0) &&
621   - (qpdf_get_last_string_length(qpdf) == 7) &&
622   - (memcmp(qpdf_oh_get_string_value(qpdf, p_string_with_null),
623   - "one\000two", 7) == 0));
624 659 assert(qpdf_oh_is_dictionary(qpdf, p_dict));
625 660 qpdf_oh p_five = qpdf_oh_get_key(qpdf, p_dict, "/Four");
626 661 assert(qpdf_oh_is_or_has_name(qpdf, p_five, "/Five"));
... ... @@ -669,33 +704,84 @@ static void test24(char const* infile,
669 704 qpdf, new_array, qpdf_oh_new_bool(qpdf, QPDF_TRUE));
670 705 qpdf_oh_replace_key(qpdf, root, "/QTest", new_dict);
671 706  
672   - /* Release and access to exercise warnings */
673   - qpdf_oh_release(qpdf, page1);
674   - contents = qpdf_oh_get_key(qpdf, page1, "/Contents");
675   - assert(qpdf_oh_is_null(qpdf, contents));
676   - assert(qpdf_oh_is_array(qpdf, mediabox));
677   - qpdf_oh_release_all(qpdf);
678   - assert(! qpdf_oh_is_null(qpdf, mediabox));
679   - assert(! qpdf_oh_is_array(qpdf, mediabox));
680   - /* Make sure something is assigned when we exit so we check that
681   - * it gets properl freed.
682   - */
683   - qpdf_get_root(qpdf);
684   -
685 707 qpdf_init_write(qpdf, outfile);
686 708 qpdf_set_static_ID(qpdf, QPDF_TRUE);
687 709 qpdf_set_qdf_mode(qpdf, QPDF_TRUE);
688 710 qpdf_set_suppress_original_object_IDs(qpdf, QPDF_TRUE);
689 711 qpdf_write(qpdf);
690 712 report_errors();
691   -
  713 +}
  714 +static void test26(char const* infile,
  715 + char const* password,
  716 + char const* outfile,
  717 + char const* outfile2)
  718 +{
692 719 /* Make sure we detect uninitialized objects */
693 720 qpdf_data qpdf2 = qpdf_init();
694   - trailer = qpdf_get_trailer(qpdf2);
  721 + qpdf_oh trailer = qpdf_get_trailer(qpdf2);
695 722 assert(! qpdf_oh_is_initialized(qpdf2, trailer));
696 723 qpdf_cleanup(&qpdf2);
697 724 }
698 725  
  726 +static void test27(char const* infile,
  727 + char const* password,
  728 + char const* outfile,
  729 + char const* outfile2)
  730 +{
  731 + /* Exercise a string with a null. Since the regular methods return
  732 + * char*, we can't see past the null character without looking
  733 + * explicitly at the length.
  734 + */
  735 + qpdf_oh p_string_with_null = qpdf_oh_parse(qpdf, "<6f6e650074776f>");
  736 + assert(qpdf_oh_is_string(qpdf, p_string_with_null));
  737 + assert(strcmp(qpdf_oh_get_string_value(qpdf, p_string_with_null),
  738 + "one") == 0);
  739 + assert(qpdf_get_last_string_length(qpdf) == 7);
  740 + assert(memcmp(qpdf_oh_get_string_value(qpdf, p_string_with_null),
  741 + "one\000two", 7) == 0);
  742 +}
  743 +
  744 +static void test28(char const* infile,
  745 + char const* password,
  746 + char const* outfile,
  747 + char const* outfile2)
  748 +{
  749 + /* This test case is designed for minimal.pdf. */
  750 +
  751 + /* Look at the media box. The media box is in array. Trivially
  752 + * wrap it and also clone it and make sure we get different
  753 + * handles with the same contents.
  754 + */
  755 + qpdf_read(qpdf, infile, password);
  756 + qpdf_oh root = qpdf_get_root(qpdf);
  757 + qpdf_oh pages = qpdf_oh_get_key(qpdf, root, "/Pages");
  758 + qpdf_oh kids = qpdf_oh_get_key(qpdf, pages, "/Kids");
  759 + qpdf_oh page1 = qpdf_oh_get_array_item(qpdf, kids, 0);
  760 + qpdf_oh mediabox = qpdf_oh_get_key(qpdf, page1, "/MediaBox");
  761 + qpdf_oh wrapped_mediabox = qpdf_oh_wrap_in_array(qpdf, mediabox);
  762 + qpdf_oh cloned_mediabox = qpdf_oh_new_object(qpdf, mediabox);
  763 + assert(wrapped_mediabox != mediabox);
  764 + assert(cloned_mediabox != mediabox);
  765 + assert(qpdf_oh_get_array_n_items(qpdf, wrapped_mediabox) == 4);
  766 + for (int i = 0; i < 4; ++i)
  767 + {
  768 + qpdf_oh item = qpdf_oh_get_array_item(qpdf, mediabox, i);
  769 + qpdf_oh item2 = qpdf_oh_get_array_item(qpdf, wrapped_mediabox, i);
  770 + qpdf_oh item3 = qpdf_oh_get_array_item(qpdf, cloned_mediabox, i);
  771 + assert(qpdf_oh_get_int_value_as_int(qpdf, item) ==
  772 + (i == 0 ? 0 :
  773 + i == 1 ? 0 :
  774 + i == 2 ? 612 :
  775 + i == 3 ? 792 :
  776 + -1));
  777 + assert(qpdf_oh_get_int_value_as_int(qpdf, item) ==
  778 + qpdf_oh_get_int_value_as_int(qpdf, item2));
  779 + assert(qpdf_oh_get_int_value_as_int(qpdf, item) ==
  780 + qpdf_oh_get_int_value_as_int(qpdf, item3));
  781 + qpdf_oh_release(qpdf, item);
  782 + }
  783 +}
  784 +
699 785 int main(int argc, char* argv[])
700 786 {
701 787 char* p = 0;
... ... @@ -760,6 +846,10 @@ int main(int argc, char* argv[])
760 846 (n == 22) ? test22 :
761 847 (n == 23) ? test23 :
762 848 (n == 24) ? test24 :
  849 + (n == 25) ? test25 :
  850 + (n == 26) ? test26 :
  851 + (n == 27) ? test27 :
  852 + (n == 28) ? test28 :
763 853 0);
764 854  
765 855 if (fn == 0)
... ...
qpdf/qtest/qpdf.test
... ... @@ -4808,18 +4808,38 @@ foreach my $i (@c_check_types)
4808 4808 show_ntests();
4809 4809 # ----------
4810 4810 $td->notify("--- C API Object Handle ---");
4811   -$n_tests += scalar(@c_check_types);
  4811 +$n_tests += 7;
4812 4812  
4813 4813 $td->runtest("C check object handles",
4814 4814 {$td->COMMAND => "qpdf-ctest 24 minimal.pdf '' a.pdf"},
4815 4815 {$td->FILE => "c-object-handles.out",
4816 4816 $td->EXIT_STATUS => 0},
4817 4817 $td->NORMALIZE_NEWLINES);
4818   -
4819 4818 $td->runtest("check output",
4820 4819 {$td->FILE => 'a.pdf'},
4821 4820 {$td->FILE => 'c-object-handles-out.pdf'});
4822 4821  
  4822 +$td->runtest("C check object handle creation",
  4823 + {$td->COMMAND => "qpdf-ctest 25 minimal.pdf '' a.pdf"},
  4824 + {$td->STRING => "", $td->EXIT_STATUS => 0},
  4825 + $td->NORMALIZE_NEWLINES);
  4826 +$td->runtest("check output",
  4827 + {$td->FILE => 'a.pdf'},
  4828 + {$td->FILE => 'c-object-handle-creation-out.pdf'});
  4829 +
  4830 +$td->runtest("C uninitialized objects",
  4831 + {$td->COMMAND => "qpdf-ctest 26 '' '' ''"},
  4832 + {$td->STRING => "", $td->EXIT_STATUS => 0},
  4833 + $td->NORMALIZE_NEWLINES);
  4834 +$td->runtest("C string with embedded null",
  4835 + {$td->COMMAND => "qpdf-ctest 27 '' '' ''"},
  4836 + {$td->STRING => "", $td->EXIT_STATUS => 0},
  4837 + $td->NORMALIZE_NEWLINES);
  4838 +$td->runtest("C wrap and clone objects",
  4839 + {$td->COMMAND => "qpdf-ctest 28 minimal.pdf '' ''"},
  4840 + {$td->STRING => "", $td->EXIT_STATUS => 0},
  4841 + $td->NORMALIZE_NEWLINES);
  4842 +
4823 4843 show_ntests();
4824 4844 # ----------
4825 4845 $td->notify("--- Content Preservation Tests ---");
... ...
qpdf/qtest/qpdf/c-object-handle-creation-out.pdf 0 โ†’ 100644
  1 +%PDF-1.3
  2 +%ยฟรทยขรพ
  3 +%QDF-1.0
  4 +
  5 +1 0 obj
  6 +<<
  7 + /Pages 2 0 R
  8 + /QTest <<
  9 + /B [
  10 + (potato)
  11 + <feff00710077007700f703c0>
  12 + /Quack
  13 + null
  14 + 4.12
  15 + 5.0
  16 + 6
  17 + true
  18 + ]
  19 + /C <<
  20 + >>
  21 + >>
  22 + /Type /Catalog
  23 +>>
  24 +endobj
  25 +
  26 +2 0 obj
  27 +<<
  28 + /Count 1
  29 + /Kids [
  30 + 3 0 R
  31 + ]
  32 + /Type /Pages
  33 +>>
  34 +endobj
  35 +
  36 +%% Page 1
  37 +3 0 obj
  38 +<<
  39 + /Contents 4 0 R
  40 + /MediaBox [
  41 + 0
  42 + 0
  43 + 612
  44 + 792
  45 + ]
  46 + /Parent 2 0 R
  47 + /Resources <<
  48 + /Font <<
  49 + /F1 6 0 R
  50 + >>
  51 + /ProcSet 7 0 R
  52 + >>
  53 + /Type /Page
  54 +>>
  55 +endobj
  56 +
  57 +%% Contents for page 1
  58 +4 0 obj
  59 +<<
  60 + /Length 5 0 R
  61 +>>
  62 +stream
  63 +BT
  64 + /F1 24 Tf
  65 + 72 720 Td
  66 + (Potato) Tj
  67 +ET
  68 +endstream
  69 +endobj
  70 +
  71 +5 0 obj
  72 +44
  73 +endobj
  74 +
  75 +6 0 obj
  76 +<<
  77 + /BaseFont /Helvetica
  78 + /Encoding /WinAnsiEncoding
  79 + /Name /F1
  80 + /Subtype /Type1
  81 + /Type /Font
  82 +>>
  83 +endobj
  84 +
  85 +7 0 obj
  86 +[
  87 + /PDF
  88 + /Text
  89 +]
  90 +endobj
  91 +
  92 +xref
  93 +0 8
  94 +0000000000 65535 f
  95 +0000000025 00000 n
  96 +0000000240 00000 n
  97 +0000000322 00000 n
  98 +0000000537 00000 n
  99 +0000000636 00000 n
  100 +0000000655 00000 n
  101 +0000000773 00000 n
  102 +trailer <<
  103 + /Root 1 0 R
  104 + /Size 8
  105 + /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
  106 +>>
  107 +startxref
  108 +808
  109 +%%EOF
... ...
qpdf/qtest/qpdf/c-object-handles-out.pdf
... ... @@ -5,20 +5,6 @@
5 5 1 0 obj
6 6 <<
7 7 /Pages 2 0 R
8   - /QTest <<
9   - /B [
10   - (potato)
11   - <feff00710077007700f703c0>
12   - /Quack
13   - null
14   - 4.12
15   - 5.0
16   - 6
17   - true
18   - ]
19   - /C <<
20   - >>
21   - >>
22 8 /Type /Catalog
23 9 >>
24 10 endobj
... ... @@ -89,16 +75,16 @@ xref
89 75 0 7
90 76 0000000000 65535 f
91 77 0000000025 00000 n
92   -0000000240 00000 n
93   -0000000322 00000 n
94   -0000000562 00000 n
95   -0000000661 00000 n
96   -0000000680 00000 n
  78 +0000000079 00000 n
  79 +0000000161 00000 n
  80 +0000000401 00000 n
  81 +0000000500 00000 n
  82 +0000000519 00000 n
97 83 trailer <<
98 84 /Root 1 0 R
99 85 /Size 7
100 86 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
101 87 >>
102 88 startxref
103   -798
  89 +637
104 90 %%EOF
... ...