Require string objects for file spec entries.
Follow the spec more closely.
- Also do the same for /Base entries in URL dictionaries.
Bug: chromium:959183
Change-Id: Ie78abd3ad13c4d39db99592efd81829ff6a820fc
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/53970
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfdoc/cpdf_action.cpp b/core/fpdfdoc/cpdf_action.cpp
index 1621741..18e4927 100644
--- a/core/fpdfdoc/cpdf_action.cpp
+++ b/core/fpdfdoc/cpdf_action.cpp
@@ -94,8 +94,11 @@
const CPDF_Dictionary* pURI = pRoot->GetDictFor("URI");
if (pURI) {
auto result = csURI.Find(":");
- if (!result.has_value() || result.value() == 0)
- csURI = pURI->GetStringFor("Base") + csURI;
+ if (!result.has_value() || result.value() == 0) {
+ auto* pBase = pURI->GetDirectObjectFor("Base");
+ if (pBase && (pBase->IsString() || pBase->IsStream()))
+ csURI = pBase->GetString() + csURI;
+ }
}
return csURI;
}
diff --git a/core/fpdfdoc/cpdf_filespec.cpp b/core/fpdfdoc/cpdf_filespec.cpp
index 1e22e2f..41c5405 100644
--- a/core/fpdfdoc/cpdf_filespec.cpp
+++ b/core/fpdfdoc/cpdf_filespec.cpp
@@ -98,26 +98,30 @@
WideString CPDF_FileSpec::GetFileName() const {
WideString csFileName;
if (const CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
- csFileName = pDict->GetUnicodeTextFor("UF");
+ const CPDF_String* pUF = ToString(pDict->GetDirectObjectFor("UF"));
+ if (pUF)
+ csFileName = pUF->GetUnicodeText();
if (csFileName.IsEmpty()) {
- csFileName = WideString::FromDefANSI(
- pDict->GetStringFor(pdfium::stream::kF).AsStringView());
+ const CPDF_String* pK =
+ ToString(pDict->GetDirectObjectFor(pdfium::stream::kF));
+ if (pK)
+ csFileName = WideString::FromDefANSI(pK->GetString().AsStringView());
}
if (pDict->GetStringFor("FS") == "URL")
return csFileName;
if (csFileName.IsEmpty()) {
- constexpr const char* keys[] = {"DOS", "Mac", "Unix"};
- for (const auto* key : keys) {
- if (pDict->KeyExist(key)) {
+ for (const auto* key : {"DOS", "Mac", "Unix"}) {
+ const CPDF_String* pValue = ToString(pDict->GetDirectObjectFor(key));
+ if (pValue) {
csFileName =
- WideString::FromDefANSI(pDict->GetStringFor(key).AsStringView());
+ WideString::FromDefANSI(pValue->GetString().AsStringView());
break;
}
}
}
- } else if (m_pObj->IsString()) {
- csFileName = WideString::FromDefANSI(m_pObj->GetString().AsStringView());
+ } else if (const CPDF_String* pString = m_pObj->AsString()) {
+ csFileName = WideString::FromDefANSI(pString->GetString().AsStringView());
}
return DecodeFileName(csFileName);
}
diff --git a/core/fpdfdoc/cpdf_filespec_unittest.cpp b/core/fpdfdoc/cpdf_filespec_unittest.cpp
index bee6574..30394ff 100644
--- a/core/fpdfdoc/cpdf_filespec_unittest.cpp
+++ b/core/fpdfdoc/cpdf_filespec_unittest.cpp
@@ -122,6 +122,17 @@
CPDF_FileSpec file_spec(name_obj.Get());
EXPECT_TRUE(file_spec.GetFileName().IsEmpty());
}
+ {
+ // Invalid CPDF_Name objects in dictionary. See https://crbug.com/959183
+ auto dict_obj = pdfium::MakeRetain<CPDF_Dictionary>();
+ CPDF_FileSpec file_spec(dict_obj.Get());
+ for (const char* key : {"Unix", "Mac", "DOS", "F", "UF"}) {
+ dict_obj->SetNewFor<CPDF_Name>(key, "http://evil.org");
+ EXPECT_TRUE(file_spec.GetFileName().IsEmpty());
+ }
+ dict_obj->SetNewFor<CPDF_String>("FS", "URL", false);
+ EXPECT_TRUE(file_spec.GetFileName().IsEmpty());
+ }
}
TEST(cpdf_filespec, SetFileName) {