Tag CFXJSE_HostObject sub-classes.

CXFA_FM2JSContext and CXFA_Object both subclass CFXJSE_HostObject.
When a CFXJSE_HostObject is obtained from an opaque pointer inside
a V8 object internal slot, there is no way to distinguish one from
the other.

Bug: 728158
Change-Id: Iabc648e8b7226e2819d8795227442c3f6c61a793
Reviewed-on: https://pdfium-review.googlesource.com/6211
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/fxjse.h b/fxjs/fxjse.h
index a29c089..8fc514b 100644
--- a/fxjs/fxjse.h
+++ b/fxjs/fxjse.h
@@ -14,10 +14,20 @@
 class CFXJSE_Arguments;
 class CFXJSE_Value;
 
-// C++ object which can be wrapped by CFXJSE_value.
+// C++ object which is retrieved from v8 object's slot.
 class CFXJSE_HostObject {
  public:
   virtual ~CFXJSE_HostObject() {}
+
+  // Small layering violation here, but we need to distinguish between the
+  // two kinds of subclasses.
+  enum Type { kXFA, kFM2JS };
+  Type type() const { return type_; }
+
+ protected:
+  explicit CFXJSE_HostObject(Type type) { type_ = type; }
+
+  Type type_;
 };
 
 typedef void (*FXJSE_FuncCallback)(CFXJSE_Value* pThis,
diff --git a/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp b/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp
index c6d5369..2da86eb 100644
--- a/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fm2jscontext.cpp
@@ -501,7 +501,10 @@
 }
 
 CXFA_FM2JSContext* ToJSContext(CFXJSE_Value* pValue, CFXJSE_Class* pClass) {
-  return static_cast<CXFA_FM2JSContext*>(pValue->ToHostObject(pClass));
+  CFXJSE_HostObject* pHostObj = pValue->ToHostObject(pClass);
+  if (!pHostObj || pHostObj->type() != CFXJSE_HostObject::kFM2JS)
+    return nullptr;
+  return static_cast<CXFA_FM2JSContext*>(pHostObj);
 }
 
 bool IsWhitespace(char c) {
@@ -6133,13 +6136,13 @@
 CXFA_FM2JSContext::CXFA_FM2JSContext(v8::Isolate* pScriptIsolate,
                                      CFXJSE_Context* pScriptContext,
                                      CXFA_Document* pDoc)
-    : m_pIsolate(pScriptIsolate),
+    : CFXJSE_HostObject(kFM2JS),
+      m_pIsolate(pScriptIsolate),
       m_pFMClass(CFXJSE_Class::Create(pScriptContext,
                                       &formcalc_fm2js_descriptor,
                                       false)),
       m_pValue(pdfium::MakeUnique<CFXJSE_Value>(pScriptIsolate)),
       m_pDocument(pDoc) {
-  m_pValue.get()->SetNull();
   m_pValue.get()->SetObject(this, m_pFMClass);
 }
 
diff --git a/xfa/fxfa/parser/cxfa_object.cpp b/xfa/fxfa/parser/cxfa_object.cpp
index 8dd35cd..32aed5d 100644
--- a/xfa/fxfa/parser/cxfa_object.cpp
+++ b/xfa/fxfa/parser/cxfa_object.cpp
@@ -17,7 +17,8 @@
                          XFA_ObjectType objectType,
                          XFA_Element elementType,
                          const CFX_WideStringC& elementName)
-    : m_pDocument(pDocument),
+    : CFXJSE_HostObject(kXFA),
+      m_pDocument(pDocument),
       m_objectType(objectType),
       m_elementType(elementType),
       m_elementNameHash(FX_HashCode_GetW(elementName, false)),
diff --git a/xfa/fxfa/parser/cxfa_scriptcontext.cpp b/xfa/fxfa/parser/cxfa_scriptcontext.cpp
index 2100299..fcf2244 100644
--- a/xfa/fxfa/parser/cxfa_scriptcontext.cpp
+++ b/xfa/fxfa/parser/cxfa_scriptcontext.cpp
@@ -115,7 +115,10 @@
 // static.
 CXFA_Object* CXFA_ScriptContext::ToObject(CFXJSE_Value* pValue,
                                           CFXJSE_Class* pClass) {
-  return static_cast<CXFA_Object*>(pValue->ToHostObject(pClass));
+  CFXJSE_HostObject* pHostObj = pValue->ToHostObject(pClass);
+  if (!pHostObj || pHostObj->type() != CFXJSE_HostObject::kXFA)
+    return nullptr;
+  return static_cast<CXFA_Object*>(pHostObj);
 }
 
 CXFA_ScriptContext::CXFA_ScriptContext(CXFA_Document* pDocument)