Fix faulty indexing CFXJSE_FormCalcContext::unfoldArgs().

Length properties may dynamically change from call to call, so
a pre-allocation may not be sufficient.

Bug: chromium:1004106
Change-Id: Ica860e7d585a8d10346ea407f8a8e3cfc1bd4a1b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/67171
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index 7a6796c..ea0c5ae 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -3103,9 +3103,7 @@
 
   bool bFlags = false;
   std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
-  std::vector<std::unique_ptr<CFXJSE_Value>> parameterValues =
-      unfoldArgs(pThis, args);
-  for (const auto& value : parameterValues) {
+  for (const auto& value : unfoldArgs(pThis, args)) {
     if (simpleValueCompare(pThis, argOne.get(), value.get())) {
       bFlags = true;
       break;
@@ -5309,59 +5307,36 @@
     CFXJSE_Value* pThis,
     CFXJSE_Arguments& args) {
   std::vector<std::unique_ptr<CFXJSE_Value>> results;
-
-  int32_t iCount = 0;
   v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
-  int32_t argc = args.GetLength();
-  std::vector<std::unique_ptr<CFXJSE_Value>> argsValue;
-  static constexpr int kStart = 1;
-  for (int32_t i = 0; i < argc - kStart; i++) {
-    argsValue.push_back(args.GetValue(i + kStart));
-    if (argsValue[i]->IsArray()) {
+  for (int32_t i = 1; i < args.GetLength(); ++i) {
+    std::unique_ptr<CFXJSE_Value> arg = args.GetValue(i);
+    if (arg->IsArray()) {
       auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
-      argsValue[i]->GetObjectProperty("length", lengthValue.get());
-      int32_t iLength = lengthValue->ToInteger();
-      iCount += ((iLength > 2) ? (iLength - 2) : 0);
-    } else {
-      ++iCount;
-    }
-  }
-
-  for (int32_t i = 0; i < iCount; i++)
-    results.push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
-
-  int32_t index = 0;
-  for (int32_t i = 0; i < argc - kStart; i++) {
-    if (argsValue[i]->IsArray()) {
-      auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
-      argsValue[i]->GetObjectProperty("length", lengthValue.get());
+      arg->GetObjectProperty("length", lengthValue.get());
       int32_t iLength = lengthValue->ToInteger();
       if (iLength < 3)
         continue;
 
       auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
-      auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
-      argsValue[i]->GetObjectPropertyByIdx(1, propertyValue.get());
-      if (propertyValue->IsNull()) {
-        for (int32_t j = 2; j < iLength; j++) {
-          argsValue[i]->GetObjectPropertyByIdx(j, jsObjectValue.get());
-          GetObjectDefaultValue(jsObjectValue.get(), results[index].get());
-          index++;
-        }
-      } else {
-        for (int32_t j = 2; j < iLength; j++) {
-          argsValue[i]->GetObjectPropertyByIdx(j, jsObjectValue.get());
+      arg->GetObjectPropertyByIdx(1, propertyValue.get());
+
+      for (int32_t j = 2; j < iLength; j++) {
+        auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
+        arg->GetObjectPropertyByIdx(j, jsObjectValue.get());
+        results.push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
+        if (propertyValue->IsNull()) {
+          GetObjectDefaultValue(jsObjectValue.get(), results.back().get());
+        } else {
           jsObjectValue->GetObjectProperty(
-              propertyValue->ToString().AsStringView(), results[index].get());
-          index++;
+              propertyValue->ToString().AsStringView(), results.back().get());
         }
       }
-    } else if (argsValue[i]->IsObject()) {
-      GetObjectDefaultValue(argsValue[i].get(), results[index].get());
-      index++;
+    } else if (arg->IsObject()) {
+      results.push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
+      GetObjectDefaultValue(arg.get(), results.back().get());
     } else {
-      results[index]->Assign(argsValue[i].get());
-      index++;
+      results.push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
+      results.back()->Assign(arg.get());
     }
   }
   return results;
diff --git a/testing/resources/javascript/xfa_specific/bug_1004106.in b/testing/resources/javascript/xfa_specific/bug_1004106.in
new file mode 100644
index 0000000..926c39b
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1004106.in
@@ -0,0 +1,65 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+  {{streamlen}}
+>>
+stream
+<template>
+  <subform layout="tb" name="subform1">
+    <pageSet id="page" relation="orderedOccurrence">
+      <occur initial="1" max="1" min="1"/>
+      <pageArea id="Page1" name="Page1">
+        <occur max="1" min="1"/>
+        <contentArea h="100mm" w="200mm" x="0.25in" y="0.25in"/>
+        <medium long="297mm" short="210mm" stock="a4"/>
+      </pageArea>
+    </pageSet>
+    <subform layout="tb" name="subform2">
+      <variables name="vara">
+      </variables>
+      <occur initial="1" max="10" min="0" name="occur1">
+      </occur>
+      <field h="10mm" name="field1" w="40mm" x="10mm" y="10mm">
+        <event activity="ready" ref="$form">
+          <script contentType="application/x-javascript">
+            var ref = [];
+
+            app.test = function () {
+              var arr = []
+              var v1 = 1;
+              st = {};
+              var v2 = [0, st, 2, 3];
+              var v3 = [0, "poc", {}];
+              st.toString = function(){
+                for (var i = 0; i != 8; i++) v3.push({});
+                return "poc";
+              }
+
+              // Trigger
+              pfm_rt.Oneof(1, v1, v2, v3);
+            }
+          </script>
+        </event>
+      </field>
+      <field h="10mm" name="field2" w="40mm" x="10mm" y="10mm">
+        <event activity="ready" ref="$form">
+          <script contentType="application/x-formcalc">
+            app.test();
+          </script>
+        </event>
+      </field>
+    </subform>
+  </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF