| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/include/fpdfapi/fpdf_objects.h" | 7 #include "core/include/fpdfapi/fpdf_objects.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| 11 #include "core/include/fpdfapi/fpdf_parser.h" | 11 #include "core/include/fpdfapi/fpdf_parser.h" |
| 12 #include "core/include/fxcrt/fx_string.h" | 12 #include "core/include/fxcrt/fx_string.h" |
| 13 #include "third_party/base/stl_util.h" | 13 #include "third_party/base/stl_util.h" |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 const FX_DWORD kBlockSize = 1024; | 17 const FX_DWORD kBlockSize = 1024; |
| 18 | 18 |
| 19 } // namespace | 19 } // namespace |
| 20 | 20 |
| 21 // static | |
| 22 int CPDF_Object::s_nCurRefDepth = 0; | |
| 23 | |
| 24 void CPDF_Object::Release() { | 21 void CPDF_Object::Release() { |
| 25 if (m_ObjNum) { | 22 if (m_ObjNum) { |
| 26 return; | 23 return; |
| 27 } | 24 } |
| 28 Destroy(); | 25 Destroy(); |
| 29 } | 26 } |
| 30 void CPDF_Object::Destroy() { | 27 void CPDF_Object::Destroy() { |
| 31 switch (m_Type) { | 28 switch (m_Type) { |
| 32 case PDFOBJ_STRING: | 29 case PDFOBJ_STRING: |
| 33 delete AsString(); | 30 delete AsString(); |
| 34 break; | 31 break; |
| 35 case PDFOBJ_NAME: | 32 case PDFOBJ_NAME: |
| 36 delete AsName(); | 33 delete AsName(); |
| 37 break; | 34 break; |
| 38 case PDFOBJ_ARRAY: | 35 case PDFOBJ_ARRAY: |
| 39 delete AsArray(); | 36 delete AsArray(); |
| 40 break; | 37 break; |
| 41 case PDFOBJ_DICTIONARY: | 38 case PDFOBJ_DICTIONARY: |
| 42 delete AsDictionary(); | 39 delete AsDictionary(); |
| 43 break; | 40 break; |
| 44 case PDFOBJ_STREAM: | 41 case PDFOBJ_STREAM: |
| 45 delete AsStream(); | 42 delete AsStream(); |
| 46 break; | 43 break; |
| 47 default: | 44 default: |
| 48 delete this; | 45 delete this; |
| 49 } | 46 } |
| 50 } | 47 } |
| 48 |
| 49 const CPDF_Object* const CPDF_Object::GetBasicObject() const { |
| 50 const CPDF_Reference* pRef = AsReference(); |
| 51 if (!pRef) { |
| 52 // This is not an indirect reference. |
| 53 return this; |
| 54 } |
| 55 if (!pRef->m_pObjList) |
| 56 return nullptr; |
| 57 return pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr); |
| 58 } |
| 59 |
| 51 CFX_ByteString CPDF_Object::GetString() const { | 60 CFX_ByteString CPDF_Object::GetString() const { |
| 52 switch (m_Type) { | 61 const CPDF_Object* obj = GetBasicObject(); |
| 53 case PDFOBJ_BOOLEAN: | 62 if (obj) { |
| 54 return AsBoolean()->m_bValue ? "true" : "false"; | 63 switch (obj->GetType()) { |
| 55 case PDFOBJ_NUMBER: | 64 case PDFOBJ_BOOLEAN: |
| 56 return AsNumber()->GetString(); | 65 return obj->AsBoolean()->GetString(); |
| 57 case PDFOBJ_STRING: | 66 case PDFOBJ_NUMBER: |
| 58 return AsString()->m_String; | 67 return obj->AsNumber()->GetString(); |
| 59 case PDFOBJ_NAME: | 68 case PDFOBJ_STRING: |
| 60 return AsName()->m_Name; | 69 return obj->AsString()->GetString(); |
| 61 case PDFOBJ_REFERENCE: { | 70 case PDFOBJ_NAME: |
| 62 const CPDF_Reference* pRef = AsReference(); | 71 return obj->AsName()->GetString(); |
| 63 if (!pRef->m_pObjList) | |
| 64 break; | |
| 65 | |
| 66 CPDF_Object* pObj = | |
| 67 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr); | |
| 68 return pObj ? pObj->GetString() : CFX_ByteString(); | |
| 69 } | 72 } |
| 70 } | 73 } |
| 71 return CFX_ByteString(); | 74 return CFX_ByteString(); |
| 72 } | 75 } |
| 76 |
| 73 CFX_ByteStringC CPDF_Object::GetConstString() const { | 77 CFX_ByteStringC CPDF_Object::GetConstString() const { |
| 74 switch (m_Type) { | 78 const CPDF_Object* obj = GetBasicObject(); |
| 75 case PDFOBJ_STRING: { | 79 if (obj) { |
| 76 CFX_ByteString str = AsString()->m_String; | 80 FX_DWORD type = obj->GetType(); |
| 77 return CFX_ByteStringC((const uint8_t*)str, str.GetLength()); | 81 if (type == PDFOBJ_STRING) { |
| 82 CFX_ByteString str = obj->AsString()->GetString(); |
| 83 return CFX_ByteStringC(str); |
| 78 } | 84 } |
| 79 case PDFOBJ_NAME: { | 85 if (type == PDFOBJ_NAME) { |
| 80 CFX_ByteString name = AsName()->m_Name; | 86 CFX_ByteString name = obj->AsName()->GetString(); |
| 81 return CFX_ByteStringC((const uint8_t*)name, name.GetLength()); | 87 return CFX_ByteStringC(name); |
| 82 } | |
| 83 case PDFOBJ_REFERENCE: { | |
| 84 const CPDF_Reference* pRef = AsReference(); | |
| 85 if (!pRef->m_pObjList) | |
| 86 break; | |
| 87 | |
| 88 CPDF_Object* pObj = | |
| 89 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr); | |
| 90 return pObj ? pObj->GetConstString() : CFX_ByteStringC(); | |
| 91 } | 88 } |
| 92 } | 89 } |
| 93 return CFX_ByteStringC(); | 90 return CFX_ByteStringC(); |
| 94 } | 91 } |
| 95 | 92 |
| 96 FX_FLOAT CPDF_Object::GetNumber() const { | 93 FX_FLOAT CPDF_Object::GetNumber() const { |
| 97 switch (m_Type) { | 94 const CPDF_Object* obj = GetBasicObject(); |
| 98 case PDFOBJ_NUMBER: | 95 if (obj && obj->GetType() == PDFOBJ_NUMBER) |
| 99 return AsNumber()->GetNumber(); | 96 return AsNumber()->GetNumber(); |
| 100 case PDFOBJ_REFERENCE: { | |
| 101 const CPDF_Reference* pRef = AsReference(); | |
| 102 if (!pRef->m_pObjList) | |
| 103 break; | |
| 104 | |
| 105 CPDF_Object* pObj = | |
| 106 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), nullptr); | |
| 107 return pObj ? pObj->GetNumber() : 0; | |
| 108 } | |
| 109 } | |
| 110 return 0; | 97 return 0; |
| 111 } | 98 } |
| 112 | 99 |
| 113 FX_FLOAT CPDF_Object::GetNumber16() const { | 100 FX_FLOAT CPDF_Object::GetNumber16() const { |
| 114 return GetNumber(); | 101 return GetNumber(); |
| 115 } | 102 } |
| 116 | 103 |
| 117 int CPDF_Object::GetInteger() const { | 104 int CPDF_Object::GetInteger() const { |
| 118 CFX_AutoRestorer<int> restorer(&s_nCurRefDepth); | 105 const CPDF_Object* obj = GetBasicObject(); |
| 119 if (++s_nCurRefDepth > kObjectRefMaxDepth) | 106 if (obj) { |
| 120 return 0; | 107 FX_DWORD type = obj->GetType(); |
| 121 | 108 if (type == PDFOBJ_BOOLEAN) |
| 122 switch (m_Type) { | 109 return obj->AsBoolean()->GetValue(); |
| 123 case PDFOBJ_BOOLEAN: | 110 if (type == PDFOBJ_NUMBER) |
| 124 return AsBoolean()->m_bValue; | 111 return obj->AsNumber()->GetInteger(); |
| 125 case PDFOBJ_NUMBER: | |
| 126 return AsNumber()->GetInteger(); | |
| 127 case PDFOBJ_REFERENCE: { | |
| 128 const CPDF_Reference* pRef = AsReference(); | |
| 129 PARSE_CONTEXT context; | |
| 130 FXSYS_memset(&context, 0, sizeof(PARSE_CONTEXT)); | |
| 131 if (!pRef->m_pObjList) | |
| 132 return 0; | |
| 133 | |
| 134 CPDF_Object* pObj = | |
| 135 pRef->m_pObjList->GetIndirectObject(pRef->GetRefObjNum(), &context); | |
| 136 return pObj ? pObj->GetInteger() : 0; | |
| 137 } | |
| 138 } | 112 } |
| 139 return 0; | 113 return 0; |
| 140 } | 114 } |
| 141 | 115 |
| 142 CPDF_Dictionary* CPDF_Object::GetDict() const { | 116 CPDF_Dictionary* CPDF_Object::GetDict() const { |
| 143 switch (m_Type) { | 117 const CPDF_Object* obj = GetBasicObject(); |
| 144 case PDFOBJ_DICTIONARY: | 118 if (obj) { |
| 119 FX_DWORD type = obj->GetType(); |
| 120 if (type == PDFOBJ_DICTIONARY) { |
| 145 // The method should be made non-const if we want to not be const. | 121 // The method should be made non-const if we want to not be const. |
| 146 // See bug #234. | 122 // See bug #234. |
| 147 return const_cast<CPDF_Dictionary*>(AsDictionary()); | 123 return const_cast<CPDF_Dictionary*>(AsDictionary()); |
| 148 case PDFOBJ_STREAM: | 124 } |
| 125 if (type == PDFOBJ_STREAM) |
| 149 return AsStream()->GetDict(); | 126 return AsStream()->GetDict(); |
| 150 case PDFOBJ_REFERENCE: { | |
| 151 const CPDF_Reference* pRef = AsReference(); | |
| 152 CPDF_IndirectObjectHolder* pIndirect = pRef->GetObjList(); | |
| 153 if (!pIndirect) | |
| 154 return nullptr; | |
| 155 CPDF_Object* pObj = | |
| 156 pIndirect->GetIndirectObject(pRef->GetRefObjNum(), nullptr); | |
| 157 if (!pObj || (pObj == this)) | |
| 158 return nullptr; | |
| 159 return pObj->GetDict(); | |
| 160 } | |
| 161 default: | |
| 162 return nullptr; | |
| 163 } | 127 } |
| 128 return nullptr; |
| 164 } | 129 } |
| 165 | 130 |
| 166 CPDF_Array* CPDF_Object::GetArray() const { | 131 CPDF_Array* CPDF_Object::GetArray() const { |
| 167 // The method should be made non-const if we want to not be const. | 132 // The method should be made non-const if we want to not be const. |
| 168 // See bug #234. | 133 // See bug #234. |
| 169 return const_cast<CPDF_Array*>(AsArray()); | 134 return const_cast<CPDF_Array*>(AsArray()); |
| 170 } | 135 } |
| 171 | 136 |
| 172 void CPDF_Object::SetString(const CFX_ByteString& str) { | 137 void CPDF_Object::SetString(const CFX_ByteString& str) { |
| 173 switch (m_Type) { | 138 switch (m_Type) { |
| (...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 pObj->Destroy(); | 1098 pObj->Destroy(); |
| 1134 return FALSE; | 1099 return FALSE; |
| 1135 } | 1100 } |
| 1136 it->second->Destroy(); | 1101 it->second->Destroy(); |
| 1137 } | 1102 } |
| 1138 pObj->m_ObjNum = objnum; | 1103 pObj->m_ObjNum = objnum; |
| 1139 m_IndirectObjs[objnum] = pObj; | 1104 m_IndirectObjs[objnum] = pObj; |
| 1140 m_LastObjNum = std::max(m_LastObjNum, objnum); | 1105 m_LastObjNum = std::max(m_LastObjNum, objnum); |
| 1141 return TRUE; | 1106 return TRUE; |
| 1142 } | 1107 } |
| OLD | NEW |