Adjust the order of clearing resource in CPDF_DocPageData::Clear

Images are basic resource and are referred or used by other objects in some cases. Images should be released after the objects who uses these objects. In this case, an image object is accessed in the process of CPDF_TilingPattern's destroy. Unlikely, this image has been destroyed before.

BUG=414046
R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/582993002
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
index 77db453..8e578f6 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
@@ -151,39 +151,34 @@
 void CPDF_DocPageData::Clear(FX_BOOL bForceRelease)
 {
     FX_POSITION pos;
-    FX_DWORD	nCount;
 
     m_bForceClear = bForceRelease;
+
+    // Release objects saved in the resource maps like font map and color space map.
+    // The compound objects shall be released before simple ones.
     pos = m_FontMap.GetStartPosition();
     while (pos) {
         CPDF_Dictionary* fontDict;
         CPDF_CountedObject<CPDF_Font*>* fontData;
         m_FontMap.GetNextAssoc(pos, fontDict, fontData);
-        nCount = fontData->m_nCount;
-        if (bForceRelease || nCount < 2) {
+        if (!fontData->m_Obj) {
+            continue;
+        }
+        if (bForceRelease || fontData->m_nCount < 2) {
             delete fontData->m_Obj;
             fontData->m_Obj = NULL;
         }
     }
-    pos = m_ImageMap.GetStartPosition();
-    while (pos) {
-        FX_DWORD objNum;
-        CPDF_CountedObject<CPDF_Image*>* imageData;
-        m_ImageMap.GetNextAssoc(pos, objNum, imageData);
-        nCount = imageData->m_nCount;
-        if (bForceRelease || nCount < 2) {
-            delete imageData->m_Obj;
-            delete imageData;
-            m_ImageMap.RemoveKey(objNum);
-        }
-    }
     pos = m_ColorSpaceMap.GetStartPosition();
     while (pos) {
         CPDF_Object* csKey;
         CPDF_CountedObject<CPDF_ColorSpace*>* csData;
         m_ColorSpaceMap.GetNextAssoc(pos, csKey, csData);
-        nCount = csData->m_nCount;
-        if (bForceRelease || nCount < 2) {
+        if (!csData->m_Obj) {
+            continue;
+        }
+        if (bForceRelease || csData->m_nCount < 2) {
+            // csData->m_Obj is deleted in the function of ReleaseCS().
             csData->m_Obj->ReleaseCS();
             csData->m_Obj = NULL;
         }
@@ -193,8 +188,10 @@
         CPDF_Stream* ipKey;
         CPDF_CountedObject<CPDF_IccProfile*>* ipData;
         m_IccProfileMap.GetNextAssoc(pos, ipKey, ipData);
-        nCount = ipData->m_nCount;
-        if (bForceRelease || nCount < 2) {
+        if (!ipData->m_Obj) {
+            continue;
+        }
+        if (bForceRelease || ipData->m_nCount < 2) {
             FX_POSITION pos2 = m_HashProfileMap.GetStartPosition();
             while (pos2) {
                 CFX_ByteString bsKey;
@@ -206,6 +203,7 @@
                 }
             }
             delete ipData->m_Obj;
+            ipData->m_Obj = NULL;
             delete ipData;
             m_IccProfileMap.RemoveKey(ipKey);
         }
@@ -215,9 +213,12 @@
         CPDF_Stream* ftKey;
         CPDF_CountedObject<CPDF_StreamAcc*>* ftData;
         m_FontFileMap.GetNextAssoc(pos, ftKey, ftData);
-        nCount = ftData->m_nCount;
-        if (bForceRelease || nCount < 2) {
+        if (!ftData->m_Obj) {
+            continue;
+        }
+        if (bForceRelease || ftData->m_nCount < 2) {
             delete ftData->m_Obj;
+            ftData->m_Obj = NULL;
             delete ftData;
             m_FontFileMap.RemoveKey(ftKey);
         }
@@ -227,13 +228,30 @@
         CPDF_Object* ptObj;
         CPDF_CountedObject<CPDF_Pattern*>* ptData;
         m_PatternMap.GetNextAssoc(pos, ptObj, ptData);
-        nCount = ptData->m_nCount;
-        if (bForceRelease || nCount < 2) {
+        if (!ptData->m_Obj) {
+            continue;
+        }
+        if (bForceRelease || ptData->m_nCount < 2) {
             ptData->m_Obj->SetForceClear(bForceRelease);
             delete ptData->m_Obj;
             ptData->m_Obj = NULL;
         }
     }
+    pos = m_ImageMap.GetStartPosition();
+    while (pos) {
+        FX_DWORD objNum;
+        CPDF_CountedObject<CPDF_Image*>* imageData;
+        m_ImageMap.GetNextAssoc(pos, objNum, imageData);
+        if (!imageData->m_Obj) {
+            continue;
+        }
+        if (bForceRelease || imageData->m_nCount < 2) {
+            delete imageData->m_Obj;
+            imageData->m_Obj = NULL;
+            delete imageData;
+            m_ImageMap.RemoveKey(objNum);
+        }
+    }
 }
 CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly)
 {