| // Copyright 2026 Google LLC | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // https://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| // | |
| #include "formats/pdf/extractor.h" | |
| #include <string> | |
| #include "absl/status/status.h" | |
| #include "absl/status/status_matchers.h" | |
| #include "absl/strings/string_view.h" | |
| #include "formats/byte_range.h" | |
| #include "gmock/gmock.h" | |
| #include "gtest/gtest.h" | |
| #include "riegeli/bytes/string_reader.h" | |
| namespace credentio { | |
| namespace { | |
| using ::absl_testing::StatusIs; | |
| using ::testing::HasSubstr; | |
| using ::testing::Optional; | |
| #ifndef ASSERT_OK_AND_ASSIGN | |
| #define ASSERT_OK_AND_ASSIGN_CONCAT2(x, y) x##y | |
| #define ASSERT_OK_AND_ASSIGN_CONCAT(x, y) ASSERT_OK_AND_ASSIGN_CONCAT2(x, y) | |
| #define ASSERT_OK_AND_ASSIGN(lhs, rexpr) \ | |
| ASSERT_OK_AND_ASSIGN_IMPL(lhs, rexpr, __COUNTER__) | |
| #define ASSERT_OK_AND_ASSIGN_IMPL(lhs, rexpr, id) \ | |
| auto ASSERT_OK_AND_ASSIGN_CONCAT(status_or_, id) = (rexpr); \ | |
| ASSERT_THAT(ASSERT_OK_AND_ASSIGN_CONCAT(status_or_, id), \ | |
| ::absl_testing::IsOk()); \ | |
| lhs = std::move(*ASSERT_OK_AND_ASSIGN_CONCAT(status_or_, id)) | |
| #endif | |
| constexpr absl::string_view kTestPdfContent = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /C2PA_Manifest /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</Names [(content_credential.c2pa) 3 0 R]>>\n" | |
| "endobj\n" | |
| "5 0 obj\n" | |
| "<</EmbeddedFiles 4 0 R>>\n" | |
| "endobj\n" | |
| "6 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names 5 0 R>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 7\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "0000000327 00000 n \n" | |
| "0000000367 00000 n \n" | |
| "trailer\n" | |
| "<</Root 6 0 R>>\n" | |
| "startxref\n" | |
| "426\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentNoC2paSubtype = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /C2PA_Manifest /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</Names [(content_credential.c2pa) 3 0 R]>>\n" | |
| "endobj\n" | |
| "5 0 obj\n" | |
| "<</EmbeddedFiles 4 0 R>>\n" | |
| "endobj\n" | |
| "6 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names 5 0 R>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 7\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000155 00000 n \n" | |
| "0000000238 00000 n \n" | |
| "0000000298 00000 n \n" | |
| "0000000338 00000 n \n" | |
| "trailer\n" | |
| "<</Root 6 0 R>>\n" | |
| "startxref\n" | |
| "397\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentNoEmbeddedFilesRef = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /C2PA_Manifest /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</Names [(not_a_c2pa_manifest.txt) 1 0 R]>>\n" | |
| "endobj\n" | |
| "5 0 obj\n" | |
| "<</EmbeddedFiles 4 0 R>>\n" | |
| "endobj\n" | |
| "6 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names 5 0 R>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 7\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "0000000327 00000 n \n" | |
| "0000000367 00000 n \n" | |
| "trailer\n" | |
| "<</Root 6 0 R>>\n" | |
| "startxref\n" | |
| "426\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentNamesNotDict = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /C2PA_Manifest /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names [1 0 R]>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 5\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "trailer\n" | |
| "<</Root 4 0 R>>\n" | |
| "startxref\n" | |
| "328\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentEmbeddedFilesDirect = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /C2PA_Manifest /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names <</EmbeddedFiles <</Names " | |
| "[(content_credential.c2pa) 3 0 R]>> >> >>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 5\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "trailer\n" | |
| "<</Root 4 0 R>>\n" | |
| "startxref\n" | |
| "386\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentNoAfRelationship = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</Names [(content_credential.c2pa) 3 0 R]>>\n" | |
| "endobj\n" | |
| "5 0 obj\n" | |
| "<</EmbeddedFiles 4 0 R>>\n" | |
| "endobj\n" | |
| "6 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names 5 0 R>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 7\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "0000000327 00000 n \n" | |
| "0000000367 00000 n \n" | |
| "trailer\n" | |
| "<</Root 6 0 R>>\n" | |
| "startxref\n" | |
| "426\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentDifferentAfRelationship = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /Other /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</Names [(content_credential.c2pa) 3 0 R]>>\n" | |
| "endobj\n" | |
| "5 0 obj\n" | |
| "<</EmbeddedFiles 4 0 R>>\n" | |
| "endobj\n" | |
| "6 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names 5 0 R>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 7\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "0000000327 00000 n \n" | |
| "0000000367 00000 n \n" | |
| "trailer\n" | |
| "<</Root 6 0 R>>\n" | |
| "startxref\n" | |
| "426\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentNonIndirectAf = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /C2PA_Manifest /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</Names [(content_credential.c2pa) 3 0 R]>>\n" | |
| "endobj\n" | |
| "5 0 obj\n" | |
| "<</EmbeddedFiles 4 0 R>>\n" | |
| "endobj\n" | |
| "6 0 obj\n" | |
| "<</AF [123 ] /Type /Catalog /Names 5 0 R>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 7\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "0000000327 00000 n \n" | |
| "0000000367 00000 n \n" | |
| "trailer\n" | |
| "<</Root 6 0 R>>\n" | |
| "startxref\n" | |
| "426\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentInvalidEmbeddedFilesType = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /C2PA_Manifest /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</Names [(content_credential.c2pa) 3 0 R]>>\n" | |
| "endobj\n" | |
| "5 0 obj\n" | |
| "<</EmbeddedFiles 12345>>\n" | |
| "endobj\n" | |
| "6 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names 5 0 R>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 7\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "0000000327 00000 n \n" | |
| "0000000367 00000 n \n" | |
| "trailer\n" | |
| "<</Root 6 0 R>>\n" | |
| "startxref\n" | |
| "426\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentNamesDictNotDict = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /C2PA_Manifest /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</Names [(content_credential.c2pa) 3 0 R]>>\n" | |
| "endobj\n" | |
| "5 0 obj\n" | |
| "12345 \n" | |
| "endobj\n" | |
| "6 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names 5 0 R>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 7\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "0000000327 00000 n \n" | |
| "0000000367 00000 n \n" | |
| "trailer\n" | |
| "<</Root 6 0 R>>\n" | |
| "startxref\n" | |
| "426\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentNoEmbeddedFiles = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /C2PA_Manifest /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</Names [(content_credential.c2pa) 3 0 R]>>\n" | |
| "endobj\n" | |
| "5 0 obj\n" | |
| "<</OtherFiles___ 4 0 R>>\n" | |
| "endobj\n" | |
| "6 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names 5 0 R>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 7\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "0000000327 00000 n \n" | |
| "0000000367 00000 n \n" | |
| "trailer\n" | |
| "<</Root 6 0 R>>\n" | |
| "startxref\n" | |
| "426\n" | |
| "%%EOF"; | |
| constexpr absl::string_view kTestPdfContentNamesObjectNotFound = | |
| "%PDF-1.7\n" | |
| "%%%%%\n" | |
| "1 0 obj\n" | |
| "<</Length 11>>\n" | |
| "stream\n" | |
| "test_stream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "2 0 obj\n" | |
| "<</Length 33 /Subtype /application#2fc2pa>>\n" | |
| "stream\n" | |
| "test_c2pa_manifest_raw_bytestream\n" | |
| "endstream\n" | |
| "endobj\n" | |
| "3 0 obj\n" | |
| "<</EF <</F 2 0 R>> /AFRelationship /C2PA_Manifest /Type /FileSpec>>\n" | |
| "endobj\n" | |
| "4 0 obj\n" | |
| "<</Names [(content_credential.c2pa) 3 0 R]>>\n" | |
| "endobj\n" | |
| "5 0 obj\n" | |
| "<</EmbeddedFiles 4 0 R>>\n" | |
| "endobj\n" | |
| "6 0 obj\n" | |
| "<</AF [3 0 R] /Type /Catalog /Names 9 0 R>>\n" | |
| "endobj\n" | |
| "xref\n" | |
| "0 7\n" | |
| "0000000000 65535 f \n" | |
| "0000000015 00000 n \n" | |
| "0000000074 00000 n \n" | |
| "0000000184 00000 n \n" | |
| "0000000267 00000 n \n" | |
| "0000000327 00000 n \n" | |
| "0000000367 00000 n \n" | |
| "trailer\n" | |
| "<</Root 6 0 R>>\n" | |
| "startxref\n" | |
| "426\n" | |
| "%%EOF"; | |
| TEST(PdfExtractorTest, ExtractManifestStoreV22EmbeddedFilesDirect) { | |
| riegeli::StringReader<> input(kTestPdfContentEmbeddedFilesDirect); | |
| PdfExtractor extractor; | |
| ASSERT_OK_AND_ASSIGN(auto manifest_store, | |
| extractor.ExtractManifestStore(input)); | |
| EXPECT_THAT(manifest_store, "test_c2pa_manifest_raw_bytestream"); | |
| } | |
| TEST(PdfExtractorTest, ExtractManifestStoreV22) { | |
| riegeli::StringReader<> input(kTestPdfContent); | |
| PdfExtractor extractor; | |
| ASSERT_OK_AND_ASSIGN(auto manifest_store, | |
| extractor.ExtractManifestStore(input)); | |
| EXPECT_THAT(manifest_store, "test_c2pa_manifest_raw_bytestream"); | |
| } | |
| TEST(PdfExtractorTest, ExtractManifestStoreNoSubtype) { | |
| riegeli::StringReader<> input(kTestPdfContentNoC2paSubtype); | |
| PdfExtractor extractor; | |
| ASSERT_OK_AND_ASSIGN(auto manifest_store, | |
| extractor.ExtractManifestStore(input)); | |
| EXPECT_THAT(manifest_store, "test_c2pa_manifest_raw_bytestream"); | |
| } | |
| TEST(PdfExtractorTest, | |
| ExtractManifestStoreThrowNotFoundErrorIfNoEmbeddedFilesRef) { | |
| riegeli::StringReader<> input(kTestPdfContentNoEmbeddedFilesRef); | |
| PdfExtractor extractor; | |
| EXPECT_THAT(extractor.ExtractManifestStore(input), | |
| StatusIs(absl::StatusCode::kNotFound)); | |
| } | |
| TEST(PdfExtractorTest, ExtractManifestStoreLocation) { | |
| riegeli::StringReader<> input(kTestPdfContent); | |
| PdfExtractor extractor; | |
| ASSERT_OK_AND_ASSIGN( | |
| auto manifest_store_location, | |
| extractor.ExtractManifestStoreLocation(input, {.requires_c2pa = true})); | |
| EXPECT_THAT(manifest_store_location, | |
| Optional(ByteRange{.offset = 74, .length = 109})); | |
| } | |
| TEST(PdfExtractorTest, ExtractManifestStoreLocationNoSubtype) { | |
| riegeli::StringReader<> input(kTestPdfContentNoC2paSubtype); | |
| PdfExtractor extractor; | |
| ASSERT_OK_AND_ASSIGN( | |
| auto manifest_store_location, | |
| extractor.ExtractManifestStoreLocation(input, {.requires_c2pa = true})); | |
| EXPECT_THAT(manifest_store_location, | |
| Optional(ByteRange{.offset = 74, .length = 80})); | |
| } | |
| TEST(PdfExtractorTest, ExtractManifestStoreFailsWithInvalidNamesType) { | |
| riegeli::StringReader<> input(kTestPdfContentNamesNotDict); | |
| PdfExtractor extractor; | |
| EXPECT_THAT( | |
| extractor.ExtractManifestStore(input), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| ::testing::AllOf(HasSubstr("Unexpected object type found."), | |
| HasSubstr("credentio::Object::")))); | |
| } | |
| TEST(PdfExtractorTest, ExtractBoxesUnimplemented) { | |
| riegeli::StringReader<> input("test_content"); | |
| PdfExtractor extractor; | |
| EXPECT_THAT(extractor.ExtractBoxes(input, {.requires_c2pa = true}), | |
| StatusIs(absl::StatusCode::kUnimplemented)); | |
| } | |
| TEST(PdfExtractorTest, | |
| ExtractManifestStoreThrowsNotFoundErrorIfNoAfRelationship) { | |
| riegeli::StringReader<> input(kTestPdfContentNoAfRelationship); | |
| PdfExtractor extractor; | |
| EXPECT_THAT(extractor.ExtractManifestStore(input), | |
| StatusIs(absl::StatusCode::kNotFound, | |
| HasSubstr("No manifest store found."))); | |
| } | |
| TEST(PdfExtractorTest, | |
| ExtractManifestStoreThrowsNotFoundErrorIfDifferentAfRelationship) { | |
| riegeli::StringReader<> input(kTestPdfContentDifferentAfRelationship); | |
| PdfExtractor extractor; | |
| EXPECT_THAT(extractor.ExtractManifestStore(input), | |
| StatusIs(absl::StatusCode::kNotFound, | |
| HasSubstr("No manifest store found."))); | |
| } | |
| TEST(PdfExtractorTest, ExtractManifestStoreThrowsNotFoundErrorIfNonIndirectAf) { | |
| riegeli::StringReader<> input(kTestPdfContentNonIndirectAf); | |
| PdfExtractor extractor; | |
| EXPECT_THAT(extractor.ExtractManifestStore(input), | |
| StatusIs(absl::StatusCode::kNotFound, | |
| HasSubstr("No manifest store found."))); | |
| } | |
| TEST(PdfExtractorTest, ExtractManifestStoreFailsWithInvalidEmbeddedFilesType) { | |
| riegeli::StringReader<> input(kTestPdfContentInvalidEmbeddedFilesType); | |
| PdfExtractor extractor; | |
| EXPECT_THAT( | |
| extractor.ExtractManifestStore(input), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| ::testing::AllOf(HasSubstr("Unexpected object type found."), | |
| HasSubstr("credentio::Object::")))); | |
| } | |
| TEST(PdfExtractorTest, ExtractManifestStoreFailsIfNamesObjectNotDict) { | |
| riegeli::StringReader<> input(kTestPdfContentNamesDictNotDict); | |
| PdfExtractor extractor; | |
| EXPECT_THAT( | |
| extractor.ExtractManifestStore(input), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("Object is not a credentio::Object::Dictionary"))); | |
| } | |
| TEST(PdfExtractorTest, | |
| ExtractManifestStoreThrowsNotFoundErrorIfNoEmbeddedFiles) { | |
| riegeli::StringReader<> input(kTestPdfContentNoEmbeddedFiles); | |
| PdfExtractor extractor; | |
| EXPECT_THAT(extractor.ExtractManifestStore(input), | |
| StatusIs(absl::StatusCode::kNotFound, | |
| HasSubstr("No '/EmbeddedFiles' dictionary found."))); | |
| } | |
| TEST(PdfExtractorTest, ExtractManifestStoreFailsIfNamesObjectNotFound) { | |
| riegeli::StringReader<> input(kTestPdfContentNamesObjectNotFound); | |
| PdfExtractor extractor; | |
| EXPECT_THAT(extractor.ExtractManifestStore(input), | |
| StatusIs(absl::StatusCode::kNotFound, | |
| HasSubstr("No offset found for object number: 9"))); | |
| } | |
| } // namespace | |
| } // namespace credentio |