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