Merge to XFA: Add type cast definitions for CPDF_Array.

This Cl adds ToArray, CPDF_Object::AsArray and CPDF_Object::IsArray and
updates the src to use them as needed.

BUG=pdfium:201
R=thestig@chromium.org, tsepez@chromium.org

Review URL: https://codereview.chromium.org/1417893003 .

(cherry picked from commit c2bfc000e502c42c9a3017038fd9104c7997d126)

Review URL: https://codereview.chromium.org/1419643005 .
diff --git a/core/include/fpdfapi/fpdf_objects.h b/core/include/fpdfapi/fpdf_objects.h
index bd7f5bf..dbd4495 100644
--- a/core/include/fpdfapi/fpdf_objects.h
+++ b/core/include/fpdfapi/fpdf_objects.h
@@ -81,12 +81,16 @@
 
   FX_BOOL IsModified() const { return FALSE; }
 
+  bool IsArray() const { return m_Type == PDFOBJ_ARRAY; }
   bool IsBoolean() const { return m_Type == PDFOBJ_BOOLEAN; }
   bool IsDictionary() const { return m_Type == PDFOBJ_DICTIONARY; }
   bool IsName() const { return m_Type == PDFOBJ_NAME; }
   bool IsNumber() const { return m_Type == PDFOBJ_NUMBER; }
   bool IsString() const { return m_Type == PDFOBJ_STRING; }
 
+  CPDF_Array* AsArray();
+  const CPDF_Array* AsArray() const;
+
   CPDF_Boolean* AsBoolean();
   const CPDF_Boolean* AsBoolean() const;
 
@@ -343,6 +347,13 @@
   CFX_PtrArray m_Objects;
   friend class CPDF_Object;
 };
