TestPDF.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * Copyright (c) 2021, Simon Woertz <simon@woertz.at>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/ByteString.h>
  7. #include <AK/Forward.h>
  8. #include <LibCore/MappedFile.h>
  9. #include <LibPDF/CommonNames.h>
  10. #include <LibPDF/Document.h>
  11. #include <LibPDF/Function.h>
  12. #include <LibTest/Macros.h>
  13. #include <LibTest/TestCase.h>
  14. TEST_CASE(linearized_pdf)
  15. {
  16. auto file = MUST(Core::MappedFile::map("linearized.pdf"sv));
  17. auto document = MUST(PDF::Document::create(file->bytes()));
  18. MUST(document->initialize());
  19. EXPECT_EQ(document->get_page_count(), 1U);
  20. }
  21. TEST_CASE(non_linearized_pdf)
  22. {
  23. auto file = MUST(Core::MappedFile::map("non-linearized.pdf"sv));
  24. auto document = MUST(PDF::Document::create(file->bytes()));
  25. MUST(document->initialize());
  26. EXPECT_EQ(document->get_page_count(), 1U);
  27. }
  28. TEST_CASE(complex_pdf)
  29. {
  30. auto file = MUST(Core::MappedFile::map("complex.pdf"sv));
  31. auto document = MUST(PDF::Document::create(file->bytes()));
  32. MUST(document->initialize());
  33. EXPECT_EQ(document->get_page_count(), 3U);
  34. }
  35. TEST_CASE(empty_file_issue_10702)
  36. {
  37. AK::ReadonlyBytes empty;
  38. auto document = PDF::Document::create(empty);
  39. EXPECT(document.is_error());
  40. }
  41. TEST_CASE(encodig)
  42. {
  43. auto file = MUST(Core::MappedFile::map("encoding.pdf"sv));
  44. auto document = MUST(PDF::Document::create(file->bytes()));
  45. MUST(document->initialize());
  46. EXPECT_EQ(document->get_page_count(), 1U);
  47. auto info_dict = MUST(document->info_dict()).value();
  48. EXPECT_EQ(MUST(info_dict.author()).value(), "Nico Weber");
  49. EXPECT_EQ(MUST(info_dict.producer()).value(), (char const*)u8"Manüally Created");
  50. EXPECT_EQ(MUST(info_dict.title()).value(), (char const*)u8"Êñ©•ding test");
  51. auto outline_dict = document->outline();
  52. EXPECT_EQ(outline_dict->count, 3u);
  53. EXPECT_EQ(outline_dict->children[0]->title, (char const*)u8"Titlè 1");
  54. EXPECT_EQ(outline_dict->children[1]->title, (char const*)u8"Titlè 2");
  55. EXPECT_EQ(outline_dict->children[2]->title, (char const*)u8"Titlè 3");
  56. }
  57. TEST_CASE(truncated_pdf_header_issue_10717)
  58. {
  59. AK::ByteString string { "%PDF-2.11%" };
  60. auto document = PDF::Document::create(string.bytes());
  61. EXPECT(document.is_error());
  62. }
  63. TEST_CASE(encrypted_with_aes)
  64. {
  65. auto file = MUST(Core::MappedFile::map("password-is-sup.pdf"sv));
  66. auto document = MUST(PDF::Document::create(file->bytes()));
  67. EXPECT(document->security_handler()->try_provide_user_password("sup"sv));
  68. MUST(document->initialize());
  69. EXPECT_EQ(document->get_page_count(), 1U);
  70. auto info_dict = MUST(document->info_dict()).value();
  71. EXPECT_EQ(MUST(info_dict.title()).value(), "sup");
  72. EXPECT_EQ(MUST(info_dict.creator()).value(), "TextEdit");
  73. }
  74. TEST_CASE(encrypted_object_stream)
  75. {
  76. auto file = MUST(Core::MappedFile::map("encryption_nocopy.pdf"sv));
  77. auto document = MUST(PDF::Document::create(file->bytes()));
  78. MUST(document->initialize());
  79. EXPECT_EQ(document->get_page_count(), 1U);
  80. auto info_dict = MUST(document->info_dict()).value();
  81. EXPECT_EQ(MUST(info_dict.author()).value(), "van der Knijff");
  82. EXPECT_EQ(MUST(info_dict.creator()).value(), "Acrobat PDFMaker 9.1 voor Word");
  83. }
  84. TEST_CASE(malformed_pdf_document)
  85. {
  86. Array test_inputs = {
  87. "oss-fuzz-testcase-62065.pdf"sv
  88. };
  89. for (auto test_input : test_inputs) {
  90. auto file = MUST(Core::MappedFile::map(test_input));
  91. auto document_or_error = PDF::Document::create(file->bytes());
  92. EXPECT(document_or_error.is_error());
  93. }
  94. }
  95. static PDF::Value make_array(Vector<float> floats)
  96. {
  97. Vector<PDF::Value> values;
  98. for (auto f : floats)
  99. values.append(PDF::Value { f });
  100. return PDF::Value { make_object<PDF::ArrayObject>(move(values)) };
  101. }
  102. static PDF::PDFErrorOr<NonnullRefPtr<PDF::Function>> make_function(int type, ReadonlyBytes data, Vector<float> domain, Vector<float> range, Function<void(HashMap<DeprecatedFlyString, PDF::Value>&)> extra_keys = nullptr)
  103. {
  104. HashMap<DeprecatedFlyString, PDF::Value> map;
  105. map.set(PDF::CommonNames::FunctionType, PDF::Value { type });
  106. map.set(PDF::CommonNames::Domain, make_array(move(domain)));
  107. map.set(PDF::CommonNames::Range, make_array(move(range)));
  108. if (extra_keys)
  109. extra_keys(map);
  110. auto dict = make_object<PDF::DictObject>(move(map));
  111. auto stream = make_object<PDF::StreamObject>(dict, MUST(ByteBuffer::copy(data)));
  112. // document isn't used for anything, but UBSan complains about a (harmless) method call on a null object without it.
  113. auto file = MUST(Core::MappedFile::map("linearized.pdf"sv));
  114. auto document = MUST(PDF::Document::create(file->bytes()));
  115. return PDF::Function::create(document, stream);
  116. }
  117. static PDF::PDFErrorOr<NonnullRefPtr<PDF::Function>> make_sampled_function(ReadonlyBytes data, Vector<float> domain, Vector<float> range, Vector<float> sizes)
  118. {
  119. return make_function(0, data, move(domain), move(range), [&sizes](auto& map) {
  120. map.set(PDF::CommonNames::Size, make_array(sizes));
  121. map.set(PDF::CommonNames::BitsPerSample, PDF::Value { 8 });
  122. });
  123. }
  124. TEST_CASE(sampled)
  125. {
  126. auto f1 = MUST(make_sampled_function(Vector<u8> { { 0, 255, 0 } }, { 0.0f, 1.0f }, { 0.0f, 10.0f }, { 3 }));
  127. EXPECT_EQ(MUST(f1->evaluate(Vector<float> { 0.0f })), Vector<float> { 0.0f });
  128. EXPECT_EQ(MUST(f1->evaluate(Vector<float> { 0.25f })), Vector<float> { 5.0f });
  129. EXPECT_EQ(MUST(f1->evaluate(Vector<float> { 0.5f })), Vector<float> { 10.0f });
  130. EXPECT_EQ(MUST(f1->evaluate(Vector<float> { 0.75f })), Vector<float> { 5.0f });
  131. EXPECT_EQ(MUST(f1->evaluate(Vector<float> { 1.0f })), Vector<float> { 0.0f });
  132. auto f2 = MUST(make_sampled_function(Vector<u8> { { 0, 255, 255, 0, 0, 255 } }, { 0.0f, 1.0f }, { 0.0f, 10.0f, 0.0f, 8.0f }, { 3 }));
  133. EXPECT_EQ(MUST(f2->evaluate(Vector<float> { 0.0f })), (Vector<float> { 0.0f, 8.0f }));
  134. EXPECT_EQ(MUST(f2->evaluate(Vector<float> { 0.25f })), (Vector<float> { 5.0f, 4.0f }));
  135. EXPECT_EQ(MUST(f2->evaluate(Vector<float> { 0.5f })), (Vector<float> { 10.0f, 0.0f }));
  136. EXPECT_EQ(MUST(f2->evaluate(Vector<float> { 0.75f })), (Vector<float> { 5.0f, 4.0f }));
  137. EXPECT_EQ(MUST(f2->evaluate(Vector<float> { 1.0f })), (Vector<float> { 0.0f, 8.0f }));
  138. auto f3 = MUST(make_sampled_function(Vector<u8> { { 0, 255, 0, 255, 0, 255 } }, { 0.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 10.0f }, { 3, 2 }));
  139. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.0f, 0.0f })), Vector<float> { 0.0f });
  140. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.25f, 0.0f })), Vector<float> { 5.0f });
  141. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.5f, 0.0f })), Vector<float> { 10.0f });
  142. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.75f, 0.0f })), Vector<float> { 5.0f });
  143. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 1.0f, 0.0f })), Vector<float> { 0.0f });
  144. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.0f, 0.5f })), Vector<float> { 5.0f });
  145. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.25f, 0.5f })), Vector<float> { 5.0f });
  146. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.5f, 0.5f })), Vector<float> { 5.0f });
  147. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.75f, 0.5f })), Vector<float> { 5.0f });
  148. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 1.0f, 0.5f })), Vector<float> { 5.0f });
  149. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.0f, 1.0f })), Vector<float> { 10.0f });
  150. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.25f, 1.0f })), Vector<float> { 5.0f });
  151. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.5f, 1.0f })), Vector<float> { 0.0f });
  152. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 0.75f, 1.0f })), Vector<float> { 5.0f });
  153. EXPECT_EQ(MUST(f3->evaluate(Vector<float> { 1.0f, 1.0f })), Vector<float> { 10.0f });
  154. auto f4 = MUST(make_sampled_function(Vector<u8> { { 0, 255, 255, 0, 0, 255, 255, 0 } }, { 0.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 10.0f, 0.0f, 8.0f }, { 2, 2 }));
  155. EXPECT_EQ(MUST(f4->evaluate(Vector<float> { 0.0f, 0.0f })), (Vector<float> { 0.0f, 8.0f }));
  156. EXPECT_EQ(MUST(f4->evaluate(Vector<float> { 0.5f, 0.5f })), (Vector<float> { 5.0f, 4.0f }));
  157. }
  158. static PDF::PDFErrorOr<NonnullRefPtr<PDF::Function>> make_postscript_function(StringView program, Vector<float> domain, Vector<float> range)
  159. {
  160. return make_function(4, program.bytes(), move(domain), move(range));
  161. }
  162. static NonnullRefPtr<PDF::Function> check_postscript_function(StringView program, Vector<float> domain, Vector<float> range)
  163. {
  164. auto function = make_postscript_function(program, move(domain), move(range));
  165. if (function.is_error())
  166. FAIL(function.error().message());
  167. return function.value();
  168. }
  169. static void check_evaluate(StringView program, Vector<float> inputs, Vector<float> outputs)
  170. {
  171. Vector<float> domain;
  172. for (size_t i = 0; i < inputs.size(); ++i) {
  173. domain.append(-100.0f);
  174. domain.append(100.0f);
  175. }
  176. Vector<float> range;
  177. for (size_t i = 0; i < outputs.size(); ++i) {
  178. range.append(-100.0f);
  179. range.append(100.0f);
  180. }
  181. auto function = check_postscript_function(program, domain, range);
  182. auto result = function->evaluate(inputs);
  183. if (result.is_error())
  184. FAIL(result.error().message());
  185. EXPECT_EQ(result.value(), outputs);
  186. }
  187. TEST_CASE(postscript)
  188. {
  189. // Arithmetic operators
  190. check_evaluate("{ abs }"sv, { 0.5f }, { 0.5f });
  191. check_evaluate("{ add }"sv, { 0.25f, 0.5f }, { 0.75f });
  192. check_evaluate("{ atan }"sv, { 1.0f, 0.01f }, { AK::to_degrees(atan2f(0.01f, 1.0f)) });
  193. check_evaluate("{ ceiling }"sv, { 0.5f }, { 1.0f });
  194. check_evaluate("{ cos }"sv, { 1.0f }, { cosf(AK::to_radians(1.0f)) });
  195. check_evaluate("{ cvi }"sv, { 0.5f }, { 0.0f });
  196. check_evaluate("{ cvr }"sv, { 0.5f }, { 0.5f });
  197. check_evaluate("{ div }"sv, { 0.5f, 1.0f }, { 0.5f });
  198. check_evaluate("{ exp }"sv, { 0.0f }, { 1.0f });
  199. check_evaluate("{ floor }"sv, { 0.5f }, { 0.0f });
  200. check_evaluate("{ idiv }"sv, { 0.5f, 1.0f }, { 0.0f });
  201. check_evaluate("{ ln }"sv, { 10.0f }, { logf(10.0f) });
  202. check_evaluate("{ log }"sv, { 10.0f }, { log10f(10.0f) });
  203. check_evaluate("{ mod }"sv, { 0.5f, 0.25f }, { 0.0f });
  204. check_evaluate("{ mul }"sv, { 0.5f, 0.25f }, { 0.125f });
  205. check_evaluate("{ neg }"sv, { 0.5f }, { -0.5f });
  206. check_evaluate("{ round }"sv, { 0.5f }, { 1.0f });
  207. check_evaluate("{ sin }"sv, { 1.0f }, { sinf(AK::to_radians(1.0f)) });
  208. check_evaluate("{ sqrt }"sv, { 0.5f }, { sqrtf(0.5f) });
  209. check_evaluate("{ sub }"sv, { 0.5f, 0.25f }, { 0.25f });
  210. check_evaluate("{ truncate }"sv, { 0.5f }, { 0.0f });
  211. // Relational, boolean, and bitwise operators
  212. check_evaluate("{ and }"sv, { 0.0f, 1.0f }, { 0.0f });
  213. check_evaluate("{ bitshift }"sv, { 1.0f, 3.0f }, { 8.0f });
  214. check_evaluate("{ bitshift }"sv, { 8.0f, -2.0f }, { 2.0f });
  215. check_evaluate("{ eq }"sv, { 0.5f, 0.5f }, { 1.0f });
  216. check_evaluate("{ ge }"sv, { 0.5f, 0.5f }, { 1.0f });
  217. check_evaluate("{ gt }"sv, { 0.5f, 0.5f }, { 0.0f });
  218. check_evaluate("{ le }"sv, { 0.5f, 0.5f }, { 1.0f });
  219. check_evaluate("{ lt }"sv, { 0.5f, 0.5f }, { 0.0f });
  220. check_evaluate("{ ne }"sv, { 0.5f, 0.5f }, { 0.0f });
  221. check_evaluate("{ not }"sv, { 0.5f }, { 0.0f });
  222. check_evaluate("{ or }"sv, { 0.0f, 1.0f }, { 1.0f });
  223. check_evaluate("{ xor }"sv, { 0.0f, 1.0f }, { 1.0f });
  224. // Conditional operators
  225. check_evaluate("{ { 4 } if }"sv, { 1.0f }, { 4.0f });
  226. check_evaluate("{ { 4 } if }"sv, { 0.0f }, {});
  227. check_evaluate("{ { 4 } { 5 } ifelse }"sv, { 1.0f }, { 4.0f });
  228. check_evaluate("{ { 4 } { 5 } ifelse }"sv, { 0.0f }, { 5.0f });
  229. // Stack operators
  230. check_evaluate("{ 2 copy }"sv, { 8.0f, 0.5f, 1.0f }, { 8.0f, 0.5f, 1.0f, 0.5f, 1.0f });
  231. check_evaluate("{ dup }"sv, { 1.0f, 0.5f }, { 1.0f, 0.5f, 0.5f });
  232. check_evaluate("{ exch }"sv, { 8.0f, 1.0f, 0.5f }, { 8.0f, 0.5f, 1.0f });
  233. check_evaluate("{ 1 index }"sv, { 8.0f, 1.0f, 0.5f }, { 8.0f, 1.0f, 0.5f, 1.0f });
  234. check_evaluate("{ pop }"sv, { 8.0f, 1.0f, 0.5f }, { 8.0f, 1.0f });
  235. check_evaluate("{ 3 1 roll }"sv, { 0.5f, 1.0f, 2.0f }, { 2.0f, 0.5f, 1.0f });
  236. check_evaluate("{ 3 -1 roll }"sv, { 0.5f, 1.0f, 2.0f }, { 1.0f, 2.0f, 0.5f });
  237. }