Rework JSE_PROP() macro to avoid illegal cast in xfa_basic_data.cpp.

Casting one function type to another is theoretically wrong. This also
facilitates adding run-time type checking in property accessor
invocations down the road.

Fix one bad argument type (unused) uncovered as a result.
Use JSE_PROP() macro in more places to instantiate static
helper methods as needed.

Change-Id: Id78a051d236c8c6c060fb45b6101def621d35a81
Reviewed-on: https://pdfium-review.googlesource.com/c/48611
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index d2c3421..ba62b85 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -167,8 +167,8 @@
   if (resolveRs.dwFlags == XFA_ResolveNode_RSType_Attribute &&
       resolveRs.script_attribute.callback) {
     CJX_Object* jsObject = resolveRs.objects.front()->JSObject();
-    (jsObject->*(resolveRs.script_attribute.callback))(
-        pValue, bSetting, resolveRs.script_attribute.attribute);
+    (*resolveRs.script_attribute.callback)(
+        jsObject, pValue, bSetting, resolveRs.script_attribute.attribute);
   }
   return true;
 }
@@ -333,8 +333,8 @@
           pObject->GetElementType(), wsPropName.AsStringView());
       if (info.has_value()) {
         CJX_Object* jsObject = pObject->JSObject();
-        (jsObject->*(info.value().callback))(pReturnValue, false,
-                                             info.value().attribute);
+        (*info.value().callback)(jsObject, pReturnValue, false,
+                                 info.value().attribute);
         return;
       }
     }
@@ -373,8 +373,8 @@
       XFA_GetScriptAttributeByName(pObject->GetElementType(), wsPropNameView);
   if (info.has_value()) {
     CJX_Object* jsObject = pObject->JSObject();
-    (jsObject->*(info.value().callback))(pReturnValue, true,
-                                         info.value().attribute);
+    (*info.value().callback)(jsObject, pReturnValue, true,
+                             info.value().attribute);
     return;
   }
 
