summaryrefslogtreecommitdiff
path: root/core/src/fpdfapi
diff options
context:
space:
mode:
authorWei Li <weili@chromium.org>2016-01-19 12:35:03 -0800
committerWei Li <weili@chromium.org>2016-01-19 12:35:03 -0800
commit6bc997a89429662668fbdce2a0d217a93e8a1be1 (patch)
treea72e82143e21aa5f8ad81d33f111acdbcbef7a0a /core/src/fpdfapi
parentacfe9a7ffca3ad1076e9b0772f4fc165a56065ff (diff)
downloadpdfium-6bc997a89429662668fbdce2a0d217a93e8a1be1.tar.xz
Merge to XFA: Fix infinite loops caused by calling circular indirect objects
There are multiple functions in CPDF_Object class which can cause infinite loop due to recursively calling circular indirect objects. Fix them by deference indirect object first. BUG=pdfium:355 TBR=jun_fang@foxitsoftware.com, thestig@chromium.org Review URL: https://codereview.chromium.org/1585533002 . (cherry picked from commit 90853cb1dfd1bf3803ec21cfae3e93948137be61) Review URL: https://codereview.chromium.org/1602103004 .
Diffstat (limited to 'core/src/fpdfapi')
-rw-r--r--core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp135
1 files changed, 50 insertions, 85 deletions
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp
index cad8d7701d..a3b0568931 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp
@@ -18,9 +18,6 @@ const FX_DWORD kBlockSize = 1024;
} // namespace
-// static
-int CPDF_Object::s_nCurRefDepth = 0;
-
void CPDF_Object::Release() {
if (m_ObjNum) {
return;
@@ -48,65 +45,55 @@ void CPDF_Object::Destroy() {
delete this;
}
}
-CFX_ByteString CPDF_Object::GetString() const {
- switch (m_Type) {
- case PDFOBJ_BOOLEAN:
- return AsBoolean()->m_bValue ? "true" : "false";
- case PDFOBJ_NUMBER:
- return AsNumber()->GetString();
- case PDFOBJ_STRING:
- return AsString()->m_String;
- case PDFOBJ_NAME:
- return AsName()->m_Name;
- case PDFOBJ_REFERENCE: {
- const CPDF_Reference* pRef = AsReference();
- if (!pRef->m_pObjList)
- break;
- CPDF_Object* pObj =
- pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr);
- return pObj ? pObj->GetString() : CFX_ByteString();
+const CPDF_Object* const CPDF_Object::GetBasicObject() const {
+ const CPDF_Reference* pRef = AsReference();
+ if (!pRef) {
+ // This is not an indirect reference.
+ return this;
+ }
+ if (!pRef->m_pObjList)
+ return nullptr;
+ return pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr);
+}
+
+CFX_ByteString CPDF_Object::GetString() const {
+ const CPDF_Object* obj = GetBasicObject();
+ if (obj) {
+ switch (obj->GetType()) {
+ case PDFOBJ_BOOLEAN:
+ return obj->AsBoolean()->GetString();
+ case PDFOBJ_NUMBER:
+ return obj->AsNumber()->GetString();
+ case PDFOBJ_STRING:
+ return obj->AsString()->GetString();
+ case PDFOBJ_NAME:
+ return obj->AsName()->GetString();
}
}
return CFX_ByteString();
}
+
CFX_ByteStringC CPDF_Object::GetConstString() const {
- switch (m_Type) {
- case PDFOBJ_STRING: {
- CFX_ByteString str = AsString()->m_String;
- return CFX_ByteStringC((const uint8_t*)str, str.GetLength());
- }
- case PDFOBJ_NAME: {
- CFX_ByteString name = AsName()->m_Name;
- return CFX_ByteStringC((const uint8_t*)name, name.GetLength());
+ const CPDF_Object* obj = GetBasicObject();
+ if (obj) {
+ FX_DWORD type = obj->GetType();
+ if (type == PDFOBJ_STRING) {
+ CFX_ByteString str = obj->AsString()->GetString();
+ return CFX_ByteStringC(str);
}
- case PDFOBJ_REFERENCE: {
- const CPDF_Reference* pRef = AsReference();
- if (!pRef->m_pObjList)
- break;
-
- CPDF_Object* pObj =
- pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr);
- return pObj ? pObj->GetConstString() : CFX_ByteStringC();
+ if (type == PDFOBJ_NAME) {
+ CFX_ByteString name = obj->AsName()->GetString();
+ return CFX_ByteStringC(name);
}
}
return CFX_ByteStringC();
}
FX_FLOAT CPDF_Object::GetNumber() const {
- switch (m_Type) {
- case PDFOBJ_NUMBER:
- return AsNumber()->GetNumber();
- case PDFOBJ_REFERENCE: {
- const CPDF_Reference* pRef = AsReference();
- if (!pRef->m_pObjList)
- break;
-
- CPDF_Object* pObj =
- pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr);
- return pObj ? pObj->GetNumber() : 0;
- }
- }
+ const CPDF_Object* obj = GetBasicObject();
+ if (obj && obj->GetType() == PDFOBJ_NUMBER)
+ return AsNumber()->GetNumber();
return 0;
}
@@ -115,52 +102,30 @@ FX_FLOAT CPDF_Object::GetNumber16() const {
}
int CPDF_Object::GetInteger() const {
- CFX_AutoRestorer<int> restorer(&s_nCurRefDepth);
- if (++s_nCurRefDepth > kObjectRefMaxDepth)
- return 0;
-
- switch (m_Type) {
- case PDFOBJ_BOOLEAN:
- return AsBoolean()->m_bValue;
- case PDFOBJ_NUMBER:
- return AsNumber()->GetInteger();
- case PDFOBJ_REFERENCE: {
- const CPDF_Reference* pRef = AsReference();
- PARSE_CONTEXT context;
- FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT));
- if (!pRef->m_pObjList)
- return 0;
-
- CPDF_Object* pObj =
- pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), &context);
- return pObj ? pObj->GetInteger() : 0;
- }
+ const CPDF_Object* obj = GetBasicObject();
+ if (obj) {
+ FX_DWORD type = obj->GetType();
+ if (type == PDFOBJ_BOOLEAN)
+ return obj->AsBoolean()->GetValue();
+ if (type == PDFOBJ_NUMBER)
+ return obj->AsNumber()->GetInteger();
}
return 0;
}
CPDF_Dictionary* CPDF_Object::GetDict() const {
- switch (m_Type) {
- case PDFOBJ_DICTIONARY:
+ const CPDF_Object* obj = GetBasicObject();
+ if (obj) {
+ FX_DWORD type = obj->GetType();
+ if (type == PDFOBJ_DICTIONARY) {
// The method should be made non-const if we want to not be const.
// See bug #234.
return const_cast<CPDF_Dictionary*>(AsDictionary());
- case PDFOBJ_STREAM:
- return AsStream()->GetDict();
- case PDFOBJ_REFERENCE: {
- const CPDF_Reference* pRef = AsReference();
- CPDF_IndirectObjectHolder* pIndirect = pRef->GetObjList();
- if (!pIndirect)
- return nullptr;
- CPDF_Object* pObj =
- pIndirect->GetIndirectObject(pRef->GetRefObjNum(), nullptr);
- if (!pObj || (pObj == this))
- return nullptr;
- return pObj->GetDict();
}
- default:
- return nullptr;
+ if (type == PDFOBJ_STREAM)
+ return AsStream()->GetDict();
}
+ return nullptr;
}
CPDF_Array* CPDF_Object::GetArray() const {