Merge to XFA: CPDF_Object() constructor should set its internal m_Type variable.
[pdfium.git] / core / src / fpdfapi / fpdf_parser / fpdf_parser_objects.cpp
index bd8b157..18f06d6 100644 (file)
@@ -5,11 +5,10 @@
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
 #include "../../../include/fpdfapi/fpdf_parser.h"
+#include "../../../include/fxcrt/fx_string.h"
+
 void CPDF_Object::Release()
 {
-    if (this == NULL) {
-        return;
-    }
     if (m_ObjNum) {
         return;
     }
@@ -39,9 +38,6 @@ void CPDF_Object::Destroy()
 }
 CFX_ByteString CPDF_Object::GetString() const
 {
-    if (this == NULL) {
-        return CFX_ByteString();
-    }
     switch (m_Type) {
         case PDFOBJ_BOOLEAN:
             return ((CPDF_Boolean*)this)->m_bValue ? "true" : "false";
@@ -67,9 +63,6 @@ CFX_ByteString CPDF_Object::GetString() const
 }
 CFX_ByteStringC CPDF_Object::GetConstString() const
 {
-    if (this == NULL) {
-        return CFX_ByteStringC();
-    }
     switch (m_Type) {
         case PDFOBJ_STRING:
             return CFX_ByteStringC((FX_LPCBYTE)((CPDF_String*)this)->m_String, ((CPDF_String*)this)->m_String.GetLength());
@@ -91,9 +84,6 @@ CFX_ByteStringC CPDF_Object::GetConstString() const
 }
 FX_FLOAT CPDF_Object::GetNumber() const
 {
-    if (this == NULL) {
-        return 0;
-    }
     switch (m_Type) {
         case PDFOBJ_NUMBER:
             return ((CPDF_Number*)this)->GetNumber();
@@ -117,9 +107,6 @@ FX_FLOAT CPDF_Object::GetNumber16() const
 }
 int CPDF_Object::GetInteger() const
 {
-    if (this == NULL) {
-        return 0;
-    }
     switch (m_Type) {
         case PDFOBJ_BOOLEAN:
             return ((CPDF_Boolean*)this)->m_bValue;
@@ -143,9 +130,6 @@ int CPDF_Object::GetInteger() const
 }
 CPDF_Dictionary* CPDF_Object::GetDict() const
 {
-    if (this == NULL) {
-        return NULL;
-    }
     switch (m_Type) {
         case PDFOBJ_DICTIONARY:
             return (CPDF_Dictionary*)this;
@@ -167,13 +151,10 @@ CPDF_Dictionary* CPDF_Object::GetDict() const
 }
 CPDF_Array* CPDF_Object::GetArray() const
 {
-    if (this == NULL) {
-        return NULL;
-    }
-    if (m_Type == PDFOBJ_ARRAY) {
+    if (m_Type == PDFOBJ_ARRAY) 
         return (CPDF_Array*)this;
-    }
-    return NULL;
+    else
+        return NULL;
 }
 void CPDF_Object::SetString(const CFX_ByteString& str)
 {
@@ -207,11 +188,11 @@ FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const
     if (this == pOther) {
         return TRUE;
     }
-    if (this == NULL || pOther == NULL) {
+    if (pOther == NULL) {
         return FALSE;
     }
     if (pOther->m_Type != m_Type) {
-        if (m_Type == PDFOBJ_REFERENCE) {
+        if (m_Type == PDFOBJ_REFERENCE && GetDirect()) {
             return GetDirect()->IsIdentical(pOther);
         } else if (pOther->m_Type == PDFOBJ_REFERENCE) {
             return IsIdentical(pOther->GetDirect());
@@ -242,9 +223,6 @@ FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const
 }
 CPDF_Object* CPDF_Object::GetDirect() const
 {
-    if (this == NULL) {
-        return NULL;
-    }
     if (m_Type != PDFOBJ_REFERENCE) {
         return (CPDF_Object*)this;
     }
@@ -261,9 +239,6 @@ CPDF_Object* CPDF_Object::Clone(FX_BOOL bDirect) const
 }
 CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const
 {
-    if (this == NULL) {
-        return NULL;
-    }
     switch (m_Type) {
         case PDFOBJ_BOOLEAN:
             return FX_NEW CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue);
@@ -303,7 +278,11 @@ CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visite
                 CPDF_StreamAcc acc;
                 acc.LoadAllData(pThis, TRUE);
                 FX_DWORD streamSize = acc.GetSize();
-                CPDF_Stream* pObj = FX_NEW CPDF_Stream(acc.DetachData(), streamSize, (CPDF_Dictionary*)((CPDF_Object*)pThis->GetDict())->CloneInternal(bDirect, visited));
+                CPDF_Stream* pObj;
+                if (pThis->GetDict())
+                    pObj = FX_NEW CPDF_Stream(acc.DetachData(), streamSize, (CPDF_Dictionary*)((CPDF_Object*)pThis->GetDict())->CloneInternal(bDirect, visited));
+                else
+                    pObj = FX_NEW CPDF_Stream(acc.DetachData(), streamSize, NULL);
                 return pObj;
             }
         case PDFOBJ_REFERENCE: {
@@ -311,7 +290,11 @@ CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visite
                 FX_DWORD obj_num = pRef->m_RefObjNum;
                 if (bDirect && !visited->GetValueAt((void*)(FX_UINTPTR)obj_num)) {
                     visited->SetAt((void*)(FX_UINTPTR)obj_num, (void*)1);
-                    CPDF_Object* ret = pRef->GetDirect()->CloneInternal(TRUE, visited);
+                    CPDF_Object* ret;
+                    if (pRef->GetDirect())
+                        ret = pRef->GetDirect()->CloneInternal(TRUE, visited);
+                    else
+                        ret = NULL;
                     return ret;
                 } else {
                     return FX_NEW CPDF_Reference(pRef->m_pObjList, obj_num);
@@ -322,9 +305,6 @@ CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visite
 }
 CPDF_Object* CPDF_Object::CloneRef(CPDF_IndirectObjects* pDoc) const
 {
-    if (this == NULL) {
-        return NULL;
-    }
     if (m_ObjNum) {
         return FX_NEW CPDF_Reference(pDoc, m_ObjNum);
     }
@@ -332,9 +312,6 @@ CPDF_Object* CPDF_Object::CloneRef(CPDF_IndirectObjects* pDoc) const
 }
 CFX_WideString CPDF_Object::GetUnicodeText(CFX_CharMap* pCharMap) const
 {
-    if (this == NULL) {
-        return CFX_WideString();
-    }
     if (m_Type == PDFOBJ_STRING) {
         return PDF_DecodeText(((CPDF_String*)this)->m_String, pCharMap);
     } else if (m_Type == PDFOBJ_STREAM) {
@@ -349,40 +326,30 @@ CFX_WideString CPDF_Object::GetUnicodeText(CFX_CharMap* pCharMap) const
 }
 void CPDF_Object::SetUnicodeText(FX_LPCWSTR pUnicodes, int len)
 {
-    if (this == NULL) {
-        return;
-    }
     if (m_Type == PDFOBJ_STRING) {
         ((CPDF_String*)this)->m_String = PDF_EncodeText(pUnicodes, len);
     } else if (m_Type == PDFOBJ_STREAM) {
         CFX_ByteString result = PDF_EncodeText(pUnicodes, len);
-        ((CPDF_Stream*)this)->SetData((FX_LPBYTE)(FX_LPCSTR)result, result.GetLength(), FALSE, FALSE);
+        ((CPDF_Stream*)this)->SetData((FX_LPBYTE)result.c_str(), result.GetLength(), FALSE, FALSE);
     }
 }
+
 CPDF_Number::CPDF_Number(int value)
-{
-    m_Type = PDFOBJ_NUMBER;
-    m_bInteger = TRUE;
-    m_Integer = value;
+    : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(TRUE), m_Integer(value) {
 }
+
 CPDF_Number::CPDF_Number(FX_FLOAT value)
-{
-    m_Type = PDFOBJ_NUMBER;
-    m_bInteger = FALSE;
-    m_Float = value;
+    : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(FALSE), m_Float(value) {
 }
+
 CPDF_Number::CPDF_Number(FX_BOOL bInteger, void* pData)
-{
-    m_Type = PDFOBJ_NUMBER;
-    m_bInteger = bInteger;
-    m_Integer = *(int*)pData;
+    : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(bInteger), m_Integer(*(int*)pData) {
 }
-extern void FX_atonum(FX_BSTR, FX_BOOL&, void*);
-CPDF_Number::CPDF_Number(FX_BSTR str)
-{
-    m_Type = PDFOBJ_NUMBER;
+
+CPDF_Number::CPDF_Number(FX_BSTR str) : CPDF_Object(PDFOBJ_NUMBER) {
     FX_atonum(str, m_bInteger, &m_Integer);
 }
+
 void CPDF_Number::SetString(FX_BSTR str)
 {
     FX_atonum(str, m_bInteger, &m_Integer);
@@ -400,24 +367,22 @@ void CPDF_Number::SetNumber(FX_FLOAT value)
     m_bInteger = FALSE;
     m_Float = value;
 }
-CPDF_String::CPDF_String(const CFX_WideString& str)
-{
-    m_Type = PDFOBJ_STRING;
+CPDF_String::CPDF_String(const CFX_WideString& str) : CPDF_Object(PDFOBJ_STRING), m_bHex(FALSE) {
     m_String = PDF_EncodeText(str, str.GetLength());
-    m_bHex = FALSE;
 }
 CPDF_Array::~CPDF_Array()
 {
     int size = m_Objects.GetSize();
     CPDF_Object** pList = (CPDF_Object**)m_Objects.GetData();
     for (int i = 0; i < size; i ++) {
-        pList[i]->Release();
+        if (pList[i])
+            pList[i]->Release();
     }
 }
 CFX_FloatRect CPDF_Array::GetRect()
 {
     CFX_FloatRect rect;
-    if (this == NULL || m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 4) {
+    if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 4) {
         return rect;
     }
     rect.left = GetNumber(0);
@@ -429,7 +394,7 @@ CFX_FloatRect CPDF_Array::GetRect()
 CFX_AffineMatrix CPDF_Array::GetMatrix()
 {
     CFX_AffineMatrix matrix;
-    if (this == NULL || m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 6) {
+    if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 6) {
         return matrix;
     }
     matrix.Set(GetNumber(0), GetNumber(1), GetNumber(2), GetNumber(3), GetNumber(4), GetNumber(5));
@@ -437,9 +402,6 @@ CFX_AffineMatrix CPDF_Array::GetMatrix()
 }
 CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const
 {
-    if (this == NULL) {
-        return NULL;
-    }
     if (i >= (FX_DWORD)m_Objects.GetSize()) {
         return NULL;
     }
@@ -447,9 +409,6 @@ CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const
 }
 CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const
 {
-    if (this == NULL) {
-        return NULL;
-    }
     if (i >= (FX_DWORD)m_Objects.GetSize()) {
         return NULL;
     }
@@ -457,23 +416,25 @@ CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const
 }
 CFX_ByteString CPDF_Array::GetString(FX_DWORD i) const
 {
-    if (this && i < (FX_DWORD)m_Objects.GetSize()) {
+    if (i < (FX_DWORD)m_Objects.GetSize()) {
         CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
         return p->GetString();
     }
-    return CFX_ByteString();
+    else
+        return CFX_ByteString();
 }
 CFX_ByteStringC CPDF_Array::GetConstString(FX_DWORD i) const
 {
-    if (this && i < (FX_DWORD)m_Objects.GetSize()) {
+    if (i < (FX_DWORD)m_Objects.GetSize()) {
         CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
         return p->GetConstString();
     }
-    return CFX_ByteStringC();
+    else
+        return CFX_ByteStringC();
 }
 int CPDF_Array::GetInteger(FX_DWORD i) const
 {
-    if (this == NULL || i >= (FX_DWORD)m_Objects.GetSize()) {
+    if (i >= (FX_DWORD)m_Objects.GetSize()) {
         return 0;
     }
     CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
@@ -481,7 +442,7 @@ int CPDF_Array::GetInteger(FX_DWORD i) const
 }
 FX_FLOAT CPDF_Array::GetNumber(FX_DWORD i) const
 {
-    if (this == NULL || i >= (FX_DWORD)m_Objects.GetSize()) {
+    if (i >= (FX_DWORD)m_Objects.GetSize()) {
         return 0;
     }
     CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
@@ -517,23 +478,25 @@ CPDF_Array* CPDF_Array::GetArray(FX_DWORD i) const
 }
 void CPDF_Array::RemoveAt(FX_DWORD i)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_ARRAY);
+    ASSERT(m_Type == PDFOBJ_ARRAY);
     if (i >= (FX_DWORD)m_Objects.GetSize()) {
         return;
     }
     CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
-    p->Release();
+    if (p)
+        p->Release();
     m_Objects.RemoveAt(i);
 }
 void CPDF_Array::SetAt(FX_DWORD i, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_ARRAY);
+    ASSERT(m_Type == PDFOBJ_ARRAY);
     ASSERT(i < (FX_DWORD)m_Objects.GetSize());
     if (i >= (FX_DWORD)m_Objects.GetSize()) {
         return;
     }
     CPDF_Object* pOld = (CPDF_Object*)m_Objects.GetAt(i);
-    pOld->Release();
+    if (pOld)
+        pOld->Release();
     if (pObj->GetObjNum()) {
         ASSERT(pObjs != NULL);
         pObj = CPDF_Reference::Create(pObjs, pObj->GetObjNum());
@@ -560,29 +523,29 @@ void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs)
 }
 void CPDF_Array::AddName(const CFX_ByteString& str)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_ARRAY);
+    ASSERT(m_Type == PDFOBJ_ARRAY);
     Add(FX_NEW CPDF_Name(str));
 }
 void CPDF_Array::AddString(const CFX_ByteString& str)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_ARRAY);
+    ASSERT(m_Type == PDFOBJ_ARRAY);
     Add(FX_NEW CPDF_String(str));
 }
 void CPDF_Array::AddInteger(int i)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_ARRAY);
+    ASSERT(m_Type == PDFOBJ_ARRAY);
     Add(FX_NEW CPDF_Number(i));
 }
 void CPDF_Array::AddNumber(FX_FLOAT f)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_ARRAY);
+    ASSERT(m_Type == PDFOBJ_ARRAY);
     CPDF_Number* pNumber = FX_NEW CPDF_Number;
     pNumber->SetNumber(f);
     Add(pNumber);
 }
 void CPDF_Array::AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_ARRAY);
+    ASSERT(m_Type == PDFOBJ_ARRAY);
     Add(FX_NEW CPDF_Reference(pDoc, objnum));
 }
 FX_BOOL CPDF_Array::Identical(CPDF_Array* pOther) const
@@ -601,7 +564,8 @@ CPDF_Dictionary::~CPDF_Dictionary()
     FX_POSITION pos = m_Map.GetStartPosition();
     while (pos) {
         FX_LPVOID value = m_Map.GetNextValue(pos);
-        ((CPDF_Object*)value)->Release();
+        if (value)
+            ((CPDF_Object*)value)->Release();
     }
 }
 FX_POSITION CPDF_Dictionary::GetStartPos() const
@@ -619,123 +583,101 @@ CPDF_Object* CPDF_Dictionary::GetNextElement(FX_POSITION& pos, CFX_ByteString& k
 }
 CPDF_Object* CPDF_Dictionary::GetElement(FX_BSTR key) const
 {
-    if (this == NULL) {
-        return NULL;
-    }
     CPDF_Object* p = NULL;
     m_Map.Lookup(key, (void*&)p);
     return p;
 }
 CPDF_Object* CPDF_Dictionary::GetElementValue(FX_BSTR key) const
 {
-    if (this == NULL) {
-        return NULL;
-    }
     CPDF_Object* p = NULL;
     m_Map.Lookup(key, (void*&)p);
-    return p->GetDirect();
+    return p ? p->GetDirect() : NULL;
 }
 CFX_ByteString CPDF_Dictionary::GetString(FX_BSTR key) const
 {
-    if (this) {
-        CPDF_Object* p = NULL;
-        m_Map.Lookup(key, (void*&)p);
-        if (p) {
-            return p->GetString();
-        }
-    }
-    return CFX_ByteString();
+    CPDF_Object* p = NULL;
+    m_Map.Lookup(key, (void*&)p);
+    if (p)
+        return p->GetString();
+    else
+        return CFX_ByteString();
 }
 CFX_ByteStringC CPDF_Dictionary::GetConstString(FX_BSTR key) const
 {
-    if (this) {
-        CPDF_Object* p = NULL;
-        m_Map.Lookup(key, (void*&)p);
-        if (p) {
-            return p->GetConstString();
-        }
-    }
-    return CFX_ByteStringC();
+    CPDF_Object* p = NULL;
+    m_Map.Lookup(key, (void*&)p);
+    if (p)
+        return p->GetConstString();
+    else
+        return CFX_ByteStringC();
 }
 CFX_WideString CPDF_Dictionary::GetUnicodeText(FX_BSTR key, CFX_CharMap* pCharMap) const
 {
-    if (this) {
-        CPDF_Object* p = NULL;
-        m_Map.Lookup(key, (void*&)p);
-        if (p) {
-            if(p->GetType() == PDFOBJ_REFERENCE) {
-                p = ((CPDF_Reference*)p)->GetDirect();
-                return p->GetUnicodeText(pCharMap);
-            } else {
+    CPDF_Object* p = NULL;
+    m_Map.Lookup(key, (void*&)p);
+    if (p) {
+        if(p->GetType() == PDFOBJ_REFERENCE) {
+            p = ((CPDF_Reference*)p)->GetDirect();
+            if (p) {
                 return p->GetUnicodeText(pCharMap);
             }
+        } else {
+            return p->GetUnicodeText(pCharMap);
         }
     }
     return CFX_WideString();
 }
 CFX_ByteString CPDF_Dictionary::GetString(FX_BSTR key, FX_BSTR def) const
 {
-    if (this) {
-        CPDF_Object* p = NULL;
-        m_Map.Lookup(key, (void*&)p);
-        if (p) {
-            return p->GetString();
-        }
+    CPDF_Object* p = NULL;
+    m_Map.Lookup(key, (void*&)p);
+    if (p) {
+        return p->GetString();
     }
     return CFX_ByteString(def);
 }
 CFX_ByteStringC CPDF_Dictionary::GetConstString(FX_BSTR key, FX_BSTR def) const
 {
-    if (this) {
-        CPDF_Object* p = NULL;
-        m_Map.Lookup(key, (void*&)p);
-        if (p) {
-            return p->GetConstString();
-        }
-    }
-    return CFX_ByteStringC(def);
+    CPDF_Object* p = NULL;
+    m_Map.Lookup(key, (void*&)p);
+    if (p)
+        return p->GetConstString();
+    else
+        return CFX_ByteStringC(def);
 }
 int CPDF_Dictionary::GetInteger(FX_BSTR key) const
 {
-    if (this) {
-        CPDF_Object* p = NULL;
-        m_Map.Lookup(key, (void*&)p);
-        if (p) {
-            return p->GetInteger();
-        }
+    CPDF_Object* p = NULL;
+    m_Map.Lookup(key, (void*&)p);
+    if (p) {
+        return p->GetInteger();
     }
     return 0;
 }
 int CPDF_Dictionary::GetInteger(FX_BSTR key, int def) const
 {
-    if (this) {
-        CPDF_Object* p = NULL;
-        m_Map.Lookup(key, (void*&)p);
-        if (p) {
-            return p->GetInteger();
-        }
+    CPDF_Object* p = NULL;
+    m_Map.Lookup(key, (void*&)p);
+    if (p) {
+        return p->GetInteger();
     }
     return def;
 }
 FX_FLOAT CPDF_Dictionary::GetNumber(FX_BSTR key) const
 {
-    if (this) {
-        CPDF_Object* p = NULL;
-        m_Map.Lookup(key, (void*&)p);
-        if (p) {
-            return p->GetNumber();
-        }
+    CPDF_Object* p = NULL;
+    m_Map.Lookup(key, (void*&)p);
+    if (p) {
+        return p->GetNumber();
     }
     return 0;
 }
 FX_BOOL CPDF_Dictionary::GetBoolean(FX_BSTR key, FX_BOOL bDefault) const
 {
-    if (this) {
-        CPDF_Object* p = NULL;
-        m_Map.Lookup(key, (void*&)p);
-        if (p && p->GetType() == PDFOBJ_BOOLEAN) {
-            return p->GetInteger();
-        }
+    CPDF_Object* p = NULL;
+    m_Map.Lookup(key, (void*&)p);
+    if (p && p->GetType() == PDFOBJ_BOOLEAN) {
+        return p->GetInteger();
     }
     return bDefault;
 }
@@ -787,23 +729,19 @@ CFX_AffineMatrix CPDF_Dictionary::GetMatrix(FX_BSTR key) const
 }
 FX_BOOL CPDF_Dictionary::KeyExist(FX_BSTR key) const
 {
-    if (this == NULL) {
-        return FALSE;
-    }
     FX_LPVOID value;
     return m_Map.Lookup(key, value);
 }
 void CPDF_Dictionary::SetAt(FX_BSTR key, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_DICTIONARY);
+    ASSERT(m_Type == PDFOBJ_DICTIONARY);
     CPDF_Object* p = NULL;
     m_Map.Lookup(key, (void*&)p);
     if (p == pObj) {
         return;
     }
-    if (p) {
+    if (p)
         p->Release();
-    }
     if (pObj) {
         if (pObj->GetObjNum()) {
             ASSERT(pObjs != NULL);
@@ -816,12 +754,12 @@ void CPDF_Dictionary::SetAt(FX_BSTR key, CPDF_Object* pObj, CPDF_IndirectObjects
 }
 void CPDF_Dictionary::AddValue(FX_BSTR key, CPDF_Object* pObj)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_DICTIONARY);
+    ASSERT(m_Type == PDFOBJ_DICTIONARY);
     m_Map.AddValue(key, pObj);
 }
 void CPDF_Dictionary::RemoveAt(FX_BSTR key)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_DICTIONARY);
+    ASSERT(m_Type == PDFOBJ_DICTIONARY);
     CPDF_Object* p = NULL;
     m_Map.Lookup(key, (void*&)p);
     if (p == NULL) {
@@ -832,7 +770,7 @@ void CPDF_Dictionary::RemoveAt(FX_BSTR key)
 }
 void CPDF_Dictionary::ReplaceKey(FX_BSTR oldkey, FX_BSTR newkey)
 {
-    ASSERT(this != NULL && m_Type == PDFOBJ_DICTIONARY);
+    ASSERT(m_Type == PDFOBJ_DICTIONARY);
     CPDF_Object* p = NULL;
     m_Map.Lookup(oldkey, (void*&)p);
     if (p == NULL) {
@@ -843,12 +781,6 @@ void CPDF_Dictionary::ReplaceKey(FX_BSTR oldkey, FX_BSTR newkey)
 }
 FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const
 {
-    if (this == NULL) {
-        if (pOther == NULL) {
-            return TRUE;
-        }
-        return FALSE;
-    }
     if (pOther == NULL) {
         return FALSE;
     }
@@ -860,6 +792,8 @@ FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const
         CFX_ByteString key;
         FX_LPVOID value;
         m_Map.GetNextAssoc(pos, key, value);
+        if (!value)
+            return FALSE;
         if (!((CPDF_Object*)value)->IsIdentical(pOther->GetElement(key))) {
             return FALSE;
         }
@@ -917,8 +851,7 @@ void CPDF_Dictionary::SetAtMatrix(FX_BSTR key, const CFX_AffineMatrix& matrix)
     SetAt(key, pArray);
 }
 CPDF_Stream::CPDF_Stream(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict)
-{
-    m_Type = PDFOBJ_STREAM;
+    : CPDF_Object(PDFOBJ_STREAM) {
     m_pDict = pDict;
     m_dwSize = size;
     m_GenNum = (FX_DWORD) - 1;
@@ -1014,6 +947,9 @@ void CPDF_Stream::InitStream(IFX_FileRead *pFile, CPDF_Dictionary* pDict)
 }
 FX_BOOL CPDF_Stream::Identical(CPDF_Stream* pOther) const
 {
+    if (!m_pDict)
+        return pOther->m_pDict ? FALSE : TRUE;
+
     if (!m_pDict->Identical(pOther->m_pDict)) {
         return FALSE;
     }
@@ -1328,9 +1264,15 @@ void CPDF_IndirectObjects::InsertIndirectObject(FX_DWORD objnum, CPDF_Object* pO
     if (objnum == 0 || pObj == NULL) {
         return;
     }
-    FX_LPVOID value;
+    FX_LPVOID value = NULL;
     if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) {
-        ((CPDF_Object*)value)->Destroy();
+        if (value)
+        {
+            if (pObj->GetGenNum() <= ((CPDF_Object*)value)->GetGenNum())
+                return;
+            else 
+                ((CPDF_Object*)value)->Destroy();
+         }         
     }
     pObj->m_ObjNum = objnum;
     m_IndirectObjs.SetAt((FX_LPVOID)(FX_UINTPTR)objnum, pObj);