@@ -657,8 +657,8 @@
               pdfium::base::checked_cast<int32_t>(wsExpression.GetLength())) {
         auto pValue = pdfium::MakeUnique<CFXJSE_Value>(GetIsolate());
         CJX_Object* jsObject = rndFind.m_Objects.front()->JSObject();
-        (jsObject->*(rndFind.m_ScriptAttribute.callback))(
-            pValue.get(), false, rndFind.m_ScriptAttribute.attribute);
+        (*rndFind.m_ScriptAttribute.callback)(
+            jsObject, pValue.get(), false, rndFind.m_ScriptAttribute.attribute);
         rndFind.m_Objects.front() = ToObject(pValue.get());
       }
       if (!m_upObjectArray.empty())
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index 4b8a73f..ae4d096 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -5762,9 +5762,9 @@
     for (auto& pObject : resolveNodeRS.objects) {
       auto pValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
       CJX_Object* jsObject = pObject->JSObject();
-      (jsObject->*(resolveNodeRS.script_attribute.callback))(
-          pValue.get(), false, resolveNodeRS.script_attribute.attribute);
-
+      (*resolveNodeRS.script_attribute.callback)(
+          jsObject, pValue.get(), false,
+          resolveNodeRS.script_attribute.attribute);
       resultValues->push_back(std::move(pValue));
       *bAttribute = false;
     }
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index 9bf80eb..9feab1b 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -1569,7 +1569,7 @@
 
 void CJX_Object::ScriptSubformInstanceManager(CFXJSE_Value* pValue,
                                               bool bSetting,
-                                              XFA_AttributeValue eAttribute) {
+                                              XFA_Attribute eAttribute) {
   if (bSetting) {
     ThrowInvalidPropertyException();
     return;
diff --git a/fxjs/xfa/cjx_object.h b/fxjs/xfa/cjx_object.h
index cdb6907..1b7e6dc 100644
--- a/fxjs/xfa/cjx_object.h
+++ b/fxjs/xfa/cjx_object.h
@@ -110,67 +110,31 @@
                          bool bNotify,
                          bool bScriptModify);
 
-  void ScriptAttributeString(CFXJSE_Value* pValue,
-                             bool bSetting,
-                             XFA_Attribute eAttribute);
-  void ScriptAttributeBool(CFXJSE_Value* pValue,
-                           bool bSetting,
-                           XFA_Attribute eAttribute);
-  void ScriptAttributeInteger(CFXJSE_Value* pValue,
-                              bool bSetting,
-                              XFA_Attribute eAttribute);
+  // Not actual properties, but invoked as property handlers to cover
+  // a broad range of underlying properties.
+  JSE_PROP(ScriptAttributeString);
+  JSE_PROP(ScriptAttributeBool);
+  JSE_PROP(ScriptAttributeInteger);
+  JSE_PROP(ScriptSomFontColor);
+  JSE_PROP(ScriptSomFillColor);
+  JSE_PROP(ScriptSomBorderColor);
+  JSE_PROP(ScriptSomBorderWidth);
+  JSE_PROP(ScriptSomValidationMessage);
+  JSE_PROP(ScriptSomMandatoryMessage);
+  JSE_PROP(ScriptFieldLength);
+  JSE_PROP(ScriptSomDefaultValue);
+  JSE_PROP(ScriptSomDefaultValue_Read);
+  JSE_PROP(ScriptSomDataNode);
+  JSE_PROP(ScriptSomMandatory);
+  JSE_PROP(ScriptSomInstanceIndex);
+  JSE_PROP(ScriptSubformInstanceManager);
+  JSE_PROP(ScriptSubmitFormatMode);
+  JSE_PROP(ScriptFormChecksumS);
+  JSE_PROP(ScriptExclGroupErrorText);
 
-  void ScriptSomFontColor(CFXJSE_Value* pValue,
-                          bool bSetting,
-                          XFA_Attribute eAttribute);
-  void ScriptSomFillColor(CFXJSE_Value* pValue,
-                          bool bSetting,
-                          XFA_Attribute eAttribute);
-  void ScriptSomBorderColor(CFXJSE_Value* pValue,
-                            bool bSetting,
-                            XFA_Attribute eAttribute);
-  void ScriptSomBorderWidth(CFXJSE_Value* pValue,
-                            bool bSetting,
-                            XFA_Attribute eAttribute);
-  void ScriptSomValidationMessage(CFXJSE_Value* pValue,
-                                  bool bSetting,
-                                  XFA_Attribute eAttribute);
-  void ScriptSomMandatoryMessage(CFXJSE_Value* pValue,
-                                 bool bSetting,
-                                 XFA_Attribute eAttribute);
-  void ScriptFieldLength(CFXJSE_Value* pValue,
-                         bool bSetting,
-                         XFA_Attribute eAttribute);
-  void ScriptSomDefaultValue(CFXJSE_Value* pValue,
-                             bool bSetting,
-                             XFA_Attribute eAttribute);
-  void ScriptSomDefaultValue_Read(CFXJSE_Value* pValue,
-                                  bool bSetting,
-                                  XFA_Attribute eAttribute);
-  void ScriptSomDataNode(CFXJSE_Value* pValue,
-                         bool bSetting,
-                         XFA_Attribute eAttribute);
-  void ScriptSomMandatory(CFXJSE_Value* pValue,
-                          bool bSetting,
-                          XFA_Attribute eAttribute);
-  void ScriptSomInstanceIndex(CFXJSE_Value* pValue,
-                              bool bSetting,
-                              XFA_Attribute eAttribute);
   void ScriptSomMessage(CFXJSE_Value* pValue,
                         bool bSetting,
                         XFA_SOM_MESSAGETYPE iMessageType);
-  void ScriptSubformInstanceManager(CFXJSE_Value* pValue,
-                                    bool bSetting,
-                                    XFA_AttributeValue eAttribute);
-  void ScriptSubmitFormatMode(CFXJSE_Value* pValue,
-                              bool bSetting,
-                              XFA_Attribute eAttribute);
-  void ScriptFormChecksumS(CFXJSE_Value* pValue,
-                           bool bSetting,
-                           XFA_Attribute eAttribute);
-  void ScriptExclGroupErrorText(CFXJSE_Value* pValue,
-                                bool bSetting,
-                                XFA_Attribute eAttribute);
 
   Optional<WideString> TryNamespace();
 
@@ -268,8 +232,9 @@
   size_t calc_recursion_count_ = 0;
 };
 
