Fix a nullptr dereference in FPDF_StructElement_GetStringAttribute(). Add a test case with a bad /StructElem to demonstrate this. Change-Id: Ibf3f454a8a22ca71f2f5e02efa5534102c63ddfd Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/86174 Reviewed-by: Hui Yingst <nigi@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_structtree.cpp b/fpdfsdk/fpdf_structtree.cpp index e611647..f06a2c7 100644 --- a/fpdfsdk/fpdf_structtree.cpp +++ b/fpdfsdk/fpdf_structtree.cpp
@@ -123,6 +123,8 @@ CPDF_ArrayLocker locker(array); for (const RetainPtr<CPDF_Object>& obj : locker) { const CPDF_Dictionary* obj_dict = obj->AsDictionary(); + if (!obj_dict) + continue; const CPDF_Object* attr = obj_dict->GetObjectFor(attr_name); if (!attr || !(attr->IsString() || attr->IsName())) continue;
diff --git a/fpdfsdk/fpdf_structtree_embeddertest.cpp b/fpdfsdk/fpdf_structtree_embeddertest.cpp index 8a0bc67..cb67560 100644 --- a/fpdfsdk/fpdf_structtree_embeddertest.cpp +++ b/fpdfsdk/fpdf_structtree_embeddertest.cpp
@@ -140,6 +140,40 @@ UnloadPage(page); } +TEST_F(FPDFStructTreeEmbedderTest, GetStringAttributeBadStructElement) { + ASSERT_TRUE(OpenDocument("tagged_table_bad_elem.pdf")); + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + { + ScopedFPDFStructTree struct_tree(FPDF_StructTree_GetForPage(page)); + ASSERT_TRUE(struct_tree); + ASSERT_EQ(1, FPDF_StructTree_CountChildren(struct_tree.get())); + + FPDF_STRUCTELEMENT document = + FPDF_StructTree_GetChildAtIndex(struct_tree.get(), 0); + ASSERT_TRUE(document); + + constexpr int kBufLen = 100; + uint16_t buffer[kBufLen] = {0}; + EXPECT_EQ(18U, FPDF_StructElement_GetType(document, buffer, kBufLen)); + EXPECT_EQ("Document", GetPlatformString(buffer)); + + ASSERT_EQ(1, FPDF_StructElement_CountChildren(document)); + FPDF_STRUCTELEMENT table = FPDF_StructElement_GetChildAtIndex(document, 0); + ASSERT_TRUE(table); + + EXPECT_EQ(12U, FPDF_StructElement_GetType(table, buffer, kBufLen)); + EXPECT_EQ("Table", GetPlatformString(buffer)); + + // The table entry cannot be retrieved, as the element is malformed. + EXPECT_EQ(0U, FPDF_StructElement_GetStringAttribute(table, "Summary", + buffer, kBufLen)); + } + + UnloadPage(page); +} + TEST_F(FPDFStructTreeEmbedderTest, GetID) { ASSERT_TRUE(OpenDocument("tagged_table.pdf")); FPDF_PAGE page = LoadPage(0);
diff --git a/testing/resources/tagged_table_bad_elem.in b/testing/resources/tagged_table_bad_elem.in new file mode 100644 index 0000000..5fffc93 --- /dev/null +++ b/testing/resources/tagged_table_bad_elem.in
@@ -0,0 +1,143 @@ +{{header}} +{{object 1 0}} << + /Type /Catalog + /Pages 2 0 R + /StructTreeRoot 8 0 R + /Lang (en-US) + /MarkInfo << + /Marked true + >> +>> +endobj +{{object 2 0}} << + /Type /Pages + /Count 1 + /Kids [3 0 R] +>> +endobj +{{object 3 0}} << + /Type /Page + /Parent 2 0 R + /Contents 4 0 R + /MediaBox [0 0 612 792] + /Group << + /CS /DeviceRGB + /I true + /S /Transparency + >> + /Resources << + /ProcSet [/PDF /ImageC /ImageI /ImageB] + /XObject << + /Tr8 5 0 R + /Im7 6 0 R + >> + /ExtGState << + /EGS9 7 0 R + >> + >> + /StructParents 0 +>> +endobj +{{object 4 0}} << + {{streamlen}} +>> +stream +0.1 w +/Artifact +BMC +q +0 0 612 792 re +W* n +EMC +/Figure<</MCID 0>> +BDC +Q +q +281 685.3 50 50 re +W* n +q +49.9 0 0 50 281.1 685.4 cm +/Im7 Do +Q +EMC +Q +q +EGS9 gs /Tr8 Do +Q +endstream +endobj +{{object 5 0}} << + /Type /XObject + /Subtype /Form + /BBox [-140 395 753 395.1] + /Group << + /CS /DeviceRGB + /K true + /S /Transparency + >> + {{streamlen}} +>> +stream +endstream +endobj +{{object 6 0}} << + /Type /XObject + /Subtype /Image + /Width 50 + /Height 50 + /BitsPerComponent 8 + /ColorSpace /DeviceRGB + /Filter [/ASCIIHexDecode /FlateDecode] + {{streamlen}} +>> +stream +789cedc13101000000c2a0f54fed6f06a00000000000000078031d4c0001 +endstream +endobj +{{object 7 0}} << + /ca 0.5 + /CA 0.5 +>> +endobj +{{object 8 0}} << + /Type /StructTreeRoot + /ParentTree 9 0 R + /K [10 0 R] + /RoleMap << + /Document /Document + /Standard /P + /Figure /Figure + >> +>> +endobj +{{object 9 0}} << + /Nums [ + 0 + [10 0 R 11 0 R] + ] +>> +endobj +{{object 10 0}} << + /Type /StructElem + /S /Document + /K [11 0 R] + /P 8 0 R + /T (TitleText) + /Pg 3 0 R + /Lang (en-US) +>> +endobj +{{object 11 0}} << + /Type /StructElem + /S /Table + /P 10 0 R + /Pg 3 0 R + /A [(bogus type)] + /ID (node12) + /Lang (hu) +>> +endobj +{{xref}} +{{trailer}} +{{startxref}} +%%EOF
diff --git a/testing/resources/tagged_table_bad_elem.pdf b/testing/resources/tagged_table_bad_elem.pdf new file mode 100644 index 0000000..82f19e3 --- /dev/null +++ b/testing/resources/tagged_table_bad_elem.pdf
@@ -0,0 +1,161 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /Pages 2 0 R + /StructTreeRoot 8 0 R + /Lang (en-US) + /MarkInfo << + /Marked true + >> +>> +endobj +2 0 obj << + /Type /Pages + /Count 1 + /Kids [3 0 R] +>> +endobj +3 0 obj << + /Type /Page + /Parent 2 0 R + /Contents 4 0 R + /MediaBox [0 0 612 792] + /Group << + /CS /DeviceRGB + /I true + /S /Transparency + >> + /Resources << + /ProcSet [/PDF /ImageC /ImageI /ImageB] + /XObject << + /Tr8 5 0 R + /Im7 6 0 R + >> + /ExtGState << + /EGS9 7 0 R + >> + >> + /StructParents 0 +>> +endobj +4 0 obj << + /Length 162 +>> +stream +0.1 w +/Artifact +BMC +q +0 0 612 792 re +W* n +EMC +/Figure<</MCID 0>> +BDC +Q +q +281 685.3 50 50 re +W* n +q +49.9 0 0 50 281.1 685.4 cm +/Im7 Do +Q +EMC +Q +q +EGS9 gs /Tr8 Do +Q +endstream +endobj +5 0 obj << + /Type /XObject + /Subtype /Form + /BBox [-140 395 753 395.1] + /Group << + /CS /DeviceRGB + /K true + /S /Transparency + >> + /Length 0 +>> +stream +endstream +endobj +6 0 obj << + /Type /XObject + /Subtype /Image + /Width 50 + /Height 50 + /BitsPerComponent 8 + /ColorSpace /DeviceRGB + /Filter [/ASCIIHexDecode /FlateDecode] + /Length 61 +>> +stream +789cedc13101000000c2a0f54fed6f06a00000000000000078031d4c0001 +endstream +endobj +7 0 obj << + /ca 0.5 + /CA 0.5 +>> +endobj +8 0 obj << + /Type /StructTreeRoot + /ParentTree 9 0 R + /K [10 0 R] + /RoleMap << + /Document /Document + /Standard /P + /Figure /Figure + >> +>> +endobj +9 0 obj << + /Nums [ + 0 + [10 0 R 11 0 R] + ] +>> +endobj +10 0 obj << + /Type /StructElem + /S /Document + /K [11 0 R] + /P 8 0 R + /T (TitleText) + /Pg 3 0 R + /Lang (en-US) +>> +endobj +11 0 obj << + /Type /StructElem + /S /Table + /P 10 0 R + /Pg 3 0 R + /A [(bogus type)] + /ID (node12) + /Lang (hu) +>> +endobj +xref +0 12 +0000000000 65535 f +0000000015 00000 n +0000000145 00000 n +0000000208 00000 n +0000000556 00000 n +0000000770 00000 n +0000000952 00000 n +0000001212 00000 n +0000001253 00000 n +0000001412 00000 n +0000001473 00000 n +0000001600 00000 n +trailer << + /Root 1 0 R + /Size 12 +>> +startxref +1726 +%%EOF