+inline CPDF_Array* ToArray(CPDF_Object* obj) {
+  return obj ? obj->AsArray() : nullptr;
+}
+inline const CPDF_Array* ToArray(const CPDF_Object* obj) {
+  return obj ? obj->AsArray() : nullptr;
+}
+
 class CPDF_Dictionary : public CPDF_Object {
  public:
   static CPDF_Dictionary* Create() { return new CPDF_Dictionary(); }
diff --git a/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp b/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp
index 79bfbdb..32802d0 100644
--- a/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp
+++ b/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp
@@ -120,13 +120,11 @@
 void CPDF_PageContentGenerate::TransformContent(CFX_Matrix& matrix) {
   CPDF_Dictionary* pDict = m_pPage->m_pFormDict;
   CPDF_Object* pContent = pDict ? pDict->GetElementValue("Contents") : NULL;
-  if (!pContent) {
+  if (!pContent)
     return;
-  }
+
   CFX_ByteTextBuf buf;
-  int type = pContent->GetType();
-  if (type == PDFOBJ_ARRAY) {
-    CPDF_Array* pArray = (CPDF_Array*)pContent;
+  if (CPDF_Array* pArray = pContent->AsArray()) {
     int iCount = pArray->GetCount();
     CPDF_StreamAcc** pContentArray = FX_Alloc(CPDF_StreamAcc*, iCount);
     int size = 0;
@@ -153,7 +151,7 @@
     ProcessForm(buf, pBuf, size, matrix);
     FX_Free(pBuf);
     FX_Free(pContentArray);
-  } else if (type == PDFOBJ_STREAM) {
+  } else if (pContent->GetType() == PDFOBJ_STREAM) {
     CPDF_StreamAcc contentStream;
     contentStream.LoadAllData((CPDF_Stream*)pContent);
     ProcessForm(buf, contentStream.GetData(), contentStream.GetSize(), matrix);
diff --git a/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp b/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp
index b097389..d652215 100644
--- a/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp
+++ b/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp
@@ -79,7 +79,7 @@
         return -1;
       }
       offset += 1;
-      CPDF_Array* p = (CPDF_Array*)pObj;
+      const CPDF_Array* p = pObj->AsArray();
       for (FX_DWORD i = 0; i < p->GetCount(); i++) {
         CPDF_Object* pElement = p->GetElement(i);
         if (pElement->GetObjNum()) {
@@ -1195,7 +1195,7 @@
         return -1;
       }
       m_Offset += 1;
-      CPDF_Array* p = (CPDF_Array*)pObj;
+      const CPDF_Array* p = pObj->AsArray();
       for (FX_DWORD i = 0; i < p->GetCount(); i++) {
         CPDF_Object* pElement = p->GetElement(i);
         if (pElement->GetObjNum()) {
diff --git a/core/src/fpdfapi/fpdf_font/fpdf_font_cid.cpp b/core/src/fpdfapi/fpdf_font/fpdf_font_cid.cpp
index 81ec84b..687e8e1 100644
--- a/core/src/fpdfapi/fpdf_font/fpdf_font_cid.cpp
+++ b/core/src/fpdfapi/fpdf_font/fpdf_font_cid.cpp
@@ -1667,14 +1667,13 @@
   FX_DWORD count = pArray->GetCount();
   for (FX_DWORD i = 0; i < count; i++) {
     CPDF_Object* pObj = pArray->GetElementValue(i);
-    if (pObj == NULL) {
+    if (!pObj)
       continue;
-    }
-    if (pObj->GetType() == PDFOBJ_ARRAY) {
-      if (width_status != 1) {
+
+    if (CPDF_Array* pArray = pObj->AsArray()) {
+      if (width_status != 1)
         return;
-      }
-      CPDF_Array* pArray = (CPDF_Array*)pObj;
+
       FX_DWORD count = pArray->GetCount();
       for (FX_DWORD j = 0; j < count; j += nElements) {
         result.Add(first_code);
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page.cpp
index f6f0333..162acfa 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page.cpp
@@ -814,8 +814,7 @@
   if (rotate < 0) {
     rotate += 4;
   }
-  CPDF_Array *pMediaBox, *pCropBox;
-  pMediaBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("MediaBox"));
+  CPDF_Array* pMediaBox = ToArray(GetPageAttr(FX_BSTRC("MediaBox")));
   CFX_FloatRect mediabox;
   if (pMediaBox) {
     mediabox = pMediaBox->GetRect();
@@ -824,7 +823,8 @@
   if (mediabox.IsEmpty()) {
     mediabox = CFX_FloatRect(0, 0, 612, 792);
   }
-  pCropBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("CropBox"));
+
+  CPDF_Array* pCropBox = ToArray(GetPageAttr(FX_BSTRC("CropBox")));
   if (pCropBox) {
     m_BBox = pCropBox->GetRect();
     m_BBox.Normalize();
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
index 73b1091..4f54c01 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
@@ -1139,14 +1139,11 @@
   max = 1.0f;
 }
 FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
-  CPDF_Object* pObj = pArray->GetElementValue(1);
-  if (!pObj) {
+  CPDF_Array* pObj = ToArray(pArray->GetElementValue(1));
+  if (!pObj)
     return FALSE;
-  }
-  if (pObj->GetType() != PDFOBJ_ARRAY) {
-    return FALSE;
-  }
-  m_nComponents = ((CPDF_Array*)pObj)->GetCount();
+
+  m_nComponents = pObj->GetCount();
   CPDF_Object* pAltCS = pArray->GetElementValue(2);
   if (!pAltCS || pAltCS == m_pArray) {
     return FALSE;
@@ -1224,21 +1221,19 @@
     }
     return nullptr;
   }
-  if (pObj->GetType() != PDFOBJ_ARRAY) {
-    return NULL;
-  }
-  CPDF_Array* pArray = (CPDF_Array*)pObj;
-  if (pArray->GetCount() == 0) {
-    return NULL;
-  }
+
+  CPDF_Array* pArray = pObj->AsArray();
+  if (!pArray || pArray->GetCount() == 0)
+    return nullptr;
+
   CPDF_Object* pFamilyObj = pArray->GetElementValue(0);
-  if (!pFamilyObj) {
-    return NULL;
-  }
+  if (!pFamilyObj)
+    return nullptr;
+
   CFX_ByteString familyname = pFamilyObj->GetString();
-  if (pArray->GetCount() == 1) {
+  if (pArray->GetCount() == 1)
     return _CSFromName(familyname);
-  }
+
   CPDF_ColorSpace* pCS = NULL;
   FX_DWORD id = familyname.GetID();
   if (id == FXBSTR_ID('C', 'a', 'l', 'G')) {
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
index 9a1d48a..436cca6 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
@@ -343,10 +343,8 @@
     return pDefaultCS ? GetColorSpace(pDefaultCS, nullptr) : pCS;
   }
 
-  if (pCSObj->GetType() != PDFOBJ_ARRAY)
-    return nullptr;
-  CPDF_Array* pArray = (CPDF_Array*)pCSObj;
-  if (pArray->GetCount() == 0)
+  CPDF_Array* pArray = pCSObj->AsArray();
+  if (!pArray || pArray->GetCount() == 0)
     return nullptr;
   if (pArray->GetCount() == 1)
     return GetColorSpace(pArray->GetElementValue(0), pResources);
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp
index 62a3c67..78d3d26 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp
@@ -461,10 +461,10 @@
   while (pos) {
     CFX_ByteString key_str;
     CPDF_Object* pElement = pGS->GetNextElement(pos, key_str);
-    CPDF_Object* pObject = pElement ? pElement->GetDirect() : NULL;
-    if (pObject == NULL) {
+    CPDF_Object* pObject = pElement ? pElement->GetDirect() : nullptr;
+    if (!pObject)
       continue;
-    }
+
     FX_DWORD key = key_str.GetID();
     switch (key) {
       case FXBSTR_ID('L', 'W', 0, 0):
@@ -482,14 +482,14 @@
         m_GraphState.GetModify()->m_MiterLimit = pObject->GetNumber();
         break;
       case FXBSTR_ID('D', 0, 0, 0): {
-        if (pObject->GetType() != PDFOBJ_ARRAY) {
+        CPDF_Array* pDash = pObject->AsArray();
+        if (!pDash)
           break;
-        }
-        CPDF_Array* pDash = (CPDF_Array*)pObject;
+
         CPDF_Array* pArray = pDash->GetArray(0);
-        if (pArray == NULL) {
+        if (!pArray)
           break;
-        }
+
         SetLineDash(pArray, pDash->GetNumber(1), 1.0f);
         break;
       }
@@ -497,10 +497,10 @@
         m_GeneralState.SetRenderIntent(pObject->GetString());
         break;
       case FXBSTR_ID('F', 'o', 'n', 't'): {
-        if (pObject->GetType() != PDFOBJ_ARRAY) {
+        CPDF_Array* pFont = pObject->AsArray();
+        if (!pFont)
           break;
-        }
-        CPDF_Array* pFont = (CPDF_Array*)pObject;
+
         m_TextState.GetModify()->m_FontSize = pFont->GetNumber(1);
         m_TextState.SetFont(pParser->FindFont(pFont->GetString(0)));
         break;
@@ -514,12 +514,10 @@
             (pObject && !pObject->IsName()) ? pObject : nullptr;
         break;
       case FXBSTR_ID('B', 'M', 0, 0): {
-        CFX_ByteString mode;
-        if (pObject->GetType() == PDFOBJ_ARRAY) {
-          mode = ((CPDF_Array*)pObject)->GetString(0);
-        } else {
-          mode = pObject->GetString();
-        }
+        CPDF_Array* pArray = pObject->AsArray();
+        CFX_ByteString mode =
+            pArray ? pArray->GetString(0) : pObject->GetString();
+
         pGeneralState->SetBlendMode(mode);
         if (pGeneralState->m_BlendType > FXDIB_BLEND_MULTIPLY) {
           pParser->GetObjectList()->m_bBackgroundAlphaNeeded = TRUE;
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
index 6f186e6..7aa2cf8 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
@@ -514,7 +514,7 @@
       break;
     }
     case PDFOBJ_ARRAY: {
-      CPDF_Array* pArray = (CPDF_Array*)pObj;
+      CPDF_Array* pArray = pObj->AsArray();
       for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
         CPDF_Object* pElement = pArray->GetElement(i);
         if (pElement->IsName()) {
@@ -577,7 +577,7 @@
       break;
     }
     case PDFOBJ_ARRAY: {
-      CPDF_Array* pArray = (CPDF_Array*)pObj;
+      CPDF_Array* pArray = pObj->AsArray();
       for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
         CPDF_Object* pElement = pArray->GetElement(i);
         if (pElement->IsName()) {
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
index f051d0d..c27ede4 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
@@ -332,16 +332,16 @@
   CFX_ByteString Decoder;
   CPDF_Dictionary* pParam = NULL;
   CPDF_Object* pFilter = pDict->GetElementValue(FX_BSTRC("Filter"));
-  if (pFilter == NULL) {
-  } else if (pFilter->GetType() == PDFOBJ_ARRAY) {
-    Decoder = ((CPDF_Array*)pFilter)->GetString(0);
-    CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms"));
-    if (pParams) {
-      pParam = pParams->GetDict(0);
+  if (pFilter) {
+    if (CPDF_Array* pArray = pFilter->AsArray()) {
+      Decoder = pArray->GetString(0);
+      CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms"));
+      if (pParams)
+        pParam = pParams->GetDict(0);
+    } else {
+      Decoder = pFilter->GetString();
+      pParam = pDict->GetDict(FX_BSTRC("DecodeParms"));
     }
-  } else {
-    Decoder = pFilter->GetString();
-    pParam = pDict->GetDict(FX_BSTRC("DecodeParms"));
   }
   FX_DWORD width = pDict->GetInteger(FX_BSTRC("Width"));
   FX_DWORD height = pDict->GetInteger(FX_BSTRC("Height"));
@@ -403,12 +403,11 @@
     if (bDecode) {
       m_Pos += dwStreamSize;
       dwStreamSize = dwDestSize;
-      if (pFilter->GetType() == PDFOBJ_ARRAY) {
-        ((CPDF_Array*)pFilter)->RemoveAt(0);
+      if (CPDF_Array* pArray = pFilter->AsArray()) {
+        pArray->RemoveAt(0);
         CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms"));
-        if (pParams) {
+        if (pParams)
           pParams->RemoveAt(0);
-        }
       } else {
         pDict->RemoveAt(FX_BSTRC("Filter"));
         pDict->RemoveAt(FX_BSTRC("DecodeParms"));
@@ -965,8 +964,7 @@
     m_nStreams = 0;
     m_pSingleStream = new CPDF_StreamAcc;
     m_pSingleStream->LoadAllData((CPDF_Stream*)pContent, FALSE);
-  } else if (pContent->GetType() == PDFOBJ_ARRAY) {
-    CPDF_Array* pArray = (CPDF_Array*)pContent;
+  } else if (CPDF_Array* pArray = pContent->AsArray()) {
     m_nStreams = pArray->GetCount();
     if (m_nStreams == 0) {
       m_Status = Done;
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp
index 3f915a7..a73bdc9 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp
@@ -118,14 +118,11 @@
   }
   CPDF_Object* pFunc = pShadingDict->GetElementValue(FX_BSTRC("Function"));
   if (pFunc) {
-    if (pFunc->GetType() == PDFOBJ_ARRAY) {
-      m_nFuncs = ((CPDF_Array*)pFunc)->GetCount();
-      if (m_nFuncs > 4) {
-        m_nFuncs = 4;
-      }
+    if (CPDF_Array* pArray = pFunc->AsArray()) {
+      m_nFuncs = std::min<int>(pArray->GetCount(), 4);
+
       for (int i = 0; i < m_nFuncs; i++) {
-        m_pFunctions[i] =
-            CPDF_Function::Load(((CPDF_Array*)pFunc)->GetElementValue(i));
+        m_pFunctions[i] = CPDF_Function::Load(pArray->GetElementValue(i));
       }
     } else {
       m_pFunctions[0] = CPDF_Function::Load(pFunc);
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp
index cbbfbd7..1815d40 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp
@@ -331,31 +331,27 @@
 
 {
   CPDF_Object* pDecoder =
-      pDict ? pDict->GetElementValue(FX_BSTRC("Filter")) : NULL;
-  if (!pDecoder || (pDecoder->GetType() != PDFOBJ_ARRAY && !pDecoder->IsName()))
+      pDict ? pDict->GetElementValue(FX_BSTRC("Filter")) : nullptr;
+  if (!pDecoder || (!pDecoder->IsArray() && !pDecoder->IsName()))
     return FALSE;
 
   CPDF_Object* pParams =
-      pDict ? pDict->GetElementValue(FX_BSTRC("DecodeParms")) : NULL;
+      pDict ? pDict->GetElementValue(FX_BSTRC("DecodeParms")) : nullptr;
   CFX_ByteStringArray DecoderList;
   CFX_PtrArray ParamList;
-  if (pDecoder->GetType() == PDFOBJ_ARRAY) {
-    if (pParams && pParams->GetType() != PDFOBJ_ARRAY) {
-      pParams = NULL;
-    }
-    CPDF_Array* pDecoders = (CPDF_Array*)pDecoder;
+  if (CPDF_Array* pDecoders = pDecoder->AsArray()) {
+    CPDF_Array* pParamsArray = ToArray(pParams);
+    if (!pParamsArray)
+      pParams = nullptr;
+
     for (FX_DWORD i = 0; i < pDecoders->GetCount(); i++) {
       CFX_ByteStringC str = pDecoders->GetConstString(i);
       DecoderList.Add(str);
-      if (pParams) {
-        ParamList.Add(((CPDF_Array*)pParams)->GetDict(i));
-      } else {
-        ParamList.Add(NULL);
-      }
+      ParamList.Add(pParams ? pParamsArray->GetDict(i) : nullptr);
     }
   } else {
     DecoderList.Add(pDecoder->GetConstString());
-    ParamList.Add(pParams ? pParams->GetDict() : NULL);
+    ParamList.Add(pParams ? pParams->GetDict() : nullptr);
   }
   uint8_t* last_buf = (uint8_t*)src_buf;
   FX_DWORD last_size = src_size;
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_document.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_document.cpp
index c98f8da..238347a 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_document.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_document.cpp
@@ -305,7 +305,7 @@
       continue;
     }
     if (pContents->GetDirectType() == PDFOBJ_ARRAY) {
-      CPDF_Array* pArray = (CPDF_Array*)pContents->GetDirect();
+      CPDF_Array* pArray = pContents->GetDirect()->AsArray();
       for (FX_DWORD j = 0; j < pArray->GetCount(); j++) {
         CPDF_Object* pRef = pArray->GetElement(j);
         if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp
index dd25044..a006138 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects.cpp
@@ -25,7 +25,7 @@
       delete AsName();
       break;
     case PDFOBJ_ARRAY:
-      delete (CPDF_Array*)this;
+      delete AsArray();
       break;
     case PDFOBJ_DICTIONARY:
       delete AsDictionary();
@@ -161,10 +161,9 @@
 }
 
 CPDF_Array* CPDF_Object::GetArray() const {
-  if (m_Type == PDFOBJ_ARRAY)
-    return (CPDF_Array*)this;
-
-  return NULL;
+  // The method should be made non-const if we want to not be const.
+  // See bug #234.
+  return const_cast<CPDF_Array*>(AsArray());
 }
 void CPDF_Object::SetString(const CFX_ByteString& str) {
   ASSERT(this != NULL);
@@ -217,7 +216,7 @@
     case PDFOBJ_NAME:
       return AsName()->Identical(pOther->AsName());
     case PDFOBJ_ARRAY:
-      return (((CPDF_Array*)this)->Identical((CPDF_Array*)pOther));
+      return AsArray()->Identical(pOther->AsArray());
     case PDFOBJ_DICTIONARY:
       return AsDictionary()->Identical(pOther->AsDictionary());
     case PDFOBJ_NULL:
@@ -261,7 +260,7 @@
       return new CPDF_Name(AsName()->m_Name);
     case PDFOBJ_ARRAY: {
       CPDF_Array* pCopy = new CPDF_Array();
-      CPDF_Array* pThis = (CPDF_Array*)this;
+      const CPDF_Array* pThis = AsArray();
       int n = pThis->GetCount();
       for (int i = 0; i < n; i++) {
         CPDF_Object* value = (CPDF_Object*)pThis->m_Objects.GetAt(i);
@@ -341,6 +340,14 @@
   }
 }
 
+CPDF_Array* CPDF_Object::AsArray() {
+  return IsArray() ? static_cast<CPDF_Array*>(this) : nullptr;
+}
+
+const CPDF_Array* CPDF_Object::AsArray() const {
+  return IsArray() ? static_cast<const CPDF_Array*>(this) : nullptr;
+}
+
 CPDF_Boolean* CPDF_Object::AsBoolean() {
   return IsBoolean() ? static_cast<CPDF_Boolean*>(this) : nullptr;
 }
@@ -420,9 +427,9 @@
 }
 CFX_FloatRect CPDF_Array::GetRect() {
   CFX_FloatRect rect;
-  if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 4) {
+  if (!IsArray() || m_Objects.GetSize() != 4)
     return rect;
-  }
+
   rect.left = GetNumber(0);
   rect.bottom = GetNumber(1);
   rect.right = GetNumber(2);
@@ -431,9 +438,9 @@
 }
 CFX_AffineMatrix CPDF_Array::GetMatrix() {
   CFX_AffineMatrix matrix;
-  if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 6) {
+  if (!IsArray() || m_Objects.GetSize() != 6)
     return matrix;
-  }
+
   matrix.Set(GetNumber(0), GetNumber(1), GetNumber(2), GetNumber(3),
              GetNumber(4), GetNumber(5));
   return matrix;
@@ -499,14 +506,10 @@
   return (CPDF_Stream*)p;
 }
 CPDF_Array* CPDF_Array::GetArray(FX_DWORD i) const {
-  CPDF_Object* p = GetElementValue(i);
-  if (p == NULL || p->GetType() != PDFOBJ_ARRAY) {
-    return NULL;
-  }
-  return (CPDF_Array*)p;
+  return ToArray(GetElementValue(i));
 }
 void CPDF_Array::RemoveAt(FX_DWORD i) {
-  ASSERT(m_Type == PDFOBJ_ARRAY);
+  ASSERT(IsArray());
   if (i >= (FX_DWORD)m_Objects.GetSize()) {
     return;
   }
@@ -518,7 +521,7 @@
 void CPDF_Array::SetAt(FX_DWORD i,
                        CPDF_Object* pObj,
                        CPDF_IndirectObjects* pObjs) {
-  ASSERT(m_Type == PDFOBJ_ARRAY);
+  ASSERT(IsArray());
   ASSERT(i < (FX_DWORD)m_Objects.GetSize());
   if (i >= (FX_DWORD)m_Objects.GetSize()) {
     return;
@@ -551,25 +554,25 @@
   m_Objects.Add(pObj);
 }
 void CPDF_Array::AddName(const CFX_ByteString& str) {
-  ASSERT(m_Type == PDFOBJ_ARRAY);
+  ASSERT(IsArray());
   Add(new CPDF_Name(str));
 }
 void CPDF_Array::AddString(const CFX_ByteString& str) {
-  ASSERT(m_Type == PDFOBJ_ARRAY);
+  ASSERT(IsArray());
   Add(new CPDF_String(str));
 }
 void CPDF_Array::AddInteger(int i) {
-  ASSERT(m_Type == PDFOBJ_ARRAY);
+  ASSERT(IsArray());
   Add(new CPDF_Number(i));
 }
 void CPDF_Array::AddNumber(FX_FLOAT f) {
-  ASSERT(m_Type == PDFOBJ_ARRAY);
+  ASSERT(IsArray());
   CPDF_Number* pNumber = new CPDF_Number;
   pNumber->SetNumber(f);
   Add(pNumber);
 }
 void CPDF_Array::AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum) {
-  ASSERT(m_Type == PDFOBJ_ARRAY);
+  ASSERT(IsArray());
   Add(new CPDF_Reference(pDoc, objnum));
 }
 FX_BOOL CPDF_Array::Identical(CPDF_Array* pOther) const {
@@ -712,11 +715,7 @@
   return nullptr;
 }
 CPDF_Array* CPDF_Dictionary::GetArray(const CFX_ByteStringC& key) const {
-  CPDF_Object* p = GetElementValue(key);
-  if (p == NULL || p->GetType() != PDFOBJ_ARRAY) {
-    return NULL;
-  }
-  return (CPDF_Array*)p;
+  return ToArray(GetElementValue(key));
 }
 CPDF_Stream* CPDF_Dictionary::GetStream(const CFX_ByteStringC& key) const {
   CPDF_Object* p = GetElementValue(key);
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
index f6e1ee8..717a5d1 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp
@@ -1154,17 +1154,14 @@
 }
 CPDF_Array* CPDF_Parser::GetIDArray() {
   CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("ID")) : NULL;
-  if (pID == NULL) {
-    return NULL;
-  }
+  if (!pID)
+    return nullptr;
+
   if (pID->GetType() == PDFOBJ_REFERENCE) {
     pID = ParseIndirectObject(NULL, ((CPDF_Reference*)pID)->GetRefObjNum());
     m_pTrailer->SetAt(FX_BSTRC("ID"), pID);
   }
-  if (pID == NULL || pID->GetType() != PDFOBJ_ARRAY) {
-    return NULL;
-  }
-  return (CPDF_Array*)pID;
+  return ToArray(pID);
 }
 FX_DWORD CPDF_Parser::GetRootObjNum() {
   CPDF_Object* pRef =
@@ -3480,7 +3477,7 @@
       }
       continue;
     }
-    if (pObj->GetType() == PDFOBJ_ARRAY) {
+    if (pObj->IsArray()) {
       CPDF_Array* pArray = pObj->GetArray();
       if (pArray) {
         int32_t iSize = pArray->GetCount();
@@ -3549,7 +3546,7 @@
       m_PageObjList.Add(pKid->GetRefObjNum());
     } break;
     case PDFOBJ_ARRAY: {
-      CPDF_Array* pKidsArray = (CPDF_Array*)pKids;
+      CPDF_Array* pKidsArray = pKids->AsArray();
       for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) {
         CPDF_Object* pKid = (CPDF_Object*)pKidsArray->GetElement(i);
         if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) {
@@ -4122,13 +4119,15 @@
     }
     return FALSE;
   }
-  if (pPages->GetType() != PDFOBJ_ARRAY) {
+
+  CPDF_Array* pArray = pPages->AsArray();
+  if (!pArray) {
     pPages->Release();
     m_docStatus = PDF_DATAAVAIL_ERROR;
     return FALSE;
   }
+
   pPageNode->m_type = PDF_PAGENODE_PAGES;
-  CPDF_Array* pArray = (CPDF_Array*)pPages;
   for (FX_DWORD i = 0; i < pArray->GetCount(); ++i) {
     CPDF_Object* pKid = (CPDF_Object*)pArray->GetElement(i);
     if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) {
@@ -4157,7 +4156,7 @@
     }
     return FALSE;
   }
-  if (pPage->GetType() == PDFOBJ_ARRAY) {
+  if (pPage->IsArray()) {
     pPageNode->m_dwPageNo = dwPageNo;
     pPageNode->m_type = PDF_PAGENODE_ARRAY;
     pPage->Release();
@@ -4186,7 +4185,7 @@
         pNode->m_dwPageNo = pKid->GetRefObjNum();
       } break;
       case PDFOBJ_ARRAY: {
-        CPDF_Array* pKidsArray = (CPDF_Array*)pKids;
+        CPDF_Array* pKidsArray = pKids->AsArray();
         for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) {
           CPDF_Object* pKid = (CPDF_Object*)pKidsArray->GetElement(i);
           if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) {
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp
index 2c161a7..a2d65fa 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp
@@ -386,7 +386,7 @@
       break;
     }
     case PDFOBJ_ARRAY: {
-      CPDF_Array* p = (CPDF_Array*)pObj;
+      const CPDF_Array* p = pObj->AsArray();
       buf << FX_BSTRC("[");
       for (FX_DWORD i = 0; i < p->GetCount(); i++) {
         CPDF_Object* pElement = p->GetElement(i);
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render.cpp
index 99835a3..7b37b1b 100644
--- a/core/src/fpdfapi/fpdf_render/fpdf_render.cpp
+++ b/core/src/fpdfapi/fpdf_render/fpdf_render.cpp
@@ -1225,9 +1225,8 @@
   CPDF_Function* pFuncs[3] = {nullptr, nullptr, nullptr};
   FX_BOOL bUniTransfer = TRUE;
   FX_BOOL bIdentity = TRUE;
-  if (pObj->GetType() == PDFOBJ_ARRAY) {
+  if (CPDF_Array* pArray = pObj->AsArray()) {
     bUniTransfer = FALSE;
-    CPDF_Array* pArray = (CPDF_Array*)pObj;
     if (pArray->GetCount() < 3)
       return nullptr;
 
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp
index cdf2104..2754223 100644
--- a/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp
+++ b/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp
@@ -412,8 +412,7 @@
             bsDecodeType == FX_BSTRC("JPXDecode")) {
           m_Flags |= FXRENDER_IMAGE_LOSSY;
         }
-      } else if (pFilters->GetType() == PDFOBJ_ARRAY) {
-        CPDF_Array* pArray = (CPDF_Array*)pFilters;
+      } else if (CPDF_Array* pArray = pFilters->AsArray()) {
         for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
           CFX_ByteStringC bsDecodeType = pArray->GetConstString(i);
           if (bsDecodeType == FX_BSTRC("DCTDecode") ||
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
index 79b4bba..fecd6da 100644
--- a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
+++ b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
@@ -482,8 +482,7 @@
             m_bDoBpcCheck = FALSE;
             return TRUE;
           }
-        } else if (pFilter->GetType() == PDFOBJ_ARRAY) {
-          CPDF_Array* pArray = (CPDF_Array*)pFilter;
+        } else if (CPDF_Array* pArray = pFilter->AsArray()) {
           if (pArray->GetString(pArray->GetCount() - 1) ==
               FX_BSTRC("JPXDecode")) {
             m_bDoBpcCheck = FALSE;
@@ -570,8 +569,7 @@
     if (pMask == NULL) {
       return pCompData;
     }
-    if (pMask->GetType() == PDFOBJ_ARRAY) {
-      CPDF_Array* pArray = (CPDF_Array*)pMask;
+    if (CPDF_Array* pArray = pMask->AsArray()) {
       if (pArray->GetCount() >= m_nComponents * 2) {
         for (FX_DWORD i = 0; i < m_nComponents; i++) {
           int min_num = pArray->GetInteger(i * 2);
@@ -953,8 +951,7 @@
       } else if (filter == FX_BSTRC("DCTDecode")) {
         m_bpc = 8;
       }
-    } else if (pFilter->GetType() == PDFOBJ_ARRAY) {
-      CPDF_Array* pArray = (CPDF_Array*)pFilter;
+    } else if (CPDF_Array* pArray = pFilter->AsArray()) {
       if (pArray->GetString(pArray->GetCount() - 1) ==
               FX_BSTRC("CCITTFaxDecode") ||
           pArray->GetString(pArray->GetCount() - 1) ==
diff --git a/core/src/fpdfdoc/doc_action.cpp b/core/src/fpdfdoc/doc_action.cpp
index bcbfe0f..d685f64 100644
--- a/core/src/fpdfdoc/doc_action.cpp
+++ b/core/src/fpdfdoc/doc_action.cpp
@@ -22,9 +22,8 @@
     CFX_ByteStringC name = pDest->GetString();
     return CPDF_Dest(name_tree.LookupNamedDest(pDoc, name));
   }
-  if (pDest->GetType() == PDFOBJ_ARRAY) {
-    return CPDF_Dest((CPDF_Array*)pDest);
-  }
+  if (CPDF_Array* pArray = pDest->AsArray())
+    return CPDF_Dest(pArray);
   return CPDF_Dest();
 }
 const FX_CHAR* g_sATypes[] = {
@@ -108,8 +107,8 @@
     return 1;
   if (pFields->IsString())
     return 1;
-  if (pFields->GetType() == PDFOBJ_ARRAY)
-    return ((CPDF_Array*)pFields)->GetCount();
+  if (CPDF_Array* pArray = pFields->AsArray())
+    return pArray->GetCount();
   return 0;
 }
 void CPDF_ActionFields::GetAllFields(CFX_PtrArray& fieldObjects) const {
@@ -133,8 +132,7 @@
 
   if (pFields->IsDictionary() || pFields->IsString()) {
     fieldObjects.Add(pFields);
-  } else if (pFields->GetType() == PDFOBJ_ARRAY) {
-    CPDF_Array* pArray = (CPDF_Array*)pFields;
+  } else if (CPDF_Array* pArray = pFields->AsArray()) {
     FX_DWORD iCount = pArray->GetCount();
     for (FX_DWORD i = 0; i < iCount; i++) {
       CPDF_Object* pObj = pArray->GetElementValue(i);
@@ -166,8 +164,8 @@
   if (pFields->IsDictionary() || pFields->IsString()) {
     if (iIndex == 0)
       pFindObj = pFields;
-  } else if (pFields->GetType() == PDFOBJ_ARRAY) {
-    pFindObj = ((CPDF_Array*)pFields)->GetElementValue(iIndex);
+  } else if (CPDF_Array* pArray = pFields->AsArray()) {
+    pFindObj = pArray->GetElementValue(iIndex);
   }
   return pFindObj;
 }
@@ -222,20 +220,16 @@
   return 0;
 }
 FX_DWORD CPDF_Action::GetSubActionsCount() const {
-  if (m_pDict == NULL || !m_pDict->KeyExist("Next")) {
+  if (!m_pDict || !m_pDict->KeyExist("Next"))
     return 0;
-  }
+
   CPDF_Object* pNext = m_pDict->GetElementValue("Next");
-  if (!pNext) {
+  if (!pNext)
     return 0;
-  }
-  int iObjType = pNext->GetType();
-  if (iObjType == PDFOBJ_DICTIONARY) {
+  if (pNext->IsDictionary())
     return 1;
-  }
-  if (iObjType == PDFOBJ_ARRAY) {
-    return ((CPDF_Array*)pNext)->GetCount();
-  }
+  if (CPDF_Array* pArray = pNext->AsArray())
+    return pArray->GetCount();
   return 0;
 }
 CPDF_Action CPDF_Action::GetSubAction(FX_DWORD iIndex) const {
@@ -246,8 +240,7 @@
   if (CPDF_Dictionary* pDict = ToDictionary(pNext)) {
     if (iIndex == 0)
       return CPDF_Action(pDict);
-  } else if (pNext->GetType() == PDFOBJ_ARRAY) {
-    CPDF_Array* pArray = static_cast<CPDF_Array*>(pNext);
+  } else if (CPDF_Array* pArray = ToArray(pNext)) {
     return CPDF_Action(pArray->GetDict(iIndex));
   }
   return CPDF_Action();
diff --git a/core/src/fpdfdoc/doc_ap.cpp b/core/src/fpdfdoc/doc_ap.cpp
index 71025ec..77a1f15 100644
--- a/core/src/fpdfdoc/doc_ap.cpp
+++ b/core/src/fpdfdoc/doc_ap.cpp
@@ -618,12 +618,11 @@
           }
           if (CPDF_Object* pOpt = pOpts->GetElementValue(i)) {
             CFX_WideString swItem;
-            if (pOpt->IsString()) {
+            if (pOpt->IsString())
               swItem = pOpt->GetUnicodeText();
-            } else if (pOpt->GetType() == PDFOBJ_ARRAY) {
-              swItem =
-                  ((CPDF_Array*)pOpt)->GetElementValue(1)->GetUnicodeText();
-            }
+            else if (CPDF_Array* pArray = pOpt->AsArray())
+              swItem = pArray->GetElementValue(1)->GetUnicodeText();
+
             FX_BOOL bSelected = FALSE;
             if (pSels) {
               for (FX_DWORD s = 0, ssz = pSels->GetCount(); s < ssz; s++) {
diff --git a/core/src/fpdfdoc/doc_basic.cpp b/core/src/fpdfdoc/doc_basic.cpp
index cbf956b..b32e34b 100644
--- a/core/src/fpdfdoc/doc_basic.cpp
+++ b/core/src/fpdfdoc/doc_basic.cpp
@@ -7,10 +7,11 @@
 #include "../../include/fpdfdoc/fpdf_doc.h"
 const int nMaxRecursion = 32;
 int CPDF_Dest::GetPageIndex(CPDF_Document* pDoc) {
-  if (m_pObj == NULL || m_pObj->GetType() != PDFOBJ_ARRAY) {
+  CPDF_Array* pArray = ToArray(m_pObj);
+  if (!pArray)
     return 0;
-  }
-  CPDF_Object* pPage = ((CPDF_Array*)m_pObj)->GetElementValue(0);
+
+  CPDF_Object* pPage = pArray->GetElementValue(0);
   if (!pPage)
     return 0;
   if (pPage->IsNumber())
@@ -20,10 +21,11 @@
   return pDoc->GetPageIndex(pPage->GetObjNum());
 }
 FX_DWORD CPDF_Dest::GetPageObjNum() {
-  if (m_pObj == NULL || m_pObj->GetType() != PDFOBJ_ARRAY) {
+  CPDF_Array* pArray = ToArray(m_pObj);
+  if (!pArray)
     return 0;
-  }
-  CPDF_Object* pPage = ((CPDF_Array*)m_pObj)->GetElementValue(0);
+
+  CPDF_Object* pPage = pArray->GetElementValue(0);
   if (!pPage)
     return 0;
   if (pPage->IsNumber())
@@ -35,11 +37,12 @@
 const FX_CHAR* g_sZoomModes[] = {"XYZ",  "Fit",   "FitH",  "FitV", "FitR",
                                  "FitB", "FitBH", "FitBV", ""};
 int CPDF_Dest::GetZoomMode() {
-  if (m_pObj == NULL || m_pObj->GetType() != PDFOBJ_ARRAY) {
+  CPDF_Array* pArray = ToArray(m_pObj);
+  if (!pArray)
     return 0;
-  }
+
   CFX_ByteString mode;
-  CPDF_Object* pObj = ((CPDF_Array*)m_pObj)->GetElementValue(1);
+  CPDF_Object* pObj = pArray->GetElementValue(1);
   mode = pObj ? pObj->GetString() : CFX_ByteString();
   int i = 0;
   while (g_sZoomModes[i][0] != '\0') {
@@ -51,16 +54,11 @@
   return 0;
 }
 FX_FLOAT CPDF_Dest::GetParam(int index) {
-  if (m_pObj == NULL || m_pObj->GetType() != PDFOBJ_ARRAY) {
-    return 0;
-  }
-  return ((CPDF_Array*)m_pObj)->GetNumber(2 + index);
+  CPDF_Array* pArray = ToArray(m_pObj);
+  return pArray ? pArray->GetNumber(2 + index) : 0;
 }
 CFX_ByteString CPDF_Dest::GetRemoteName() {
-  if (m_pObj == NULL) {
-    return CFX_ByteString();
-  }
-  return m_pObj->GetString();
+  return m_pObj ? m_pObj->GetString() : CFX_ByteString();
 }
 CPDF_NameTree::CPDF_NameTree(CPDF_Document* pDoc,
                              const CFX_ByteStringC& category) {
@@ -224,23 +222,19 @@
 CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc,
                                            const CFX_ByteStringC& sName) {
   CPDF_Object* pValue = LookupValue(sName);
-  if (pValue == NULL) {
+  if (!pValue) {
     CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDict(FX_BSTRC("Dests"));
-    if (pDests == NULL) {
-      return NULL;
-    }
+    if (!pDests)
+      return nullptr;
     pValue = pDests->GetElementValue(sName);
   }
-  if (pValue == NULL) {
-    return NULL;
-  }
-  if (pValue->GetType() == PDFOBJ_ARRAY) {
-    return (CPDF_Array*)pValue;
-  }
-  if (CPDF_Dictionary* pDict = pValue->AsDictionary()) {
+  if (!pValue)
+    return nullptr;
+  if (CPDF_Array* pArray = pValue->AsArray())
+    return pArray;
+  if (CPDF_Dictionary* pDict = pValue->AsDictionary())
     return pDict->GetArray(FX_BSTRC("D"));
-  }
-  return NULL;
+  return nullptr;
 }
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \
     _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
diff --git a/core/src/fpdfdoc/doc_bookmark.cpp b/core/src/fpdfdoc/doc_bookmark.cpp
index 6b020e5..5ebd27e 100644
--- a/core/src/fpdfdoc/doc_bookmark.cpp
+++ b/core/src/fpdfdoc/doc_bookmark.cpp
@@ -68,21 +68,19 @@
   return CFX_WideString(buf.get(), len);
 }
 CPDF_Dest CPDF_Bookmark::GetDest(CPDF_Document* pDocument) const {
-  if (!m_pDict) {
+  if (!m_pDict)
     return CPDF_Dest();
-  }
+
   CPDF_Object* pDest = m_pDict->GetElementValue("Dest");
   if (!pDest)
     return CPDF_Dest();
-
   if (pDest->IsString() || pDest->IsName()) {
     CPDF_NameTree name_tree(pDocument, FX_BSTRC("Dests"));
     CFX_ByteStringC name = pDest->GetString();
     return CPDF_Dest(name_tree.LookupNamedDest(pDocument, name));
   }
-  if (pDest->GetType() == PDFOBJ_ARRAY) {
-    return CPDF_Dest((CPDF_Array*)pDest);
-  }
+  if (CPDF_Array* pArray = pDest->AsArray())
+    return CPDF_Dest(pArray);
   return CPDF_Dest();
 }
 CPDF_Action CPDF_Bookmark::GetAction() const {
diff --git a/core/src/fpdfdoc/doc_formcontrol.cpp b/core/src/fpdfdoc/doc_formcontrol.cpp
index c5f47d2..35329f9 100644
--- a/core/src/fpdfdoc/doc_formcontrol.cpp
+++ b/core/src/fpdfdoc/doc_formcontrol.cpp
@@ -85,15 +85,13 @@
   CFX_ByteString csOn = GetOnStateName();
   if (GetType() == CPDF_FormField::RadioButton ||
       GetType() == CPDF_FormField::CheckBox) {
-    CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pField->m_pDict, "Opt");
-    if (pOpt != NULL && pOpt->GetType() == PDFOBJ_ARRAY) {
+    if (ToArray(FPDF_GetFieldAttr(m_pField->m_pDict, "Opt"))) {
       int iIndex = m_pField->GetControlIndex(this);
       csOn.Format("%d", iIndex);
     }
   }
-  if (csOn.IsEmpty()) {
+  if (csOn.IsEmpty())
     csOn = "Yes";
-  }
   return csOn;
 }
 CFX_WideString CPDF_FormControl::GetExportValue() {
@@ -102,10 +100,10 @@
   CFX_ByteString csOn = GetOnStateName();
   if (GetType() == CPDF_FormField::RadioButton ||
       GetType() == CPDF_FormField::CheckBox) {
-    CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pField->m_pDict, "Opt");
-    if (pOpt != NULL && pOpt->GetType() == PDFOBJ_ARRAY) {
+    if (CPDF_Array* pArray =
+            ToArray(FPDF_GetFieldAttr(m_pField->m_pDict, "Opt"))) {
       int iIndex = m_pField->GetControlIndex(this);
-      csOn = ((CPDF_Array*)pOpt)->GetString(iIndex);
+      csOn = pArray->GetString(iIndex);
     }
   }
   if (csOn.IsEmpty()) {
diff --git a/core/src/fpdfdoc/doc_formfield.cpp b/core/src/fpdfdoc/doc_formfield.cpp
index 0766eb0..efa2ea2 100644
--- a/core/src/fpdfdoc/doc_formfield.cpp
+++ b/core/src/fpdfdoc/doc_formfield.cpp
@@ -307,10 +307,9 @@
     case PDFOBJ_STREAM:
       return pValue->GetUnicodeText();
     case PDFOBJ_ARRAY:
-      pValue = ((CPDF_Array*)pValue)->GetElementValue(0);
-      if (pValue) {
+      pValue = pValue->AsArray()->GetElementValue(0);
+      if (pValue)
         return pValue->GetUnicodeText();
-      }
       break;
   }
   return CFX_WideString();
@@ -419,28 +418,24 @@
 }
 int CPDF_FormField::CountSelectedItems() {
   CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V");
-  if (pValue == NULL) {
+  if (!pValue) {
     pValue = FPDF_GetFieldAttr(m_pDict, "I");
-    if (pValue == NULL) {
+    if (!pValue)
       return 0;
-    }
   }
 
   if (pValue->IsString() || pValue->IsNumber())
     return pValue->GetString().IsEmpty() ? 0 : 1;
-
-  if (pValue->GetType() != PDFOBJ_ARRAY) {
-    return 0;
-  }
-  return ((CPDF_Array*)pValue)->GetCount();
+  if (CPDF_Array* pArray = pValue->AsArray())
+    return pArray->GetCount();
+  return 0;
 }
 int CPDF_FormField::GetSelectedIndex(int index) {
   CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V");
-  if (pValue == NULL) {
+  if (!pValue) {
     pValue = FPDF_GetFieldAttr(m_pDict, "I");
-    if (pValue == NULL) {
+    if (!pValue)
       return -1;
-    }
   }
   if (pValue->IsNumber())
     return pValue->GetInteger();
@@ -449,16 +444,13 @@
   if (pValue->IsString()) {
     if (index != 0)
       return -1;
-
     sel_value = pValue->GetUnicodeText();
   } else {
-    if (pValue->GetType() != PDFOBJ_ARRAY) {
+    CPDF_Array* pArray = pValue->AsArray();
+    if (!pArray || index < 0)
       return -1;
-    }
-    if (index < 0) {
-      return -1;
-    }
-    CPDF_Object* elementValue = ((CPDF_Array*)pValue)->GetElementValue(index);
+
+    CPDF_Object* elementValue = pArray->GetElementValue(index);
     sel_value =
         elementValue ? elementValue->GetUnicodeText() : CFX_WideString();
   }
@@ -537,10 +529,10 @@
     return (pValue->GetInteger() == index);
   }
 
-  if (pValue->GetType() != PDFOBJ_ARRAY) {
+  CPDF_Array* pArray = pValue->AsArray();
+  if (!pArray)
     return FALSE;
-  }
-  CPDF_Array* pArray = (CPDF_Array*)pValue;
+
   int iPos = -1;
   for (int j = 0; j < CountSelectedOptions(); j++) {
     if (GetSelectedOptionIndex(j) == index) {
@@ -584,11 +576,8 @@
           if (pValue->GetUnicodeText() == opt_value) {
             m_pDict->RemoveAt("V");
           }
-        } else if (pValue->GetType() == PDFOBJ_ARRAY) {
+        } else if (pValue->IsArray()) {
           CPDF_Array* pArray = CPDF_Array::Create();
-          if (pArray == NULL) {
-            return FALSE;
-          }
           int iCount = CountOptions();
           for (int i = 0; i < iCount; i++) {
             if (i != index) {
@@ -703,24 +692,19 @@
   }
 }
 int CPDF_FormField::CountOptions() {
-  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "Opt");
-  if (pValue == NULL || pValue->GetType() != PDFOBJ_ARRAY) {
-    return 0;
-  }
-  return ((CPDF_Array*)pValue)->GetCount();
+  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict, "Opt"));
+  return pArray ? pArray->GetCount() : 0;
 }
 CFX_WideString CPDF_FormField::GetOptionText(int index, int sub_index) {
-  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "Opt");
-  if (pValue == NULL || pValue->GetType() != PDFOBJ_ARRAY) {
+  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict, "Opt"));
+  if (!pArray)
     return CFX_WideString();
-  }
-  CPDF_Object* pOption = ((CPDF_Array*)pValue)->GetElementValue(index);
-  if (pOption == NULL) {
+
+  CPDF_Object* pOption = pArray->GetElementValue(index);
+  if (!pOption)
     return CFX_WideString();
-  }
-  if (pOption->GetType() == PDFOBJ_ARRAY) {
-    pOption = ((CPDF_Array*)pOption)->GetElementValue(sub_index);
-  }
+  if (CPDF_Array* pOptionArray = pOption->AsArray())
+    pOption = pOptionArray->GetElementValue(sub_index);
 
   CPDF_String* pString = ToString(pOption);
   return pString ? pString->GetUnicodeText() : CFX_WideString();
@@ -873,7 +857,7 @@
     }
   }
   CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict, "Opt");
-  if (pOpt == NULL || pOpt->GetType() != PDFOBJ_ARRAY) {
+  if (!ToArray(pOpt)) {
     if (bChecked) {
       m_pDict->SetAtName("V", csBExport);
     } else {
diff --git a/core/src/fpdfdoc/doc_link.cpp b/core/src/fpdfdoc/doc_link.cpp
index 977efea..6d3f6c5 100644
--- a/core/src/fpdfdoc/doc_link.cpp
+++ b/core/src/fpdfdoc/doc_link.cpp
@@ -81,9 +81,8 @@
     CFX_ByteStringC name = pDest->GetString();
     return CPDF_Dest(name_tree.LookupNamedDest(pDoc, name));
   }
-  if (pDest->GetType() == PDFOBJ_ARRAY) {
-    return CPDF_Dest((CPDF_Array*)pDest);
-  }
+  if (CPDF_Array* pArray = pDest->AsArray())
+    return CPDF_Dest(pArray);
   return CPDF_Dest();
 }
 CPDF_Action CPDF_Link::GetAction() {
diff --git a/core/src/fpdfdoc/doc_ocg.cpp b/core/src/fpdfdoc/doc_ocg.cpp
index e66b044..b252456 100644
--- a/core/src/fpdfdoc/doc_ocg.cpp
+++ b/core/src/fpdfdoc/doc_ocg.cpp
@@ -7,23 +7,18 @@
 #include "../../include/fpdfdoc/fpdf_doc.h"
 static int32_t FPDFDOC_OCG_FindGroup(const CPDF_Object* pObject,
                                      const CPDF_Dictionary* pGroupDict) {
-  if (pObject == NULL || pGroupDict == NULL) {
+  if (!pObject || !pGroupDict)
     return -1;
-  }
-  int32_t iType = pObject->GetType();
-  if (iType == PDFOBJ_ARRAY) {
-    FX_DWORD dwCount = ((CPDF_Array*)pObject)->GetCount();
+
+  if (const CPDF_Array* pArray = pObject->AsArray()) {
+    FX_DWORD dwCount = pArray->GetCount();
     for (FX_DWORD i = 0; i < dwCount; i++) {
-      if (((CPDF_Array*)pObject)->GetDict(i) == pGroupDict) {
+      if (pArray->GetDict(i) == pGroupDict)
         return i;
-      }
     }
     return -1;
   }
-  if (pObject->GetDict() == pGroupDict) {
-    return 0;
-  }
-  return -1;
+  return pObject->GetDict() == pGroupDict ? 0 : -1;
 }
 static FX_BOOL FPDFDOC_OCG_HasIntent(
     const CPDF_Dictionary* pDict,
@@ -35,13 +30,12 @@
     return csElement == csDef;
   }
   CFX_ByteString bsIntent;
-  if (pIntent->GetType() == PDFOBJ_ARRAY) {
-    FX_DWORD dwCount = ((CPDF_Array*)pIntent)->GetCount();
+  if (CPDF_Array* pArray = pIntent->AsArray()) {
+    FX_DWORD dwCount = pArray->GetCount();
     for (FX_DWORD i = 0; i < dwCount; i++) {
-      bsIntent = ((CPDF_Array*)pIntent)->GetString(i);
-      if (bsIntent == FX_BSTRC("All") || bsIntent == csElement) {
+      bsIntent = pArray->GetString(i);
+      if (bsIntent == FX_BSTRC("All") || bsIntent == csElement)
         return TRUE;
-      }
     }
     return FALSE;
   }
@@ -206,15 +200,12 @@
   CFX_ByteString csOperator = pExpression->GetString(0);
   if (csOperator == FX_BSTRC("Not")) {
     pOCGObj = pExpression->GetElementValue(1);
-    if (pOCGObj == NULL) {
+    if (!pOCGObj)
       return FALSE;
-    }
-    if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) {
+    if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary())
       return !(bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict));
-    }
-    if (pOCGObj->GetType() == PDFOBJ_ARRAY) {
-      return !GetOCGVE((CPDF_Array*)pOCGObj, bFromConfig, nLevel + 1);
-    }
+    if (CPDF_Array* pArray = pOCGObj->AsArray())
+      return !GetOCGVE(pArray, bFromConfig, nLevel + 1);
     return FALSE;
   }
   if (csOperator == FX_BSTRC("Or") || csOperator == FX_BSTRC("And")) {
@@ -225,11 +216,11 @@
         continue;
       }
       FX_BOOL bItem = FALSE;
-      if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) {
+      if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary())
         bItem = bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict);
-      } else if (pOCGObj->GetType() == PDFOBJ_ARRAY) {
-        bItem = GetOCGVE((CPDF_Array*)pOCGObj, bFromConfig, nLevel + 1);
-      }
+      else if (CPDF_Array* pArray = pOCGObj->AsArray())
+        bItem = GetOCGVE(pArray, bFromConfig, nLevel + 1);
+
       if (i == 1) {
         bValue = bItem;
       } else {
@@ -253,38 +244,32 @@
   }
   CFX_ByteString csP = pOCMDDict->GetString(FX_BSTRC("P"), FX_BSTRC("AnyOn"));
   CPDF_Object* pOCGObj = pOCMDDict->GetElementValue(FX_BSTRC("OCGs"));
-  if (pOCGObj == NULL) {
+  if (!pOCGObj)
     return TRUE;
-  }
-  if (const CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) {
+  if (const CPDF_Dictionary* pDict = pOCGObj->AsDictionary())
     return bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict);
-  }
-  if (pOCGObj->GetType() != PDFOBJ_ARRAY) {
+
+  CPDF_Array* pArray = pOCGObj->AsArray();
+  if (!pArray)
     return TRUE;
-  }
+
   FX_BOOL bState = FALSE;
   if (csP == FX_BSTRC("AllOn") || csP == FX_BSTRC("AllOff")) {
     bState = TRUE;
   }
-  int32_t iCount = ((CPDF_Array*)pOCGObj)->GetCount();
+  int32_t iCount = pArray->GetCount();
   for (int32_t i = 0; i < iCount; i++) {
     FX_BOOL bItem = TRUE;
-    CPDF_Dictionary* pItemDict = ((CPDF_Array*)pOCGObj)->GetDict(i);
-    if (pItemDict) {
+    CPDF_Dictionary* pItemDict = pArray->GetDict(i);
+    if (pItemDict)
       bItem = bFromConfig ? LoadOCGState(pItemDict) : GetOCGVisible(pItemDict);
-    }
-    if (csP == FX_BSTRC("AnyOn") && bItem) {
+
+    if ((csP == FX_BSTRC("AnyOn") && bItem) ||
+        (csP == FX_BSTRC("AnyOff") && !bItem))
       return TRUE;
-    }
-    if (csP == FX_BSTRC("AnyOff") && !bItem) {
-      return TRUE;
-    }
-    if (csP == FX_BSTRC("AllOn") && !bItem) {
+    if ((csP == FX_BSTRC("AllOn") && !bItem) ||
+        (csP == FX_BSTRC("AllOff") && bItem))
       return FALSE;
-    }
-    if (csP == FX_BSTRC("AllOff") && bItem) {
-      return FALSE;
-    }
   }
   return bState;
 }
diff --git a/core/src/fpdfdoc/doc_tagged.cpp b/core/src/fpdfdoc/doc_tagged.cpp
index ac29d90..2b20e07 100644
--- a/core/src/fpdfdoc/doc_tagged.cpp
+++ b/core/src/fpdfdoc/doc_tagged.cpp
@@ -46,48 +46,47 @@
     }
 }
 void CPDF_StructTreeImpl::LoadDocTree() {
-  m_pPage = NULL;
-  if (m_pTreeRoot == NULL) {
+  m_pPage = nullptr;
+  if (!m_pTreeRoot)
     return;
-  }
+
   CPDF_Object* pKids = m_pTreeRoot->GetElementValue(FX_BSTRC("K"));
-  if (pKids == NULL) {
+  if (!pKids)
     return;
-  }
   if (CPDF_Dictionary* pDict = pKids->AsDictionary()) {
     CPDF_StructElementImpl* pStructElementImpl =
-        new CPDF_StructElementImpl(this, NULL, pDict);
+        new CPDF_StructElementImpl(this, nullptr, pDict);
     m_Kids.Add(pStructElementImpl);
     return;
   }
-  if (pKids->GetType() != PDFOBJ_ARRAY) {
+  CPDF_Array* pArray = pKids->AsArray();
+  if (!pArray)
     return;
-  }
-  CPDF_Array* pArray = (CPDF_Array*)pKids;
+
   for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
     CPDF_Dictionary* pKid = pArray->GetDict(i);
     CPDF_StructElementImpl* pStructElementImpl =
-        new CPDF_StructElementImpl(this, NULL, pKid);
+        new CPDF_StructElementImpl(this, nullptr, pKid);
     m_Kids.Add(pStructElementImpl);
   }
 }
 void CPDF_StructTreeImpl::LoadPageTree(const CPDF_Dictionary* pPageDict) {
   m_pPage = pPageDict;
-  if (m_pTreeRoot == NULL) {
+  if (!m_pTreeRoot)
     return;
-  }
+
   CPDF_Object* pKids = m_pTreeRoot->GetElementValue(FX_BSTRC("K"));
-  if (pKids == NULL) {
+  if (!pKids)
     return;
-  }
+
   FX_DWORD dwKids = 0;
-  if (pKids->IsDictionary()) {
+  if (pKids->IsDictionary())
     dwKids = 1;
-  } else if (pKids->GetType() == PDFOBJ_ARRAY) {
-    dwKids = ((CPDF_Array*)pKids)->GetCount();
-  } else {
+  else if (CPDF_Array* pArray = pKids->AsArray())
+    dwKids = pArray->GetCount();
+  else
     return;
-  }
+
   FX_DWORD i;
   m_Kids.SetSize(dwKids);
   for (i = 0; i < dwKids; i++) {
@@ -101,11 +100,10 @@
   CPDF_NumberTree parent_tree(pParentTree);
   int parents_id = pPageDict->GetInteger(FX_BSTRC("StructParents"), -1);
   if (parents_id >= 0) {
-    CPDF_Object* pParents = parent_tree.LookupValue(parents_id);
-    if (pParents == NULL || pParents->GetType() != PDFOBJ_ARRAY) {
+    CPDF_Array* pParentArray = ToArray(parent_tree.LookupValue(parents_id));
+    if (!pParentArray)
       return;
-    }
-    CPDF_Array* pParentArray = (CPDF_Array*)pParents;
+
     for (i = 0; i < pParentArray->GetCount(); i++) {
       CPDF_Dictionary* pParent = pParentArray->GetDict(i);
       if (pParent == NULL) {
@@ -171,27 +169,23 @@
       return FALSE;
     }
   }
-  if (pObj->GetType() == PDFOBJ_ARRAY) {
-    CPDF_Array* pTopKids = (CPDF_Array*)pObj;
+  if (CPDF_Array* pTopKids = pObj->AsArray()) {
     FX_DWORD i;
     FX_BOOL bSave = FALSE;
     for (i = 0; i < pTopKids->GetCount(); i++) {
       CPDF_Object* pKidRef = pTopKids->GetElement(i);
-      if (pKidRef == NULL || pKidRef->GetType() != PDFOBJ_REFERENCE) {
+      if (!pKidRef || pKidRef->GetType() != PDFOBJ_REFERENCE)
         continue;
-      }
-      if (((CPDF_Reference*)pKidRef)->GetRefObjNum() != pDict->GetObjNum()) {
+      if (((CPDF_Reference*)pKidRef)->GetRefObjNum() != pDict->GetObjNum())
         continue;
-      }
-      if (m_Kids[i]) {
+
+      if (m_Kids[i])
         m_Kids[i]->Release();
-      }
       m_Kids[i] = pElement->Retain();
       bSave = TRUE;
     }
-    if (!bSave) {
+    if (!bSave)
       return FALSE;
-    }
   }
   return TRUE;
 }
@@ -231,15 +225,14 @@
 void CPDF_StructElementImpl::LoadKids(CPDF_Dictionary* pDict) {
   CPDF_Object* pObj = pDict->GetElement(FX_BSTRC("Pg"));
   FX_DWORD PageObjNum = 0;
-  if (pObj && pObj->GetType() == PDFOBJ_REFERENCE) {
+  if (pObj && pObj->GetType() == PDFOBJ_REFERENCE)
     PageObjNum = ((CPDF_Reference*)pObj)->GetRefObjNum();
-  }
+
   CPDF_Object* pKids = pDict->GetElementValue(FX_BSTRC("K"));
-  if (pKids == NULL) {
+  if (!pKids)
     return;
-  }
-  if (pKids->GetType() == PDFOBJ_ARRAY) {
-    CPDF_Array* pArray = (CPDF_Array*)pKids;
+
+  if (CPDF_Array* pArray = pKids->AsArray()) {
     m_Kids.SetSize(pArray->GetCount());
     for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
       CPDF_Object* pKid = pArray->GetElementValue(i);
@@ -316,25 +309,22 @@
 static CPDF_Dictionary* FindAttrDict(CPDF_Object* pAttrs,
                                      const CFX_ByteStringC& owner,
                                      FX_FLOAT nLevel = 0.0F) {
-  if (nLevel > nMaxRecursion) {
-    return NULL;
-  }
-  if (pAttrs == NULL) {
-    return NULL;
-  }
-  CPDF_Dictionary* pDict = NULL;
+  if (nLevel > nMaxRecursion)
+    return nullptr;
+  if (!pAttrs)
+    return nullptr;
+
+  CPDF_Dictionary* pDict = nullptr;
   if (pAttrs->IsDictionary()) {
     pDict = pAttrs->AsDictionary();
   } else if (pAttrs->GetType() == PDFOBJ_STREAM) {
     pDict = ((CPDF_Stream*)pAttrs)->GetDict();
-  } else if (pAttrs->GetType() == PDFOBJ_ARRAY) {
-    CPDF_Array* pArray = (CPDF_Array*)pAttrs;
+  } else if (CPDF_Array* pArray = pAttrs->AsArray()) {
     for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
       CPDF_Object* pElement = pArray->GetElementValue(i);
       pDict = FindAttrDict(pElement, owner, nLevel + 1);
-      if (pDict) {
+      if (pDict)
         return pDict;
-      }
     }
   }
   if (pDict && pDict->GetString(FX_BSTRC("O")) == owner) {
@@ -370,44 +360,40 @@
     }
   }
   CPDF_Object* pC = m_pDict->GetElementValue(FX_BSTRC("C"));
-  if (pC == NULL) {
-    return NULL;
-  }
+  if (!pC)
+    return nullptr;
+
   CPDF_Dictionary* pClassMap =
       m_pTree->m_pTreeRoot->GetDict(FX_BSTRC("ClassMap"));
-  if (pClassMap == NULL) {
-    return NULL;
-  }
-  if (pC->GetType() == PDFOBJ_ARRAY) {
-    CPDF_Array* pArray = (CPDF_Array*)pC;
+  if (!pClassMap)
+    return nullptr;
+
+  if (CPDF_Array* pArray = pC->AsArray()) {
     for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
       CFX_ByteString class_name = pArray->GetString(i);
       CPDF_Dictionary* pClassDict = pClassMap->GetDict(class_name);
-      if (pClassDict && pClassDict->GetString(FX_BSTRC("O")) == owner) {
+      if (pClassDict && pClassDict->GetString(FX_BSTRC("O")) == owner)
         return pClassDict->GetElementValue(name);
-      }
     }
-    return NULL;
+    return nullptr;
   }
   CFX_ByteString class_name = pC->GetString();
   CPDF_Dictionary* pClassDict = pClassMap->GetDict(class_name);
-  if (pClassDict && pClassDict->GetString(FX_BSTRC("O")) == owner) {
+  if (pClassDict && pClassDict->GetString(FX_BSTRC("O")) == owner)
     return pClassDict->GetElementValue(name);
-  }
-  return NULL;
+  return nullptr;
 }
 CPDF_Object* CPDF_StructElementImpl::GetAttr(const CFX_ByteStringC& owner,
                                              const CFX_ByteStringC& name,
                                              FX_BOOL bInheritable,
                                              int subindex) {
   CPDF_Object* pAttr = GetAttr(owner, name, bInheritable);
-  if (pAttr == NULL || subindex == -1 || pAttr->GetType() != PDFOBJ_ARRAY) {
+  CPDF_Array* pArray = ToArray(pAttr);
+  if (!pArray || subindex == -1)
     return pAttr;
-  }
-  CPDF_Array* pArray = (CPDF_Array*)pAttr;
-  if (subindex >= (int)pArray->GetCount()) {
+
+  if (subindex >= static_cast<int>(pArray->GetCount()))
     return pAttr;
-  }
   return pArray->GetElementValue(subindex);
 }
 CFX_ByteString CPDF_StructElementImpl::GetName(
@@ -427,11 +413,9 @@
                                          FX_ARGB default_value,
                                          FX_BOOL bInheritable,
                                          int subindex) {
-  CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex);
-  if (pAttr == NULL || pAttr->GetType() != PDFOBJ_ARRAY) {
+  CPDF_Array* pArray = ToArray(GetAttr(owner, name, bInheritable, subindex));
+  if (!pArray)
     return default_value;
-  }
-  CPDF_Array* pArray = (CPDF_Array*)pAttr;
   return 0xff000000 | ((int)(pArray->GetNumber(0) * 255) << 16) |
          ((int)(pArray->GetNumber(1) * 255) << 8) |
          (int)(pArray->GetNumber(2) * 255);
diff --git a/fpdfsdk/src/fpdf_flatten.cpp b/fpdfsdk/src/fpdf_flatten.cpp
index fee93f2..f4d49ce 100644
--- a/fpdfsdk/src/fpdf_flatten.cpp
+++ b/fpdfsdk/src/fpdf_flatten.cpp
@@ -226,7 +226,7 @@
     }
 
     case PDFOBJ_ARRAY: {
-      pContentsArray = (CPDF_Array*)pContentsObj;
+      pContentsArray = pContentsObj->AsArray();
       break;
     }
     default:
diff --git a/fpdfsdk/src/fpdf_transformpage.cpp b/fpdfsdk/src/fpdf_transformpage.cpp
index 1e24b68..d2ad26b 100644
--- a/fpdfsdk/src/fpdf_transformpage.cpp
+++ b/fpdfsdk/src/fpdf_transformpage.cpp
@@ -109,14 +109,15 @@
   textBuf << bsMatix;
 
   CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
-  CPDF_Object* pContentObj = pPageDic ? pPageDic->GetElement("Contents") : NULL;
+  CPDF_Object* pContentObj =
+      pPageDic ? pPageDic->GetElement("Contents") : nullptr;
   if (!pContentObj)
-    pContentObj = pPageDic ? pPageDic->GetArray("Contents") : NULL;
+    pContentObj = pPageDic ? pPageDic->GetArray("Contents") : nullptr;
   if (!pContentObj)
     return FALSE;
 
   CPDF_Dictionary* pDic = new CPDF_Dictionary;
-  CPDF_Stream* pStream = new CPDF_Stream(NULL, 0, pDic);
+  CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic);
   pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
   CPDF_Document* pDoc = pPage->m_pDocument;
   if (!pDoc)
@@ -124,22 +125,22 @@
   pDoc->AddIndirectObject(pStream);
 
   pDic = new CPDF_Dictionary;
-  CPDF_Stream* pEndStream = new CPDF_Stream(NULL, 0, pDic);
+  CPDF_Stream* pEndStream = new CPDF_Stream(nullptr, 0, pDic);
   pEndStream->SetData((const uint8_t*)" Q", 2, FALSE, FALSE);
   pDoc->AddIndirectObject(pEndStream);
 
-  CPDF_Array* pContentArray = NULL;
-  if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY) {
-    pContentArray = (CPDF_Array*)pContentObj;
+  CPDF_Array* pContentArray = nullptr;
+  if (CPDF_Array* pArray = ToArray(pContentObj)) {
+    pContentArray = pArray;
     CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
     pContentArray->InsertAt(0, pRef);
     pContentArray->AddReference(pDoc, pEndStream);
   } else if (pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE) {
     CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
     CPDF_Object* pDirectObj = pReference->GetDirect();
-    if (pDirectObj != NULL) {
-      if (pDirectObj->GetType() == PDFOBJ_ARRAY) {
-        pContentArray = (CPDF_Array*)pDirectObj;
+    if (pDirectObj) {
+      if (CPDF_Array* pArray = pDirectObj->AsArray()) {
+        pContentArray = pArray;
         CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
         pContentArray->InsertAt(0, pRef);
         pContentArray->AddReference(pDoc, pEndStream);
@@ -267,9 +268,10 @@
     return;
 
   CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
-  CPDF_Object* pContentObj = pPageDic ? pPageDic->GetElement("Contents") : NULL;
+  CPDF_Object* pContentObj =
+      pPageDic ? pPageDic->GetElement("Contents") : nullptr;
   if (!pContentObj)
-    pContentObj = pPageDic ? pPageDic->GetArray("Contents") : NULL;
+    pContentObj = pPageDic ? pPageDic->GetArray("Contents") : nullptr;
   if (!pContentObj)
     return;
 
@@ -291,24 +293,24 @@
     }
   }
   CPDF_Dictionary* pDic = new CPDF_Dictionary;
-  CPDF_Stream* pStream = new CPDF_Stream(NULL, 0, pDic);
+  CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic);
   pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
   CPDF_Document* pDoc = pPage->m_pDocument;
   if (!pDoc)
     return;
   pDoc->AddIndirectObject(pStream);
 
-  CPDF_Array* pContentArray = NULL;
-  if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY) {
-    pContentArray = (CPDF_Array*)pContentObj;
+  CPDF_Array* pContentArray = nullptr;
+  if (CPDF_Array* pArray = ToArray(pContentObj)) {
+    pContentArray = pArray;
     CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
     pContentArray->InsertAt(0, pRef);
   } else if (pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE) {
     CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
     CPDF_Object* pDirectObj = pReference->GetDirect();
-    if (pDirectObj != NULL) {
-      if (pDirectObj->GetType() == PDFOBJ_ARRAY) {
-        pContentArray = (CPDF_Array*)pDirectObj;
+    if (pDirectObj) {
+      if (CPDF_Array* pArray = pDirectObj->AsArray()) {
+        pContentArray = pArray;
         CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
         pContentArray->InsertAt(0, pRef);
       } else if (pDirectObj->GetType() == PDFOBJ_STREAM) {
diff --git a/fpdfsdk/src/fpdfdoc.cpp b/fpdfsdk/src/fpdfdoc.cpp
index ad8ef8b..8a4d619 100644
--- a/fpdfsdk/src/fpdfdoc.cpp
+++ b/fpdfsdk/src/fpdfdoc.cpp
@@ -197,7 +197,7 @@
   CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
   if (!pDoc)
     return 0;
-  CPDF_Dest dest((CPDF_Array*)pDict);
+  CPDF_Dest dest(static_cast<CPDF_Array*>(pDict));
   return dest.GetPageIndex(pDoc);
 }
 
diff --git a/fpdfsdk/src/fpdfppo.cpp b/fpdfsdk/src/fpdfppo.cpp
index c37ecca..b071630 100644
--- a/fpdfsdk/src/fpdfppo.cpp
+++ b/fpdfsdk/src/fpdfppo.cpp
@@ -242,7 +242,7 @@
       break;
     }
     case PDFOBJ_ARRAY: {
-      CPDF_Array* pArray = (CPDF_Array*)pObj;
+      CPDF_Array* pArray = pObj->AsArray();
       FX_DWORD count = pArray->GetCount();
       for (FX_DWORD i = 0; i < count; i++) {
         CPDF_Object* pNextObj = pArray->GetElement(i);
diff --git a/fpdfsdk/src/fpdfview.cpp b/fpdfsdk/src/fpdfview.cpp
index bd7741d..b3c8137 100644
--- a/fpdfsdk/src/fpdfview.cpp
+++ b/fpdfsdk/src/fpdfview.cpp
@@ -1041,14 +1041,15 @@
     pDestObj = nameTree.LookupValue(index, bsName);
   }
   if (!pDestObj)
-    return NULL;
+    return nullptr;
   if (CPDF_Dictionary* pDict = pDestObj->AsDictionary()) {
     pDestObj = pDict->GetArray(FX_BSTRC("D"));
     if (!pDestObj)
-      return NULL;
+      return nullptr;
   }
-  if (pDestObj->GetType() != PDFOBJ_ARRAY)
-    return NULL;
+  if (!pDestObj->IsArray())
+    return nullptr;
+
   CFX_WideString wsName = PDF_DecodeText(bsName);
   CFX_ByteString utf16Name = wsName.UTF16LE_Encode();
   unsigned int len = utf16Name.GetLength();
diff --git a/fpdfsdk/src/fsdk_actionhandler.cpp b/fpdfsdk/src/fsdk_actionhandler.cpp
index feb9a85..9d510b7 100644
--- a/fpdfsdk/src/fsdk_actionhandler.cpp
+++ b/fpdfsdk/src/fsdk_actionhandler.cpp
@@ -426,7 +426,7 @@
 }
 
 FX_BOOL CPDFSDK_ActionHandler::IsValidDocView(CPDFSDK_Document* pDocument) {
-  ASSERT(pDocument != NULL);
+  ASSERT(pDocument);
   return TRUE;
 }
 
@@ -435,17 +435,15 @@
   ASSERT(action);
 
   CPDF_Document* pPDFDocument = pDocument->GetDocument()->GetPDFDoc();
-  ASSERT(pPDFDocument != NULL);
-  CPDFDoc_Environment* pApp = pDocument->GetEnv();
-  ASSERT(pApp != NULL);
+  ASSERT(pPDFDocument);
 
   CPDF_Dest MyDest = action.GetDest(pPDFDocument);
   int nPageIndex = MyDest.GetPageIndex(pPDFDocument);
   int nFitType = MyDest.GetZoomMode();
-  const CPDF_Array* pMyArray = (CPDF_Array*)MyDest.GetObject();
-  float* pPosAry = NULL;
+  const CPDF_Array* pMyArray = ToArray(MyDest.GetObject());
+  float* pPosAry = nullptr;
   int sizeOfAry = 0;
-  if (pMyArray != NULL) {
+  if (pMyArray) {
     pPosAry = new float[pMyArray->GetCount()];
     int j = 0;
     for (int i = 2; i < (int)pMyArray->GetCount(); i++) {
@@ -453,6 +451,8 @@
     }
     sizeOfAry = j;
   }
+
+  CPDFDoc_Environment* pApp = pDocument->GetEnv();
   pApp->FFI_DoGoToAction(nPageIndex, nFitType, pPosAry, sizeOfAry);
   delete[] pPosAry;
 }
diff --git a/fpdfsdk/src/fsdk_mgr.cpp b/fpdfsdk/src/fsdk_mgr.cpp
index b7de36c..a698453 100644
--- a/fpdfsdk/src/fsdk_mgr.cpp
+++ b/fpdfsdk/src/fsdk_mgr.cpp
@@ -484,7 +484,7 @@
   if (!pOpenAction)
     return FALSE;
 
-  if (pOpenAction->GetType() == PDFOBJ_ARRAY)
+  if (pOpenAction->IsArray())
     return TRUE;
 
   if (CPDF_Dictionary* pDict = pOpenAction->AsDictionary()) {