-typedef void (CJX_Object::*XFA_ATTRIBUTE_CALLBACK)(CFXJSE_Value* pValue,
-                                                   bool bSetting,
-                                                   XFA_Attribute eAttribute);
+typedef void (*XFA_ATTRIBUTE_CALLBACK)(CJX_Object* pNode,
+                                       CFXJSE_Value* pValue,
+                                       bool bSetting,
+                                       XFA_Attribute eAttribute);
 
 #endif  // FXJS_XFA_CJX_OBJECT_H_
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp
index f86f90d..0eb8874 100644
--- a/fxjs/xfa/cjx_tree.cpp
+++ b/fxjs/xfa/cjx_tree.cpp
@@ -72,8 +72,8 @@
 
   auto pValue = pdfium::MakeUnique<CFXJSE_Value>(pScriptContext->GetIsolate());
   CJX_Object* jsObject = resolveNodeRS.objects.front()->JSObject();
-  (jsObject->*(resolveNodeRS.script_attribute.callback))(
-      pValue.get(), false, resolveNodeRS.script_attribute.attribute);
+  (*resolveNodeRS.script_attribute.callback)(
+      jsObject, pValue.get(), false, resolveNodeRS.script_attribute.attribute);
   return CJS_Result::Success(
       pValue->DirectGetValue().Get(runtime->GetIsolate()));
 }
@@ -235,9 +235,9 @@
         auto innerValue =
             pdfium::MakeUnique<CFXJSE_Value>(pScriptContext->GetIsolate());
         CJX_Object* jsObject = pObject->JSObject();
-        (jsObject->*(resolveNodeRS.script_attribute.callback))(
-            innerValue.get(), false, resolveNodeRS.script_attribute.attribute);
-
+        (*resolveNodeRS.script_attribute.callback)(
+            jsObject, innerValue.get(), false,
+            resolveNodeRS.script_attribute.attribute);
         CXFA_Object* obj = CFXJSE_Engine::ToObject(innerValue.get());
         if (obj->IsNode())
           pNodeList->Append(obj->AsNode());
diff --git a/fxjs/xfa/jse_define.h b/fxjs/xfa/jse_define.h
index b4056e9..6d35df8 100644
--- a/fxjs/xfa/jse_define.h
+++ b/fxjs/xfa/jse_define.h
@@ -22,7 +22,11 @@
   CJS_Result method_name(CFX_V8* runtime,                            \
                          const std::vector<v8::Local<v8::Value>>& params)
 
-#define JSE_PROP(prop_name) \
+#define JSE_PROP(prop_name)                                               \
+  static void prop_name##_static(CJX_Object* node, CFXJSE_Value* value,   \
+                                 bool setting, XFA_Attribute attribute) { \
+    static_cast<Type__*>(node)->prop_name(value, setting, attribute);     \
+  }                                                                       \
   void prop_name(CFXJSE_Value* pValue, bool bSetting, XFA_Attribute eAttribute)
 
 #endif  // FXJS_XFA_JSE_DEFINE_H_
diff --git a/xfa/fxfa/parser/xfa_basic_data.cpp b/xfa/fxfa/parser/xfa_basic_data.cpp
index e673cde..950d6b9 100644
--- a/xfa/fxfa/parser/xfa_basic_data.cpp
+++ b/xfa/fxfa/parser/xfa_basic_data.cpp
@@ -219,9 +219,7 @@
 
 const ElementAttributeRecord g_ElementAttributeTable[] = {
 #undef ELEM_ATTR____
-#define ELEM_ATTR____(a, b, c)       \
-  {XFA_Element::a, XFA_Attribute::b, \
-   reinterpret_cast<XFA_ATTRIBUTE_CALLBACK>(c)},
+#define ELEM_ATTR____(a, b, c) {XFA_Element::a, XFA_Attribute::b, c##_static},
 #include "xfa/fxfa/parser/element_attributes.inc"
 #undef ELEM_ATTR____
 };