diff options
author | Wei Li <weili@chromium.org> | 2016-01-19 12:35:03 -0800 |
---|---|---|
committer | Wei Li <weili@chromium.org> | 2016-01-19 12:35:03 -0800 |
commit | 6bc997a89429662668fbdce2a0d217a93e8a1be1 (patch) | |
tree | a72e82143e21aa5f8ad81d33f111acdbcbef7a0a /core/src/fpdfapi | |
parent | acfe9a7ffca3ad1076e9b0772f4fc165a56065ff (diff) | |
download | pdfium-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.cpp | 135 |
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 { |