Update pdfium to Chrome 114.0.5735.130 pdfium
pdfium last commit id: 9505810f6
Bug: 279055389
Test: Build the code and flash the device and check Print functionality
Test: atest FrameworksCoreTests
Test: atest CtsPrintTestCases
Test: atest CtsPdfTestCases
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3e2fb7d98efb4ba7b51fd84e9a0ae04f8c0f7805)
Merged-In: I2efabeec0d0fa3925bcbeebf36031cee6f7f9fc4
Change-Id: I2efabeec0d0fa3925bcbeebf36031cee6f7f9fc4
diff --git a/fxjs/Android.bp b/fxjs/Android.bp
index 9616816..13d7b15 100644
--- a/fxjs/Android.bp
+++ b/fxjs/Android.bp
@@ -4,11 +4,8 @@
visibility: ["//external/pdfium:__subpackages__"],
- header_libs: [
- "libpdfium-constants",
- ],
-
static_libs: [
+ "libpdfium-constants",
"libpdfium-fdrm",
"libpdfium-page",
"libpdfium-parser",
diff --git a/fxjs/BUILD.gn b/fxjs/BUILD.gn
index 2fb819c..e3f62ff 100644
--- a/fxjs/BUILD.gn
+++ b/fxjs/BUILD.gn
@@ -1,4 +1,4 @@
-# Copyright 2018 The PDFium Authors. All rights reserved.
+# Copyright 2018 The PDFium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -15,8 +15,9 @@
"ijs_runtime.cpp",
"ijs_runtime.h",
]
- configs += [ "../:pdfium_core_config" ]
+ configs += [ "../:pdfium_strict_config" ]
deps = [ "../core/fxcrt" ]
+ public_deps = []
visibility = [ "../*" ]
if (pdf_enable_v8) {
@@ -27,6 +28,8 @@
"cfx_keyvalue.h",
"cfx_v8.cpp",
"cfx_v8.h",
+ "cfx_v8_array_buffer_allocator.cpp",
+ "cfx_v8_array_buffer_allocator.h",
"cfxjs_engine.cpp",
"cfxjs_engine.h",
"cjs_annot.cpp",
@@ -49,8 +52,6 @@
"cjs_event.h",
"cjs_event_context.cpp",
"cjs_event_context.h",
- "cjs_eventrecorder.cpp",
- "cjs_eventrecorder.h",
"cjs_field.cpp",
"cjs_field.h",
"cjs_font.cpp",
@@ -89,6 +90,8 @@
"cjs_zoomtype.h",
"fx_date_helpers.cpp",
"fx_date_helpers.h",
+ "fxv8.cpp",
+ "fxv8.h",
"global_timer.cpp",
"global_timer.h",
"js_define.cpp",
@@ -108,12 +111,13 @@
"//v8:v8_libplatform",
]
configs += [ "//v8:external_startup_data" ]
- public_deps = [ "//v8" ]
+ public_deps += [
+ "../core/fxcrt",
+ "//v8",
+ ]
if (pdf_enable_xfa) {
sources += [
- "xfa/cfxjse_arguments.cpp",
- "xfa/cfxjse_arguments.h",
"xfa/cfxjse_class.cpp",
"xfa/cfxjse_class.h",
"xfa/cfxjse_context.cpp",
@@ -124,6 +128,10 @@
"xfa/cfxjse_formcalc_context.h",
"xfa/cfxjse_isolatetracker.cpp",
"xfa/cfxjse_isolatetracker.h",
+ "xfa/cfxjse_mapmodule.cpp",
+ "xfa/cfxjse_mapmodule.h",
+ "xfa/cfxjse_nodehelper.cpp",
+ "xfa/cfxjse_nodehelper.h",
"xfa/cfxjse_resolveprocessor.cpp",
"xfa/cfxjse_resolveprocessor.h",
"xfa/cfxjse_runtimedata.cpp",
@@ -203,27 +211,65 @@
"xfa/jse_define.h",
]
deps += [
- "../xfa/fgas",
- "../xfa/fxfa/fm2js",
+ ":gc",
+ "../xfa/fgas/crt",
+ "../xfa/fxfa/formcalc",
]
}
}
}
if (pdf_enable_v8) {
+ if (pdf_enable_xfa) {
+ source_set("gc") {
+ sources = [
+ "gc/container_trace.h",
+ "gc/gced_tree_node.h",
+ "gc/gced_tree_node_mixin.h",
+ "gc/heap.cpp",
+ "gc/heap.h",
+ ]
+ configs += [ "../:pdfium_strict_config" ]
+ deps = [
+ "../core/fxcrt",
+ "//v8:v8_libplatform",
+ ]
+ public_deps = [ "//v8:cppgc" ]
+ }
+ }
+}
+
+if (pdf_enable_v8) {
pdfium_unittest_source_set("unittests") {
sources = [
"cfx_globaldata_unittest.cpp",
"cfx_v8_unittest.cpp",
- "cfx_v8_unittest.h",
"cfxjs_engine_unittest.cpp",
"cjs_publicmethods_unittest.cpp",
"cjs_util_unittest.cpp",
"fx_date_helpers_unittest.cpp",
]
configs = [ "//v8:external_startup_data" ]
- deps = [ ":fxjs" ]
+ deps = [
+ ":fxjs",
+ "../core/fxcrt:unit_test_support",
+ ]
pdfium_root_dir = "../"
+ if (pdf_enable_xfa) {
+ sources += [
+ "gc/container_trace_unittest.cpp",
+ "gc/gced_tree_node_mixin_unittest.cpp",
+ "gc/gced_tree_node_unittest.cpp",
+ "gc/heap_unittest.cpp",
+ "gc/move_unittest.cpp",
+ "xfa/cfxjse_formcalc_context_unittest.cpp",
+ "xfa/cfxjse_mapmodule_unittest.cpp",
+ ]
+ deps += [
+ ":gc",
+ "../xfa/fxfa/parser",
+ ]
+ }
}
pdfium_embeddertest_source_set("embeddertests") {
@@ -237,7 +283,6 @@
"../fpdfsdk",
]
pdfium_root_dir = "../"
-
if (pdf_enable_xfa) {
sources += [
"xfa/cfxjse_app_embeddertest.cpp",
@@ -245,8 +290,12 @@
"xfa/cfxjse_value_embeddertest.cpp",
"xfa/cjx_hostpseudomodel_embeddertest.cpp",
"xfa/cjx_list_embeddertest.cpp",
+ "xfa/cjx_object_embeddertest.cpp",
]
- deps += [ "../xfa/fxfa" ]
+ deps += [
+ ":gc",
+ "../xfa/fxfa",
+ ]
}
}
}
diff --git a/fxjs/README b/fxjs/README
index a1cfe32..59b55a2 100644
--- a/fxjs/README
+++ b/fxjs/README
@@ -20,20 +20,20 @@
objects, regardless of the FXJS/FXJSE distinction. Slot 0 is the
tag and contains either:
kPerObjectDataTag for FXJS objects, or
- g_FXJSEHostObjectTag for FXJSE Host objects, or
- g_FXJSEProxyObjectTag for a global proxy object under FXJSE, or
+ kFXJSEHostObjectTag for FXJSE Host objects, or
+ kFXJSEProxyObjectTag for a global proxy object under FXJSE, or
One of 4 specific FXJSE_CLASS_DESCRIPTOR globals for FXJSE classes:
- GlobalClassDescriptor
- NormalClassDescriptor
- VariablesClassDescriptor
- formcalc_fm2js_descriptor
+ kGlobalClassDescriptor
+ kNormalClassDescriptor
+ kVariablesClassDescriptor
+ kFormCalcDescriptor
Slot 1's contents are determined by these tags:
kPerObjectDataTag means an aligned pointer to CFXJS_PerObjectData.
- g_FXJSEHostObjectTag means an aligned pointer to CFXJSE_HostObject.
- g_FXJSEProxyObjectTag means nullptr, and to check the prototype instead.
+ kFXJSEHostObjectTag means an aligned pointer to CFXJSE_HostObject.
+ kFXJSEProxyObjectTag means nullptr, and to check the prototype instead.
A FXJSE_CLASS_DESCRIPTOR pointer means to expect an actual v8 function
- object (or a string naming that function), and not an aligned pointer.
+ object (or a string naming that function), and not an aligned pointer.
Because PDFium uses V8 for various unrelated purposes, there may be up to
four v8::Contexts (JS Global Objects) associated with each document. One is
diff --git a/fxjs/cfx_globaldata.cpp b/fxjs/cfx_globaldata.cpp
index 9131f02..59b43c1 100644
--- a/fxjs/cfx_globaldata.cpp
+++ b/fxjs/cfx_globaldata.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,8 +9,8 @@
#include <utility>
#include "core/fdrm/fx_crypt.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
+#include "core/fxcrt/stl_util.h"
+#include "third_party/base/numerics/safe_conversions.h"
namespace {
@@ -40,44 +40,41 @@
void MakeNameTypeString(const ByteString& name,
CFX_Value::DataType eType,
- CFX_BinaryBuf* result) {
- uint32_t dwNameLen = (uint32_t)name.GetLength();
- result->AppendBlock(&dwNameLen, sizeof(uint32_t));
+ BinaryBuffer* result) {
+ uint32_t dwNameLen = pdfium::base::checked_cast<uint32_t>(name.GetLength());
+ result->AppendUint32(dwNameLen);
result->AppendString(name);
-
- uint16_t wType = static_cast<uint16_t>(eType);
- result->AppendBlock(&wType, sizeof(uint16_t));
+ result->AppendUint16(static_cast<uint16_t>(eType));
}
bool MakeByteString(const ByteString& name,
const CFX_KeyValue& pData,
- CFX_BinaryBuf* result) {
+ BinaryBuffer* result) {
switch (pData.nType) {
- case CFX_Value::DataType::NUMBER: {
+ case CFX_Value::DataType::kNumber: {
MakeNameTypeString(name, pData.nType, result);
- double dData = pData.dData;
- result->AppendBlock(&dData, sizeof(double));
+ result->AppendDouble(pData.dData);
return true;
}
- case CFX_Value::DataType::BOOLEAN: {
+ case CFX_Value::DataType::kBoolean: {
MakeNameTypeString(name, pData.nType, result);
- uint16_t wData = static_cast<uint16_t>(pData.bData);
- result->AppendBlock(&wData, sizeof(uint16_t));
+ result->AppendUint16(static_cast<uint16_t>(pData.bData));
return true;
}
- case CFX_Value::DataType::STRING: {
+ case CFX_Value::DataType::kString: {
MakeNameTypeString(name, pData.nType, result);
- uint32_t dwDataLen = (uint32_t)pData.sData.GetLength();
- result->AppendBlock(&dwDataLen, sizeof(uint32_t));
+ uint32_t dwDataLen =
+ pdfium::base::checked_cast<uint32_t>(pData.sData.GetLength());
+ result->AppendUint32(dwDataLen);
result->AppendString(pData.sData);
return true;
}
- case CFX_Value::DataType::NULLOBJ: {
+ case CFX_Value::DataType::kNull: {
MakeNameTypeString(name, pData.nType, result);
return true;
}
// Arrays don't get persisted per JS spec page 484.
- case CFX_Value::DataType::OBJECT:
+ case CFX_Value::DataType::kObject:
default:
break;
}
@@ -135,13 +132,13 @@
CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
if (pData) {
- pData->data.nType = CFX_Value::DataType::NUMBER;
+ pData->data.nType = CFX_Value::DataType::kNumber;
pData->data.dData = dData;
return;
}
- auto pNewData = pdfium::MakeUnique<CFX_GlobalData::Element>();
+ auto pNewData = std::make_unique<CFX_GlobalData::Element>();
pNewData->data.sKey = std::move(sPropName);
- pNewData->data.nType = CFX_Value::DataType::NUMBER;
+ pNewData->data.nType = CFX_Value::DataType::kNumber;
pNewData->data.dData = dData;
m_arrayGlobalData.push_back(std::move(pNewData));
}
@@ -153,13 +150,13 @@
CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
if (pData) {
- pData->data.nType = CFX_Value::DataType::BOOLEAN;
+ pData->data.nType = CFX_Value::DataType::kBoolean;
pData->data.bData = bData;
return;
}
- auto pNewData = pdfium::MakeUnique<CFX_GlobalData::Element>();
+ auto pNewData = std::make_unique<CFX_GlobalData::Element>();
pNewData->data.sKey = std::move(sPropName);
- pNewData->data.nType = CFX_Value::DataType::BOOLEAN;
+ pNewData->data.nType = CFX_Value::DataType::kBoolean;
pNewData->data.bData = bData;
m_arrayGlobalData.push_back(std::move(pNewData));
}
@@ -171,13 +168,13 @@
CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
if (pData) {
- pData->data.nType = CFX_Value::DataType::STRING;
+ pData->data.nType = CFX_Value::DataType::kString;
pData->data.sData = sData;
return;
}
- auto pNewData = pdfium::MakeUnique<CFX_GlobalData::Element>();
+ auto pNewData = std::make_unique<CFX_GlobalData::Element>();
pNewData->data.sKey = std::move(sPropName);
- pNewData->data.nType = CFX_Value::DataType::STRING;
+ pNewData->data.nType = CFX_Value::DataType::kString;
pNewData->data.sData = sData;
m_arrayGlobalData.push_back(std::move(pNewData));
}
@@ -190,13 +187,13 @@
CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
if (pData) {
- pData->data.nType = CFX_Value::DataType::OBJECT;
+ pData->data.nType = CFX_Value::DataType::kObject;
pData->data.objData = std::move(array);
return;
}
- auto pNewData = pdfium::MakeUnique<CFX_GlobalData::Element>();
+ auto pNewData = std::make_unique<CFX_GlobalData::Element>();
pNewData->data.sKey = std::move(sPropName);
- pNewData->data.nType = CFX_Value::DataType::OBJECT;
+ pNewData->data.nType = CFX_Value::DataType::kObject;
pNewData->data.objData = std::move(array);
m_arrayGlobalData.push_back(std::move(pNewData));
}
@@ -207,12 +204,12 @@
CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
if (pData) {
- pData->data.nType = CFX_Value::DataType::NULLOBJ;
+ pData->data.nType = CFX_Value::DataType::kNull;
return;
}
- auto pNewData = pdfium::MakeUnique<CFX_GlobalData::Element>();
+ auto pNewData = std::make_unique<CFX_GlobalData::Element>();
pNewData->data.sKey = std::move(sPropName);
- pNewData->data.nType = CFX_Value::DataType::NULLOBJ;
+ pNewData->data.nType = CFX_Value::DataType::kNull;
m_arrayGlobalData.push_back(std::move(pNewData));
}
@@ -242,7 +239,7 @@
}
int32_t CFX_GlobalData::GetSize() const {
- return pdfium::CollectionSize<int32_t>(m_arrayGlobalData);
+ return fxcrt::CollectionSize<int32_t>(m_arrayGlobalData);
}
CFX_GlobalData::Element* CFX_GlobalData::GetAt(int index) {
@@ -258,7 +255,7 @@
bool ret;
{
// Span can't outlive call to BufferDone().
- Optional<pdfium::span<uint8_t>> buffer = m_pDelegate->LoadBuffer();
+ absl::optional<pdfium::span<uint8_t>> buffer = m_pDelegate->LoadBuffer();
if (!buffer.has_value() || buffer.value().empty())
return false;
@@ -312,7 +309,7 @@
p += sizeof(uint16_t);
switch (wDataType) {
- case CFX_Value::DataType::NUMBER: {
+ case CFX_Value::DataType::kNumber: {
double dData = 0;
switch (wVersion) {
case 1: {
@@ -328,13 +325,13 @@
SetGlobalVariableNumber(sEntry, dData);
SetGlobalVariablePersistent(sEntry, true);
} break;
- case CFX_Value::DataType::BOOLEAN: {
+ case CFX_Value::DataType::kBoolean: {
uint16_t wData = *((uint16_t*)p);
p += sizeof(uint16_t);
SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
SetGlobalVariablePersistent(sEntry, true);
} break;
- case CFX_Value::DataType::STRING: {
+ case CFX_Value::DataType::kString: {
uint32_t dwLength = *((uint32_t*)p);
p += sizeof(uint32_t);
if (p + dwLength > buffer.end())
@@ -344,11 +341,11 @@
SetGlobalVariablePersistent(sEntry, true);
p += sizeof(char) * dwLength;
} break;
- case CFX_Value::DataType::NULLOBJ: {
+ case CFX_Value::DataType::kNull: {
SetGlobalVariableNull(sEntry);
SetGlobalVariablePersistent(sEntry, true);
} break;
- case CFX_Value::DataType::OBJECT:
+ case CFX_Value::DataType::kObject:
default:
// Arrays aren't allowed in these buffers, nor are unrecoginzed tags.
return false;
@@ -362,12 +359,12 @@
return false;
uint32_t nCount = 0;
- CFX_BinaryBuf sData;
+ BinaryBuffer sData;
for (const auto& pElement : m_arrayGlobalData) {
if (!pElement->bPersistent)
continue;
- CFX_BinaryBuf sElement;
+ BinaryBuffer sElement;
if (!MakeByteString(pElement->data.sKey, pElement->data, &sElement))
continue;
@@ -378,20 +375,17 @@
nCount++;
}
- CFX_BinaryBuf sFile;
- uint16_t wType = kMagic;
- uint16_t wVersion = 2;
- sFile.AppendBlock(&wType, sizeof(uint16_t));
- sFile.AppendBlock(&wVersion, sizeof(uint16_t));
- sFile.AppendBlock(&nCount, sizeof(uint32_t));
+ BinaryBuffer sFile;
+ sFile.AppendUint16(kMagic);
+ sFile.AppendUint16(kMaxVersion);
+ sFile.AppendUint32(nCount);
- uint32_t dwSize = sData.GetSize();
- sFile.AppendBlock(&dwSize, sizeof(uint32_t));
+ uint32_t dwSize = pdfium::base::checked_cast<uint32_t>(sData.GetSize());
+ sFile.AppendUint32(dwSize);
sFile.AppendSpan(sData.GetSpan());
- CRYPT_ArcFourCryptBlock(sFile.GetSpan(), kRC4KEY);
-
- return m_pDelegate->StoreBuffer({sFile.GetBuffer(), sFile.GetSize()});
+ CRYPT_ArcFourCryptBlock(sFile.GetMutableSpan(), kRC4KEY);
+ return m_pDelegate->StoreBuffer(sFile.GetSpan());
}
CFX_GlobalData::Element::Element() = default;
diff --git a/fxjs/cfx_globaldata.h b/fxjs/cfx_globaldata.h
index 421a3b4..6b94265 100644
--- a/fxjs/cfx_globaldata.h
+++ b/fxjs/cfx_globaldata.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,22 +10,20 @@
#include <memory>
#include <vector>
-#include "core/fxcrt/cfx_binarybuf.h"
+#include "core/fxcrt/binary_buffer.h"
#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/cfx_keyvalue.h"
-#include "third_party/base/optional.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/base/span.h"
-class CPDFSDK_FormFillEnvironment;
-
class CFX_GlobalData {
public:
class Delegate {
public:
- virtual ~Delegate() {}
+ virtual ~Delegate() = default;
virtual bool StoreBuffer(pdfium::span<const uint8_t> pBuffer) = 0;
- virtual Optional<pdfium::span<uint8_t>> LoadBuffer() = 0;
+ virtual absl::optional<pdfium::span<uint8_t>> LoadBuffer() = 0;
virtual void BufferDone() = 0;
};
@@ -35,7 +33,7 @@
~Element();
CFX_KeyValue data;
- bool bPersistent;
+ bool bPersistent = false;
};
static CFX_GlobalData* GetRetainedInstance(Delegate* pDelegate);
@@ -66,16 +64,8 @@
bool LoadGlobalPersistentVariables();
bool LoadGlobalPersistentVariablesFromBuffer(pdfium::span<uint8_t> buffer);
bool SaveGlobalPersisitentVariables();
-
iterator FindGlobalVariable(const ByteString& sPropname);
- void LoadFileBuffer(const wchar_t* sFilePath,
- uint8_t*& pBuffer,
- int32_t& nLength);
- void WriteFileBuffer(const wchar_t* sFilePath,
- const char* pBuffer,
- int32_t nLength);
-
size_t m_RefCount = 0;
UnownedPtr<Delegate> const m_pDelegate;
std::vector<std::unique_ptr<Element>> m_arrayGlobalData;
diff --git a/fxjs/cfx_globaldata_unittest.cpp b/fxjs/cfx_globaldata_unittest.cpp
index 3eb0ac4..8121701 100644
--- a/fxjs/cfx_globaldata_unittest.cpp
+++ b/fxjs/cfx_globaldata_unittest.cpp
@@ -1,12 +1,15 @@
-// Copyright 2018 PDFium Authors. All rights reserved.
+// Copyright 2018 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fxjs/cfx_globaldata.h"
+#include <stdint.h>
+
#include <utility>
#include <vector>
+#include "core/fxcrt/data_vector.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -14,39 +17,40 @@
class TestDelegate : public CFX_GlobalData::Delegate {
public:
TestDelegate() = default;
- ~TestDelegate() override {}
+ ~TestDelegate() override = default;
bool StoreBuffer(pdfium::span<const uint8_t> buffer) override {
- last_buffer_ = std::vector<uint8_t>(buffer.begin(), buffer.end());
+ last_buffer_ = DataVector<uint8_t>(buffer.begin(), buffer.end());
return true;
}
- Optional<pdfium::span<uint8_t>> LoadBuffer() override {
+ absl::optional<pdfium::span<uint8_t>> LoadBuffer() override {
return pdfium::span<uint8_t>(last_buffer_);
}
void BufferDone() override {
- last_buffer_ = std::vector<uint8_t>(); // Catch misuse after done.
+ // Catch misuse after done.
+ last_buffer_ = DataVector<uint8_t>();
}
- std::vector<uint8_t> last_buffer_;
+ DataVector<uint8_t> last_buffer_;
};
} // namespace
TEST(CFXGlobalData, GetSafety) {
CFX_GlobalData* pInstance = CFX_GlobalData::GetRetainedInstance(nullptr);
- EXPECT_EQ(nullptr, pInstance->GetGlobalVariable("nonesuch"));
- EXPECT_EQ(nullptr, pInstance->GetAt(-1));
- EXPECT_EQ(nullptr, pInstance->GetAt(0));
- EXPECT_EQ(nullptr, pInstance->GetAt(1));
+ EXPECT_FALSE(pInstance->GetGlobalVariable("nonesuch"));
+ EXPECT_FALSE(pInstance->GetAt(-1));
+ EXPECT_FALSE(pInstance->GetAt(0));
+ EXPECT_FALSE(pInstance->GetAt(1));
pInstance->SetGlobalVariableNumber("double", 2.0);
pInstance->SetGlobalVariableString("string", "clams");
- EXPECT_EQ(nullptr, pInstance->GetGlobalVariable("nonesuch"));
- EXPECT_EQ(nullptr, pInstance->GetAt(-1));
+ EXPECT_FALSE(pInstance->GetGlobalVariable("nonesuch"));
+ EXPECT_FALSE(pInstance->GetAt(-1));
EXPECT_EQ(pInstance->GetGlobalVariable("double"), pInstance->GetAt(0));
EXPECT_EQ(pInstance->GetGlobalVariable("string"), pInstance->GetAt(1));
- EXPECT_EQ(nullptr, pInstance->GetAt(2));
+ EXPECT_FALSE(pInstance->GetAt(2));
ASSERT_TRUE(pInstance->Release());
}
@@ -71,25 +75,25 @@
auto* element = pInstance->GetAt(0);
ASSERT_TRUE(element);
EXPECT_EQ("double", element->data.sKey);
- EXPECT_EQ(CFX_Value::DataType::NUMBER, element->data.nType);
+ EXPECT_EQ(CFX_Value::DataType::kNumber, element->data.nType);
EXPECT_EQ(2.0, element->data.dData);
element = pInstance->GetAt(1);
ASSERT_TRUE(element);
EXPECT_EQ("string", element->data.sKey);
- EXPECT_EQ(CFX_Value::DataType::STRING, element->data.nType);
+ EXPECT_EQ(CFX_Value::DataType::kString, element->data.nType);
EXPECT_EQ("clams", element->data.sData);
element = pInstance->GetAt(2);
ASSERT_TRUE(element);
EXPECT_EQ("boolean", element->data.sKey);
- EXPECT_EQ(CFX_Value::DataType::BOOLEAN, element->data.nType);
+ EXPECT_EQ(CFX_Value::DataType::kBoolean, element->data.nType);
EXPECT_EQ(true, element->data.bData);
element = pInstance->GetAt(3);
ASSERT_TRUE(element);
EXPECT_EQ("null", element->data.sKey);
- EXPECT_EQ(CFX_Value::DataType::NULLOBJ, element->data.nType);
+ EXPECT_EQ(CFX_Value::DataType::kNull, element->data.nType);
// Arrays don't get persisted.
element = pInstance->GetAt(4);
@@ -113,25 +117,25 @@
auto* element = pInstance->GetAt(0);
ASSERT_TRUE(element);
EXPECT_EQ("double", element->data.sKey);
- EXPECT_EQ(CFX_Value::DataType::NUMBER, element->data.nType);
+ EXPECT_EQ(CFX_Value::DataType::kNumber, element->data.nType);
EXPECT_EQ(2.0, element->data.dData);
element = pInstance->GetAt(1);
ASSERT_TRUE(element);
EXPECT_EQ("string", element->data.sKey);
- EXPECT_EQ(CFX_Value::DataType::STRING, element->data.nType);
+ EXPECT_EQ(CFX_Value::DataType::kString, element->data.nType);
EXPECT_EQ("clams", element->data.sData);
element = pInstance->GetAt(2);
ASSERT_TRUE(element);
EXPECT_EQ("boolean", element->data.sKey);
- EXPECT_EQ(CFX_Value::DataType::BOOLEAN, element->data.nType);
+ EXPECT_EQ(CFX_Value::DataType::kBoolean, element->data.nType);
EXPECT_EQ(true, element->data.bData);
element = pInstance->GetAt(3);
ASSERT_TRUE(element);
EXPECT_EQ("null", element->data.sKey);
- EXPECT_EQ(CFX_Value::DataType::NULLOBJ, element->data.nType);
+ EXPECT_EQ(CFX_Value::DataType::kNull, element->data.nType);
ASSERT_TRUE(pInstance->Release());
}
diff --git a/fxjs/cfx_keyvalue.cpp b/fxjs/cfx_keyvalue.cpp
index d1c7fae..a0ee7c2 100644
--- a/fxjs/cfx_keyvalue.cpp
+++ b/fxjs/cfx_keyvalue.cpp
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
diff --git a/fxjs/cfx_keyvalue.h b/fxjs/cfx_keyvalue.h
index b66dc12..a6ff52a 100644
--- a/fxjs/cfx_keyvalue.h
+++ b/fxjs/cfx_keyvalue.h
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,26 +10,26 @@
#include <memory>
#include <vector>
-#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/bytestring.h"
class CFX_KeyValue;
class CFX_Value {
public:
enum class DataType : uint8_t {
- NUMBER = 0,
- BOOLEAN,
- STRING,
- OBJECT,
- NULLOBJ
+ kNumber = 0,
+ kBoolean,
+ kString,
+ kObject,
+ kNull
};
CFX_Value();
~CFX_Value();
- DataType nType = DataType::NULLOBJ;
- bool bData;
- double dData;
+ DataType nType = DataType::kNull;
+ bool bData = false;
+ double dData = 0.0;
ByteString sData;
std::vector<std::unique_ptr<CFX_KeyValue>> objData;
};
diff --git a/fxjs/cfx_v8.cpp b/fxjs/cfx_v8.cpp
index 72bf361..422e28a 100644
--- a/fxjs/cfx_v8.cpp
+++ b/fxjs/cfx_v8.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,8 +6,8 @@
#include "fxjs/cfx_v8.h"
-#include "core/fxcrt/fx_memory.h"
-#include "third_party/base/allocator/partition_allocator/partition_alloc.h"
+#include "fxjs/fxv8.h"
+#include "v8/include/v8-isolate.h"
CFX_V8::CFX_V8(v8::Isolate* isolate) : m_pIsolate(isolate) {}
@@ -16,103 +16,68 @@
v8::Local<v8::Value> CFX_V8::GetObjectProperty(
v8::Local<v8::Object> pObj,
ByteStringView bsUTF8PropertyName) {
- if (pObj.IsEmpty())
- return v8::Local<v8::Value>();
- v8::Local<v8::Value> val;
- if (!pObj->Get(m_pIsolate->GetCurrentContext(), NewString(bsUTF8PropertyName))
- .ToLocal(&val))
- return v8::Local<v8::Value>();
- return val;
+ return fxv8::ReentrantGetObjectPropertyHelper(GetIsolate(), pObj,
+ bsUTF8PropertyName);
}
std::vector<WideString> CFX_V8::GetObjectPropertyNames(
v8::Local<v8::Object> pObj) {
- if (pObj.IsEmpty())
- return std::vector<WideString>();
-
- v8::Local<v8::Array> val;
- v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
- if (!pObj->GetPropertyNames(context).ToLocal(&val))
- return std::vector<WideString>();
-
- std::vector<WideString> result;
- for (uint32_t i = 0; i < val->Length(); ++i) {
- result.push_back(ToWideString(val->Get(context, i).ToLocalChecked()));
- }
-
- return result;
+ return fxv8::ReentrantGetObjectPropertyNamesHelper(GetIsolate(), pObj);
}
-bool CFX_V8::PutObjectProperty(v8::Local<v8::Object> pObj,
+void CFX_V8::PutObjectProperty(v8::Local<v8::Object> pObj,
ByteStringView bsUTF8PropertyName,
v8::Local<v8::Value> pPut) {
- ASSERT(!pPut.IsEmpty());
- if (pObj.IsEmpty())
- return false;
-
- v8::Local<v8::String> name = NewString(bsUTF8PropertyName);
- return pObj->Set(m_pIsolate->GetCurrentContext(), name, pPut).IsJust();
+ fxv8::ReentrantPutObjectPropertyHelper(GetIsolate(), pObj, bsUTF8PropertyName,
+ pPut);
}
void CFX_V8::DisposeIsolate() {
if (m_pIsolate)
- m_pIsolate.Release()->Dispose();
+ m_pIsolate.ExtractAsDangling()->Dispose();
}
v8::Local<v8::Array> CFX_V8::NewArray() {
- return v8::Array::New(GetIsolate());
+ return fxv8::NewArrayHelper(GetIsolate());
}
v8::Local<v8::Object> CFX_V8::NewObject() {
- return v8::Object::New(GetIsolate());
+ return fxv8::NewObjectHelper(GetIsolate());
}
-bool CFX_V8::PutArrayElement(v8::Local<v8::Array> pArray,
- unsigned index,
+void CFX_V8::PutArrayElement(v8::Local<v8::Array> pArray,
+ size_t index,
v8::Local<v8::Value> pValue) {
- ASSERT(!pValue.IsEmpty());
- if (pArray.IsEmpty())
- return false;
- return pArray->Set(m_pIsolate->GetCurrentContext(), index, pValue).IsJust();
+ fxv8::ReentrantPutArrayElementHelper(GetIsolate(), pArray, index, pValue);
}
v8::Local<v8::Value> CFX_V8::GetArrayElement(v8::Local<v8::Array> pArray,
- unsigned index) {
- if (pArray.IsEmpty())
- return v8::Local<v8::Value>();
- v8::Local<v8::Value> val;
- if (!pArray->Get(m_pIsolate->GetCurrentContext(), index).ToLocal(&val))
- return v8::Local<v8::Value>();
- return val;
+ size_t index) {
+ return fxv8::ReentrantGetArrayElementHelper(GetIsolate(), pArray, index);
}
-unsigned CFX_V8::GetArrayLength(v8::Local<v8::Array> pArray) {
- if (pArray.IsEmpty())
- return 0;
- return pArray->Length();
+size_t CFX_V8::GetArrayLength(v8::Local<v8::Array> pArray) {
+ return fxv8::GetArrayLengthHelper(pArray);
}
v8::Local<v8::Number> CFX_V8::NewNumber(int number) {
- return v8::Int32::New(GetIsolate(), number);
+ return fxv8::NewNumberHelper(GetIsolate(), number);
}
v8::Local<v8::Number> CFX_V8::NewNumber(double number) {
- return v8::Number::New(GetIsolate(), number);
+ return fxv8::NewNumberHelper(GetIsolate(), number);
}
v8::Local<v8::Number> CFX_V8::NewNumber(float number) {
- return v8::Number::New(GetIsolate(), number);
+ return fxv8::NewNumberHelper(GetIsolate(), number);
}
v8::Local<v8::Boolean> CFX_V8::NewBoolean(bool b) {
- return v8::Boolean::New(GetIsolate(), b);
+ return fxv8::NewBooleanHelper(GetIsolate(), b);
}
v8::Local<v8::String> CFX_V8::NewString(ByteStringView str) {
- v8::Isolate* pIsolate = m_pIsolate ? GetIsolate() : v8::Isolate::GetCurrent();
- return v8::String::NewFromUtf8(pIsolate, str.unterminated_c_str(),
- v8::NewStringType::kNormal, str.GetLength())
- .ToLocalChecked();
+ return fxv8::NewStringHelper(GetIsolate(), str);
}
v8::Local<v8::String> CFX_V8::NewString(WideStringView str) {
@@ -123,95 +88,45 @@
}
v8::Local<v8::Value> CFX_V8::NewNull() {
- return v8::Null(GetIsolate());
+ return fxv8::NewNullHelper(GetIsolate());
}
v8::Local<v8::Value> CFX_V8::NewUndefined() {
- return v8::Undefined(GetIsolate());
+ return fxv8::NewUndefinedHelper(GetIsolate());
}
v8::Local<v8::Date> CFX_V8::NewDate(double d) {
- return v8::Date::New(m_pIsolate->GetCurrentContext(), d)
- .ToLocalChecked()
- .As<v8::Date>();
+ return fxv8::NewDateHelper(GetIsolate(), d);
}
int CFX_V8::ToInt32(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty())
- return 0;
- v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
- v8::MaybeLocal<v8::Int32> maybe_int32 = pValue->ToInt32(context);
- if (maybe_int32.IsEmpty())
- return 0;
- return maybe_int32.ToLocalChecked()->Value();
+ return fxv8::ReentrantToInt32Helper(GetIsolate(), pValue);
}
bool CFX_V8::ToBoolean(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty())
- return false;
- return pValue->BooleanValue(m_pIsolate.Get());
+ return fxv8::ReentrantToBooleanHelper(GetIsolate(), pValue);
}
double CFX_V8::ToDouble(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty())
- return 0.0;
- v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
- v8::MaybeLocal<v8::Number> maybe_number = pValue->ToNumber(context);
- if (maybe_number.IsEmpty())
- return 0.0;
- return maybe_number.ToLocalChecked()->Value();
+ return fxv8::ReentrantToDoubleHelper(GetIsolate(), pValue);
}
WideString CFX_V8::ToWideString(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty())
- return WideString();
- v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
- v8::MaybeLocal<v8::String> maybe_string = pValue->ToString(context);
- if (maybe_string.IsEmpty())
- return WideString();
- v8::String::Utf8Value s(GetIsolate(), maybe_string.ToLocalChecked());
- return WideString::FromUTF8(ByteStringView(*s, s.length()));
+ return fxv8::ReentrantToWideStringHelper(GetIsolate(), pValue);
}
ByteString CFX_V8::ToByteString(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty())
- return ByteString();
- v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
- v8::MaybeLocal<v8::String> maybe_string = pValue->ToString(context);
- if (maybe_string.IsEmpty())
- return ByteString();
- v8::String::Utf8Value s(GetIsolate(), maybe_string.ToLocalChecked());
- return ByteString(*s);
+ return fxv8::ReentrantToByteStringHelper(GetIsolate(), pValue);
}
v8::Local<v8::Object> CFX_V8::ToObject(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty() || !pValue->IsObject())
- return v8::Local<v8::Object>();
- v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
- return pValue->ToObject(context).ToLocalChecked();
+ return fxv8::ReentrantToObjectHelper(GetIsolate(), pValue);
}
v8::Local<v8::Array> CFX_V8::ToArray(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty() || !pValue->IsArray())
- return v8::Local<v8::Array>();
- v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
- return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
+ return fxv8::ReentrantToArrayHelper(GetIsolate(), pValue);
}
-void* CFX_V8ArrayBufferAllocator::Allocate(size_t length) {
- if (length > kMaxAllowedBytes)
- return nullptr;
- return GetArrayBufferPartitionAllocator().root()->AllocFlags(
- pdfium::base::PartitionAllocZeroFill, length, "CFX_V8ArrayBuffer");
-}
-
-void* CFX_V8ArrayBufferAllocator::AllocateUninitialized(size_t length) {
- if (length > kMaxAllowedBytes)
- return nullptr;
- return GetArrayBufferPartitionAllocator().root()->Alloc(length,
- "CFX_V8ArrayBuffer");
-}
-
-void CFX_V8ArrayBufferAllocator::Free(void* data, size_t length) {
- GetArrayBufferPartitionAllocator().root()->Free(data);
+void CFX_V8IsolateDeleter::operator()(v8::Isolate* ptr) {
+ ptr->Dispose();
}
diff --git a/fxjs/cfx_v8.h b/fxjs/cfx_v8.h
index cb152ac..7b2ddc9 100644
--- a/fxjs/cfx_v8.h
+++ b/fxjs/cfx_v8.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,18 +7,20 @@
#ifndef FXJS_CFX_V8_H_
#define FXJS_CFX_V8_H_
+#include <stddef.h>
+
#include <vector>
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/unowned_ptr.h"
-#include "v8/include/v8.h"
+#include "v8/include/v8-forward.h"
class CFX_V8 {
public:
explicit CFX_V8(v8::Isolate* pIsolate);
virtual ~CFX_V8();
- v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); }
+ v8::Isolate* GetIsolate() const { return m_pIsolate; }
v8::Local<v8::Value> NewNull();
v8::Local<v8::Value> NewUndefined();
@@ -41,18 +43,18 @@
v8::Local<v8::Array> ToArray(v8::Local<v8::Value> pValue);
// Arrays.
- unsigned GetArrayLength(v8::Local<v8::Array> pArray);
+ size_t GetArrayLength(v8::Local<v8::Array> pArray);
v8::Local<v8::Value> GetArrayElement(v8::Local<v8::Array> pArray,
- unsigned index);
- bool PutArrayElement(v8::Local<v8::Array> pArray,
- unsigned index,
+ size_t index);
+ void PutArrayElement(v8::Local<v8::Array> pArray,
+ size_t index,
v8::Local<v8::Value> pValue);
// Objects.
std::vector<WideString> GetObjectPropertyNames(v8::Local<v8::Object> pObj);
v8::Local<v8::Value> GetObjectProperty(v8::Local<v8::Object> pObj,
ByteStringView bsUTF8PropertyName);
- bool PutObjectProperty(v8::Local<v8::Object> pObj,
+ void PutObjectProperty(v8::Local<v8::Object> pObj,
ByteStringView bsUTF8PropertyName,
v8::Local<v8::Value> pValue);
@@ -64,16 +66,9 @@
UnownedPtr<v8::Isolate> m_pIsolate;
};
-class CFX_V8ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator {
- static const size_t kMaxAllowedBytes = 0x10000000;
- void* Allocate(size_t length) override;
- void* AllocateUninitialized(size_t length) override;
- void Free(void* data, size_t length) override;
-};
-
// Use with std::unique_ptr<v8::Isolate> to dispose of isolates correctly.
struct CFX_V8IsolateDeleter {
- inline void operator()(v8::Isolate* ptr) { ptr->Dispose(); }
+ void operator()(v8::Isolate* ptr);
};
#endif // FXJS_CFX_V8_H_
diff --git a/fxjs/cfx_v8_array_buffer_allocator.cpp b/fxjs/cfx_v8_array_buffer_allocator.cpp
new file mode 100644
index 0000000..c0ddad0
--- /dev/null
+++ b/fxjs/cfx_v8_array_buffer_allocator.cpp
@@ -0,0 +1,53 @@
+// Copyright 2021 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fxjs/cfx_v8_array_buffer_allocator.h"
+
+#include "core/fxcrt/fx_memory.h"
+
+CFX_V8ArrayBufferAllocator::CFX_V8ArrayBufferAllocator() = default;
+
+CFX_V8ArrayBufferAllocator::~CFX_V8ArrayBufferAllocator() = default;
+
+// NOTE: Under V8 sandbox mode, defer NewDefaultAllocator() call until
+// first use, since V8 must be initialized first for it to succeed, but
+// we need the allocator in order to initialize V8.
+
+void* CFX_V8ArrayBufferAllocator::Allocate(size_t length) {
+ if (length > kMaxAllowedBytes)
+ return nullptr;
+#ifdef V8_ENABLE_SANDBOX
+ if (!wrapped_) {
+ wrapped_.reset(v8::ArrayBuffer::Allocator::NewDefaultAllocator());
+ }
+ return wrapped_->Allocate(length);
+#else // V8_ENABLE_SANDBOX
+ return FX_ArrayBufferAllocate(length);
+#endif // V8_ENABLE_SANDBOX
+}
+
+void* CFX_V8ArrayBufferAllocator::AllocateUninitialized(size_t length) {
+ if (length > kMaxAllowedBytes)
+ return nullptr;
+#ifdef V8_ENABLE_SANDBOX
+ if (!wrapped_) {
+ wrapped_.reset(v8::ArrayBuffer::Allocator::NewDefaultAllocator());
+ }
+ return wrapped_->AllocateUninitialized(length);
+#else // V8_ENABLE_SANDBOX
+ return FX_ArrayBufferAllocateUninitialized(length);
+#endif
+}
+
+void CFX_V8ArrayBufferAllocator::Free(void* data, size_t length) {
+#ifdef V8_ENABLE_SANDBOX
+ if (wrapped_) {
+ wrapped_->Free(data, length);
+ }
+#else // V8_ENABLE_SANDBOX
+ FX_ArrayBufferFree(data);
+#endif
+}
diff --git a/fxjs/cfx_v8_array_buffer_allocator.h b/fxjs/cfx_v8_array_buffer_allocator.h
new file mode 100644
index 0000000..a6daef0
--- /dev/null
+++ b/fxjs/cfx_v8_array_buffer_allocator.h
@@ -0,0 +1,35 @@
+// Copyright 2021 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJS_CFX_V8_ARRAY_BUFFER_ALLOCATOR_H_
+#define FXJS_CFX_V8_ARRAY_BUFFER_ALLOCATOR_H_
+
+#include <stddef.h>
+
+#include <memory>
+
+#include "v8/include/v8-array-buffer.h"
+
+class CFX_V8ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator {
+ public:
+ static const size_t kMaxAllowedBytes = 0x10000000;
+
+ CFX_V8ArrayBufferAllocator();
+ CFX_V8ArrayBufferAllocator(const CFX_V8ArrayBufferAllocator&) = delete;
+ CFX_V8ArrayBufferAllocator(CFX_V8ArrayBufferAllocator&&) = delete;
+ ~CFX_V8ArrayBufferAllocator() override;
+
+ void* Allocate(size_t length) override;
+ void* AllocateUninitialized(size_t length) override;
+ void Free(void* data, size_t length) override;
+
+#ifdef V8_ENABLE_SANDBOX
+ private:
+ std::unique_ptr<v8::ArrayBuffer::Allocator> wrapped_;
+#endif // V8_ENABLE_SANDBOX
+};
+
+#endif // FXJS_CFX_V8_ARRAY_BUFFER_ALLOCATOR_H_
diff --git a/fxjs/cfx_v8_unittest.cpp b/fxjs/cfx_v8_unittest.cpp
index 7b9ecb5..0a2dca8 100644
--- a/fxjs/cfx_v8_unittest.cpp
+++ b/fxjs/cfx_v8_unittest.cpp
@@ -1,39 +1,43 @@
-// Copyright 2018 PDFium Authors. All rights reserved.
+// Copyright 2018 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "fxjs/cfx_v8_unittest.h"
+#include "fxjs/cfx_v8.h"
+
+#include <math.h>
#include <memory>
-#include "fxjs/cfx_v8.h"
+#include "testing/fxv8_unittest.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/base/ptr_util.h"
+#include "v8/include/v8-container.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-date.h"
+#include "v8/include/v8-isolate.h"
namespace {
bool getter_sentinel = false;
bool setter_sentinel = false;
} // namespace
-void FXV8UnitTest::V8IsolateDeleter::operator()(v8::Isolate* ptr) const {
- ptr->Dispose();
-}
+class CFXV8UnitTest : public FXV8UnitTest {
+ public:
+ CFXV8UnitTest() = default;
+ ~CFXV8UnitTest() override = default;
-FXV8UnitTest::FXV8UnitTest() = default;
+ // FXV8UnitTest:
+ void SetUp() override {
+ FXV8UnitTest::SetUp();
+ cfx_v8_ = std::make_unique<CFX_V8>(isolate());
+ }
-FXV8UnitTest::~FXV8UnitTest() = default;
+ CFX_V8* cfx_v8() const { return cfx_v8_.get(); }
-void FXV8UnitTest::SetUp() {
- array_buffer_allocator_ = pdfium::MakeUnique<CFX_V8ArrayBufferAllocator>();
+ protected:
+ std::unique_ptr<CFX_V8> cfx_v8_;
+};
- v8::Isolate::CreateParams params;
- params.array_buffer_allocator = array_buffer_allocator_.get();
- isolate_.reset(v8::Isolate::New(params));
-
- cfx_v8_ = pdfium::MakeUnique<CFX_V8>(isolate_.get());
-}
-
-TEST_F(FXV8UnitTest, EmptyLocal) {
+TEST_F(CFXV8UnitTest, EmptyLocal) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(v8::Context::New(isolate()));
@@ -50,18 +54,18 @@
// Can't set properties on empty objects, but does not fault.
v8::Local<v8::Value> marker = cfx_v8()->NewNumber(2);
v8::Local<v8::Object> empty_object;
- EXPECT_FALSE(cfx_v8()->PutObjectProperty(empty_object, "clams", marker));
+ cfx_v8()->PutObjectProperty(empty_object, "clams", marker);
EXPECT_TRUE(cfx_v8()->GetObjectProperty(empty_object, "clams").IsEmpty());
EXPECT_EQ(0u, cfx_v8()->GetObjectPropertyNames(empty_object).size());
// Can't set elements in empty arrays, but does not fault.
v8::Local<v8::Array> empty_array;
- EXPECT_FALSE(cfx_v8()->PutArrayElement(empty_array, 0, marker));
+ cfx_v8()->PutArrayElement(empty_array, 0, marker);
EXPECT_TRUE(cfx_v8()->GetArrayElement(empty_array, 0).IsEmpty());
EXPECT_EQ(0u, cfx_v8()->GetArrayLength(empty_array));
}
-TEST_F(FXV8UnitTest, NewNull) {
+TEST_F(CFXV8UnitTest, NewNull) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(v8::Context::New(isolate()));
@@ -76,7 +80,7 @@
EXPECT_TRUE(cfx_v8()->ToArray(nullz).IsEmpty());
}
-TEST_F(FXV8UnitTest, NewUndefined) {
+TEST_F(CFXV8UnitTest, NewUndefined) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(v8::Context::New(isolate()));
@@ -84,14 +88,14 @@
auto undef = cfx_v8()->NewUndefined();
EXPECT_FALSE(cfx_v8()->ToBoolean(undef));
EXPECT_EQ(0, cfx_v8()->ToInt32(undef));
- EXPECT_TRUE(std::isnan(cfx_v8()->ToDouble(undef)));
+ EXPECT_TRUE(isnan(cfx_v8()->ToDouble(undef)));
EXPECT_EQ("undefined", cfx_v8()->ToByteString(undef));
EXPECT_EQ(L"undefined", cfx_v8()->ToWideString(undef));
EXPECT_TRUE(cfx_v8()->ToObject(undef).IsEmpty());
EXPECT_TRUE(cfx_v8()->ToArray(undef).IsEmpty());
}
-TEST_F(FXV8UnitTest, NewBoolean) {
+TEST_F(CFXV8UnitTest, NewBoolean) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(v8::Context::New(isolate()));
@@ -115,7 +119,7 @@
EXPECT_TRUE(cfx_v8()->ToArray(boolz).IsEmpty());
}
-TEST_F(FXV8UnitTest, NewNumber) {
+TEST_F(CFXV8UnitTest, NewNumber) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(v8::Context::New(isolate()));
@@ -130,7 +134,7 @@
EXPECT_TRUE(cfx_v8()->ToArray(num).IsEmpty());
}
-TEST_F(FXV8UnitTest, NewString) {
+TEST_F(CFXV8UnitTest, NewString) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(v8::Context::New(isolate()));
@@ -154,7 +158,7 @@
EXPECT_TRUE(cfx_v8()->ToArray(str2).IsEmpty());
}
-TEST_F(FXV8UnitTest, NewDate) {
+TEST_F(CFXV8UnitTest, NewDate) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(v8::Context::New(isolate()));
@@ -169,7 +173,7 @@
EXPECT_TRUE(cfx_v8()->ToArray(date).IsEmpty());
}
-TEST_F(FXV8UnitTest, NewArray) {
+TEST_F(CFXV8UnitTest, NewArray) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(v8::Context::New(isolate()));
@@ -180,7 +184,7 @@
EXPECT_TRUE(cfx_v8()->GetArrayElement(array, 2)->IsUndefined());
EXPECT_EQ(0u, cfx_v8()->GetArrayLength(array));
- EXPECT_TRUE(cfx_v8()->PutArrayElement(array, 3, cfx_v8()->NewNumber(12)));
+ cfx_v8()->PutArrayElement(array, 3, cfx_v8()->NewNumber(12));
EXPECT_FALSE(cfx_v8()->GetArrayElement(array, 2).IsEmpty());
EXPECT_TRUE(cfx_v8()->GetArrayElement(array, 2)->IsUndefined());
EXPECT_FALSE(cfx_v8()->GetArrayElement(array, 3).IsEmpty());
@@ -196,7 +200,7 @@
EXPECT_TRUE(cfx_v8()->ToArray(array)->IsArray());
}
-TEST_F(FXV8UnitTest, NewObject) {
+TEST_F(CFXV8UnitTest, NewObject) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(v8::Context::New(isolate()));
@@ -208,8 +212,7 @@
EXPECT_TRUE(cfx_v8()->GetObjectProperty(object, "clams")->IsUndefined());
EXPECT_EQ(0u, cfx_v8()->GetObjectPropertyNames(object).size());
- EXPECT_TRUE(
- cfx_v8()->PutObjectProperty(object, "clams", cfx_v8()->NewNumber(12)));
+ cfx_v8()->PutObjectProperty(object, "clams", cfx_v8()->NewNumber(12));
EXPECT_FALSE(cfx_v8()->GetObjectProperty(object, "clams").IsEmpty());
EXPECT_TRUE(cfx_v8()->GetObjectProperty(object, "clams")->IsNumber());
EXPECT_EQ(1u, cfx_v8()->GetObjectPropertyNames(object).size());
@@ -224,7 +227,7 @@
EXPECT_TRUE(cfx_v8()->ToArray(object).IsEmpty());
}
-TEST_F(FXV8UnitTest, ThrowFromGetter) {
+TEST_F(CFXV8UnitTest, ThrowFromGetter) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Context> context = v8::Context::New(isolate());
@@ -246,7 +249,7 @@
EXPECT_TRUE(getter_sentinel);
}
-TEST_F(FXV8UnitTest, ThrowFromSetter) {
+TEST_F(CFXV8UnitTest, ThrowFromSetter) {
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Context> context = v8::Context::New(isolate());
@@ -264,6 +267,6 @@
})
.FromJust());
setter_sentinel = false;
- EXPECT_FALSE(cfx_v8()->PutObjectProperty(object, "clams", name));
+ cfx_v8()->PutObjectProperty(object, "clams", name);
EXPECT_TRUE(setter_sentinel);
}
diff --git a/fxjs/cfx_v8_unittest.h b/fxjs/cfx_v8_unittest.h
deleted file mode 100644
index e5d4e3f..0000000
--- a/fxjs/cfx_v8_unittest.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef FXJS_CFX_V8_UNITTEST_H_
-#define FXJS_CFX_V8_UNITTEST_H_
-
-#include <memory>
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-class CFX_V8;
-class CFX_V8ArrayBufferAllocator;
-
-namespace v8 {
-class Isolate;
-} // namespace v8
-
-class FXV8UnitTest : public ::testing::Test {
- public:
- struct V8IsolateDeleter {
- void operator()(v8::Isolate* ptr) const;
- };
-
- FXV8UnitTest();
- ~FXV8UnitTest() override;
-
- void SetUp() override;
-
- v8::Isolate* isolate() const { return isolate_.get(); }
- CFX_V8* cfx_v8() const { return cfx_v8_.get(); }
-
- protected:
- std::unique_ptr<CFX_V8ArrayBufferAllocator> array_buffer_allocator_;
- std::unique_ptr<v8::Isolate, V8IsolateDeleter> isolate_;
- std::unique_ptr<CFX_V8> cfx_v8_;
-};
-
-#endif // FXJS_CFX_V8_UNITTEST_H_
diff --git a/fxjs/cfxjs_engine.cpp b/fxjs/cfxjs_engine.cpp
index c4d46a2..35653c9 100644
--- a/fxjs/cfxjs_engine.cpp
+++ b/fxjs/cfxjs_engine.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,17 +8,23 @@
#include <memory>
#include <utility>
-#include <vector>
+#include "core/fxcrt/stl_util.h"
#include "core/fxcrt/unowned_ptr.h"
+#include "fxjs/cfx_v8_array_buffer_allocator.h"
#include "fxjs/cjs_object.h"
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_runtimedata.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
+#include "third_party/base/check.h"
+#include "third_party/base/check_op.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-exception.h"
+#include "v8/include/v8-isolate.h"
+#include "v8/include/v8-message.h"
+#include "v8/include/v8-primitive.h"
+#include "v8/include/v8-script.h"
#include "v8/include/v8-util.h"
-class CFXJS_PerObjectData;
-
namespace {
unsigned int g_embedderDataSlot = 1u;
@@ -26,7 +32,14 @@
size_t g_isolate_ref_count = 0;
CFX_V8ArrayBufferAllocator* g_arrayBufferAllocator = nullptr;
v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr;
+
+// Only the address matters, values are for humans debugging. ASLR should
+// ensure that these values are unlikely to arise otherwise. Keep these
+// wchar_t to prevent the compiler from doing something clever, like
+// aligning them on a byte boundary to save space, which would make them
+// incompatible for use as V8 aligned pointers.
const wchar_t kPerObjectDataTag[] = L"CFXJS_PerObjectData";
+const wchar_t kPerIsolateDataTag[] = L"FXJS_PerIsolateData";
void* GetAlignedPointerForPerObjectDataTag() {
return const_cast<void*>(static_cast<const void*>(kPerObjectDataTag));
@@ -42,6 +55,41 @@
} // namespace
+class CFXJS_PerObjectData {
+ public:
+ ~CFXJS_PerObjectData() = default;
+
+ static void SetNewDataInObject(uint32_t nObjDefnID,
+ v8::Local<v8::Object> pObj) {
+ if (pObj->InternalFieldCount() == 2) {
+ pObj->SetAlignedPointerInInternalField(
+ 0, GetAlignedPointerForPerObjectDataTag());
+ pObj->SetAlignedPointerInInternalField(
+ 1, new CFXJS_PerObjectData(nObjDefnID));
+ }
+ }
+
+ static CFXJS_PerObjectData* GetFromObject(v8::Local<v8::Object> pObj) {
+ if (pObj.IsEmpty() || pObj->InternalFieldCount() != 2 ||
+ pObj->GetAlignedPointerFromInternalField(0) !=
+ GetAlignedPointerForPerObjectDataTag()) {
+ return nullptr;
+ }
+ return static_cast<CFXJS_PerObjectData*>(
+ pObj->GetAlignedPointerFromInternalField(1));
+ }
+
+ uint32_t GetObjDefnID() const { return m_ObjDefnID; }
+ CJS_Object* GetPrivate() { return m_pPrivate.get(); }
+ void SetPrivate(std::unique_ptr<CJS_Object> p) { m_pPrivate = std::move(p); }
+
+ private:
+ explicit CFXJS_PerObjectData(uint32_t nObjDefnID) : m_ObjDefnID(nObjDefnID) {}
+
+ const uint32_t m_ObjDefnID;
+ std::unique_ptr<CJS_Object> m_pPrivate;
+};
+
// Global weak map to save dynamic objects.
class V8TemplateMapTraits final
: public v8::StdMapTraits<CFXJS_PerObjectData*, v8::Object> {
@@ -84,8 +132,9 @@
explicit V8TemplateMap(v8::Isolate* isolate) : m_map(isolate) {}
~V8TemplateMap() = default;
- void SetAndMakeWeak(WeakCallbackDataType* key, v8::Local<v8::Object> handle) {
- ASSERT(!m_map.Contains(key));
+ void SetAndMakeWeak(v8::Local<v8::Object> handle) {
+ WeakCallbackDataType* key = CFXJS_PerObjectData::GetFromObject(handle);
+ DCHECK(!m_map.Contains(key));
// Inserting an object into a GlobalValueMap with the appropriate traits
// has the side-effect of making the object weak deep in the guts of V8,
@@ -93,41 +142,12 @@
m_map.Set(key, handle);
}
- friend class V8TemplateMapTraits;
+ MapType* GetMap() { return &m_map; }
private:
MapType m_map;
};
-class CFXJS_PerObjectData {
- public:
- explicit CFXJS_PerObjectData(int nObjDefID) : m_ObjDefID(nObjDefID) {}
-
- ~CFXJS_PerObjectData() = default;
-
- static void SetInObject(CFXJS_PerObjectData* pData,
- v8::Local<v8::Object> pObj) {
- if (pObj->InternalFieldCount() == 2) {
- pObj->SetAlignedPointerInInternalField(
- 0, GetAlignedPointerForPerObjectDataTag());
- pObj->SetAlignedPointerInInternalField(1, pData);
- }
- }
-
- static CFXJS_PerObjectData* GetFromObject(v8::Local<v8::Object> pObj) {
- if (pObj.IsEmpty() || pObj->InternalFieldCount() != 2 ||
- pObj->GetAlignedPointerFromInternalField(0) !=
- GetAlignedPointerForPerObjectDataTag()) {
- return nullptr;
- }
- return static_cast<CFXJS_PerObjectData*>(
- pObj->GetAlignedPointerFromInternalField(1));
- }
-
- const int m_ObjDefID;
- std::unique_ptr<CJS_Object> m_pPrivate;
-};
-
class CFXJS_ObjDefinition {
public:
CFXJS_ObjDefinition(v8::Isolate* isolate,
@@ -142,42 +162,37 @@
m_pIsolate(isolate) {
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
- v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate);
- fun->InstanceTemplate()->SetInternalFieldCount(2);
- fun->SetCallHandler(CallHandler, v8::Number::New(isolate, eObjType));
+ v8::Local<v8::FunctionTemplate> fn = v8::FunctionTemplate::New(isolate);
+ fn->InstanceTemplate()->SetInternalFieldCount(2);
+ fn->InstanceTemplate()->SetImmutableProto();
+ fn->SetCallHandler(CallHandler, v8::Number::New(isolate, eObjType));
if (eObjType == FXJSOBJTYPE_GLOBAL) {
- fun->InstanceTemplate()->Set(
- v8::Symbol::GetToStringTag(isolate),
- v8::String::NewFromUtf8(isolate, "global", v8::NewStringType::kNormal)
- .ToLocalChecked());
+ fn->InstanceTemplate()->Set(v8::Symbol::GetToStringTag(isolate),
+ fxv8::NewStringHelper(isolate, "global"));
}
- m_FunctionTemplate.Reset(isolate, fun);
- m_Signature.Reset(isolate, v8::Signature::New(isolate, fun));
+ m_FunctionTemplate.Reset(isolate, fn);
+ m_Signature.Reset(isolate, v8::Signature::New(isolate, fn));
}
static void CallHandler(const v8::FunctionCallbackInfo<v8::Value>& info) {
v8::Isolate* isolate = info.GetIsolate();
if (!info.IsConstructCall()) {
- isolate->ThrowException(
- v8::String::NewFromUtf8(isolate, "illegal constructor",
- v8::NewStringType::kNormal)
- .ToLocalChecked());
+ fxv8::ThrowExceptionHelper(isolate, "illegal constructor");
return;
}
if (info.Data().As<v8::Int32>()->Value() != FXJSOBJTYPE_DYNAMIC) {
- isolate->ThrowException(
- v8::String::NewFromUtf8(isolate, "not a dynamic object",
- v8::NewStringType::kNormal)
- .ToLocalChecked());
+ fxv8::ThrowExceptionHelper(isolate, "not a dynamic object");
return;
}
v8::Local<v8::Object> holder = info.Holder();
- ASSERT(holder->InternalFieldCount() == 2);
+ DCHECK_EQ(holder->InternalFieldCount(), 2);
holder->SetAlignedPointerInInternalField(0, nullptr);
holder->SetAlignedPointerInInternalField(1, nullptr);
}
- v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); }
+ FXJSOBJTYPE GetObjType() const { return m_ObjType; }
+ const char* GetObjName() const { return m_ObjName; }
+ v8::Isolate* GetIsolate() const { return m_pIsolate; }
void DefineConst(const char* sConstName, v8::Local<v8::Value> pDefault) {
GetInstanceTemplate()->Set(GetIsolate(), sConstName, pDefault);
@@ -197,12 +212,14 @@
GetInstanceTemplate()->Set(sMethodName, fun, v8::ReadOnly);
}
- void DefineAllProperties(v8::GenericNamedPropertyQueryCallback pPropQurey,
- v8::GenericNamedPropertyGetterCallback pPropGet,
- v8::GenericNamedPropertySetterCallback pPropPut,
- v8::GenericNamedPropertyDeleterCallback pPropDel) {
+ void DefineAllProperties(
+ v8::GenericNamedPropertyQueryCallback pPropQurey,
+ v8::GenericNamedPropertyGetterCallback pPropGet,
+ v8::GenericNamedPropertySetterCallback pPropPut,
+ v8::GenericNamedPropertyDeleterCallback pPropDel,
+ v8::GenericNamedPropertyEnumeratorCallback pPropEnum) {
GetInstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
- pPropGet, pPropPut, pPropQurey, pPropDel, nullptr,
+ pPropGet, pPropPut, pPropQurey, pPropDel, pPropEnum,
v8::Local<v8::Value>(),
v8::PropertyHandlerFlags::kOnlyInterceptStrings));
}
@@ -219,7 +236,20 @@
return scope.Escape(m_Signature.Get(GetIsolate()));
}
- const char* const m_ObjName;
+ void RunConstructor(CFXJS_Engine* pEngine,
+ v8::Local<v8::Object> obj,
+ v8::Local<v8::Object> proxy) {
+ if (m_pConstructor)
+ m_pConstructor(pEngine, obj, proxy);
+ }
+
+ void RunDestructor(v8::Local<v8::Object> obj) {
+ if (m_pDestructor)
+ m_pDestructor(obj);
+ }
+
+ private:
+ UnownedPtr<const char> const m_ObjName;
const FXJSOBJTYPE m_ObjType;
const CFXJS_Engine::Constructor m_pConstructor;
const CFXJS_Engine::Destructor m_pDestructor;
@@ -231,18 +261,16 @@
static v8::Local<v8::ObjectTemplate> GetGlobalObjectTemplate(
v8::Isolate* pIsolate) {
FXJS_PerIsolateData* pIsolateData = FXJS_PerIsolateData::Get(pIsolate);
- for (int i = 0; i < pIsolateData->MaxObjDefinitionID(); ++i) {
+ for (uint32_t i = 1; i <= pIsolateData->CurrentMaxObjDefinitionID(); ++i) {
CFXJS_ObjDefinition* pObjDef = pIsolateData->ObjDefinitionForID(i);
- if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL)
+ if (pObjDef->GetObjType() == FXJSOBJTYPE_GLOBAL)
return pObjDef->GetInstanceTemplate();
}
if (!g_DefaultGlobalObjectTemplate) {
v8::Local<v8::ObjectTemplate> hGlobalTemplate =
v8::ObjectTemplate::New(pIsolate);
- hGlobalTemplate->Set(
- v8::Symbol::GetToStringTag(pIsolate),
- v8::String::NewFromUtf8(pIsolate, "global", v8::NewStringType::kNormal)
- .ToLocalChecked());
+ hGlobalTemplate->Set(v8::Symbol::GetToStringTag(pIsolate),
+ fxv8::NewStringHelper(pIsolate, "global"));
g_DefaultGlobalObjectTemplate =
new v8::Global<v8::ObjectTemplate>(pIsolate, hGlobalTemplate);
}
@@ -255,15 +283,14 @@
v8::Local<v8::Object> obj = value.Get(isolate);
if (obj.IsEmpty())
return;
- int id = CFXJS_Engine::GetObjDefnID(obj);
- if (id == -1)
+ uint32_t id = CFXJS_Engine::GetObjDefnID(obj);
+ if (id == 0)
return;
FXJS_PerIsolateData* pIsolateData = FXJS_PerIsolateData::Get(isolate);
CFXJS_ObjDefinition* pObjDef = pIsolateData->ObjDefinitionForID(id);
if (!pObjDef)
return;
- if (pObjDef->m_pDestructor)
- pObjDef->m_pDestructor(obj);
+ pObjDef->RunDestructor(obj);
CFXJS_Engine::FreeObjectPrivate(obj);
}
@@ -273,16 +300,16 @@
}
V8TemplateMapTraits::MapType* V8TemplateMapTraits::MapFromWeakCallbackInfo(
- const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {
- V8TemplateMap* pMap =
- FXJS_PerIsolateData::Get(data.GetIsolate())->m_pDynamicObjsMap.get();
- return pMap ? &pMap->m_map : nullptr;
+ const v8::WeakCallbackInfo<WeakCallbackDataType>& info) {
+ auto* pIsolateData = FXJS_PerIsolateData::Get(info.GetIsolate());
+ V8TemplateMap* pObjsMap = pIsolateData->GetDynamicObjsMap();
+ return pObjsMap ? pObjsMap->GetMap() : nullptr;
}
void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate) {
if (g_isolate) {
- ASSERT(g_embedderDataSlot == embedderDataSlot);
- ASSERT(g_isolate == pIsolate);
+ DCHECK_EQ(g_embedderDataSlot, embedderDataSlot);
+ DCHECK_EQ(g_isolate, pIsolate);
return;
}
g_embedderDataSlot = embedderDataSlot;
@@ -290,7 +317,7 @@
}
void FXJS_Release() {
- ASSERT(!g_isolate || g_isolate_ref_count == 0);
+ DCHECK(!g_isolate || g_isolate_ref_count == 0);
delete g_DefaultGlobalObjectTemplate;
g_DefaultGlobalObjectTemplate = nullptr;
g_isolate = nullptr;
@@ -317,8 +344,6 @@
return g_isolate_ref_count;
}
-FXJS_PerIsolateData::~FXJS_PerIsolateData() {}
-
// static
void FXJS_PerIsolateData::SetUp(v8::Isolate* pIsolate) {
if (!pIsolate->GetData(g_embedderDataSlot))
@@ -327,26 +352,33 @@
// static
FXJS_PerIsolateData* FXJS_PerIsolateData::Get(v8::Isolate* pIsolate) {
- return static_cast<FXJS_PerIsolateData*>(
- pIsolate->GetData(g_embedderDataSlot));
-}
-
-int FXJS_PerIsolateData::MaxObjDefinitionID() const {
- return pdfium::CollectionSize<int>(m_ObjectDefnArray);
+ auto* result =
+ static_cast<FXJS_PerIsolateData*>(pIsolate->GetData(g_embedderDataSlot));
+ CHECK(result->m_Tag == kPerIsolateDataTag);
+ return result;
}
FXJS_PerIsolateData::FXJS_PerIsolateData(v8::Isolate* pIsolate)
- : m_pDynamicObjsMap(new V8TemplateMap(pIsolate)) {}
+ : m_Tag(kPerIsolateDataTag),
+ m_pDynamicObjsMap(std::make_unique<V8TemplateMap>(pIsolate)) {}
-CFXJS_ObjDefinition* FXJS_PerIsolateData::ObjDefinitionForID(int id) const {
- return (id >= 0 && id < MaxObjDefinitionID()) ? m_ObjectDefnArray[id].get()
- : nullptr;
+FXJS_PerIsolateData::~FXJS_PerIsolateData() = default;
+
+uint32_t FXJS_PerIsolateData::CurrentMaxObjDefinitionID() const {
+ return fxcrt::CollectionSize<uint32_t>(m_ObjectDefnArray);
}
-int FXJS_PerIsolateData::AssignIDForObjDefinition(
+CFXJS_ObjDefinition* FXJS_PerIsolateData::ObjDefinitionForID(
+ uint32_t id) const {
+ return id > 0 && id <= CurrentMaxObjDefinitionID()
+ ? m_ObjectDefnArray[id - 1].get()
+ : nullptr;
+}
+
+uint32_t FXJS_PerIsolateData::AssignIDForObjDefinition(
std::unique_ptr<CFXJS_ObjDefinition> pDefn) {
m_ObjectDefnArray.push_back(std::move(pDefn));
- return m_ObjectDefnArray.size() - 1;
+ return CurrentMaxObjDefinitionID();
}
CFXJS_Engine::CFXJS_Engine() : CFX_V8(nullptr) {}
@@ -356,9 +388,9 @@
CFXJS_Engine::~CFXJS_Engine() = default;
// static
-int CFXJS_Engine::GetObjDefnID(v8::Local<v8::Object> pObj) {
+uint32_t CFXJS_Engine::GetObjDefnID(v8::Local<v8::Object> pObj) {
CFXJS_PerObjectData* pData = CFXJS_PerObjectData::GetFromObject(pObj);
- return pData ? pData->m_ObjDefID : -1;
+ return pData ? pData->GetObjDefnID() : 0;
}
// static
@@ -366,9 +398,8 @@
std::unique_ptr<CJS_Object> p) {
CFXJS_PerObjectData* pPerObjectData =
CFXJS_PerObjectData::GetFromObject(pObj);
- if (!pPerObjectData)
- return;
- pPerObjectData->m_pPrivate = std::move(p);
+ if (pPerObjectData)
+ pPerObjectData->SetPrivate(std::move(p));
}
// static
@@ -379,20 +410,20 @@
delete pData;
}
-int CFXJS_Engine::DefineObj(const char* sObjName,
- FXJSOBJTYPE eObjType,
- CFXJS_Engine::Constructor pConstructor,
- CFXJS_Engine::Destructor pDestructor) {
+uint32_t CFXJS_Engine::DefineObj(const char* sObjName,
+ FXJSOBJTYPE eObjType,
+ CFXJS_Engine::Constructor pConstructor,
+ CFXJS_Engine::Destructor pDestructor) {
v8::Isolate::Scope isolate_scope(GetIsolate());
v8::HandleScope handle_scope(GetIsolate());
FXJS_PerIsolateData::SetUp(GetIsolate());
FXJS_PerIsolateData* pIsolateData = FXJS_PerIsolateData::Get(GetIsolate());
return pIsolateData->AssignIDForObjDefinition(
- pdfium::MakeUnique<CFXJS_ObjDefinition>(GetIsolate(), sObjName, eObjType,
- pConstructor, pDestructor));
+ std::make_unique<CFXJS_ObjDefinition>(GetIsolate(), sObjName, eObjType,
+ pConstructor, pDestructor));
}
-void CFXJS_Engine::DefineObjMethod(int nObjDefnID,
+void CFXJS_Engine::DefineObjMethod(uint32_t nObjDefnID,
const char* sMethodName,
v8::FunctionCallback pMethodCall) {
v8::Isolate::Scope isolate_scope(GetIsolate());
@@ -402,7 +433,7 @@
pObjDef->DefineMethod(NewString(sMethodName), pMethodCall);
}
-void CFXJS_Engine::DefineObjProperty(int nObjDefnID,
+void CFXJS_Engine::DefineObjProperty(uint32_t nObjDefnID,
const char* sPropName,
v8::AccessorGetterCallback pPropGet,
v8::AccessorSetterCallback pPropPut) {
@@ -414,19 +445,21 @@
}
void CFXJS_Engine::DefineObjAllProperties(
- int nObjDefnID,
+ uint32_t nObjDefnID,
v8::GenericNamedPropertyQueryCallback pPropQurey,
v8::GenericNamedPropertyGetterCallback pPropGet,
v8::GenericNamedPropertySetterCallback pPropPut,
- v8::GenericNamedPropertyDeleterCallback pPropDel) {
+ v8::GenericNamedPropertyDeleterCallback pPropDel,
+ v8::GenericNamedPropertyEnumeratorCallback pPropEnum) {
v8::Isolate::Scope isolate_scope(GetIsolate());
v8::HandleScope handle_scope(GetIsolate());
FXJS_PerIsolateData* pIsolateData = FXJS_PerIsolateData::Get(GetIsolate());
CFXJS_ObjDefinition* pObjDef = pIsolateData->ObjDefinitionForID(nObjDefnID);
- pObjDef->DefineAllProperties(pPropQurey, pPropGet, pPropPut, pPropDel);
+ pObjDef->DefineAllProperties(pPropQurey, pPropGet, pPropPut, pPropDel,
+ pPropEnum);
}
-void CFXJS_Engine::DefineObjConst(int nObjDefnID,
+void CFXJS_Engine::DefineObjConst(uint32_t nObjDefnID,
const char* sConstName,
v8::Local<v8::Value> pDefault) {
v8::Isolate::Scope isolate_scope(GetIsolate());
@@ -486,24 +519,15 @@
v8::Context::Scope context_scope(v8Context);
FXJS_PerIsolateData* pIsolateData = FXJS_PerIsolateData::Get(GetIsolate());
- int maxID = pIsolateData->MaxObjDefinitionID();
+ uint32_t maxID = pIsolateData->CurrentMaxObjDefinitionID();
m_StaticObjects.resize(maxID + 1);
- for (int i = 0; i < maxID; ++i) {
+ for (uint32_t i = 1; i <= maxID; ++i) {
CFXJS_ObjDefinition* pObjDef = pIsolateData->ObjDefinitionForID(i);
- if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) {
- CFXJS_PerObjectData::SetInObject(new CFXJS_PerObjectData(i),
- v8Context->Global()
- ->GetPrototype()
- ->ToObject(v8Context)
- .ToLocalChecked());
- if (pObjDef->m_pConstructor) {
- pObjDef->m_pConstructor(this, v8Context->Global()
- ->GetPrototype()
- ->ToObject(v8Context)
- .ToLocalChecked());
- }
- } else if (pObjDef->m_ObjType == FXJSOBJTYPE_STATIC) {
- v8::Local<v8::String> pObjName = NewString(pObjDef->m_ObjName);
+ if (pObjDef->GetObjType() == FXJSOBJTYPE_GLOBAL) {
+ CFXJS_PerObjectData::SetNewDataInObject(i, pThis);
+ pObjDef->RunConstructor(this, pThis, pThisProxy);
+ } else if (pObjDef->GetObjType() == FXJSOBJTYPE_STATIC) {
+ v8::Local<v8::String> pObjName = NewString(pObjDef->GetObjName());
v8::Local<v8::Object> obj = NewFXJSBoundObject(i, FXJSOBJTYPE_STATIC);
if (!obj.IsEmpty()) {
v8Context->Global()->Set(v8Context, pObjName, obj).FromJust();
@@ -525,10 +549,10 @@
m_ConstArrays.clear();
- for (int i = 0; i < pIsolateData->MaxObjDefinitionID(); ++i) {
+ for (uint32_t i = 1; i <= pIsolateData->CurrentMaxObjDefinitionID(); ++i) {
CFXJS_ObjDefinition* pObjDef = pIsolateData->ObjDefinitionForID(i);
v8::Local<v8::Object> pObj;
- if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) {
+ if (pObjDef->GetObjType() == FXJSOBJTYPE_GLOBAL) {
pObj =
context->Global()->GetPrototype()->ToObject(context).ToLocalChecked();
} else if (!m_StaticObjects[i].IsEmpty()) {
@@ -536,8 +560,7 @@
m_StaticObjects[i].Reset();
}
if (!pObj.IsEmpty()) {
- if (pObjDef->m_pDestructor)
- pObjDef->m_pDestructor(pObj);
+ pObjDef->RunDestructor(pObj);
FreeObjectPrivate(pObj);
}
}
@@ -551,7 +574,7 @@
GetIsolate()->SetData(g_embedderDataSlot, nullptr);
}
-Optional<IJS_Runtime::JS_Error> CFXJS_Engine::Execute(
+absl::optional<IJS_Runtime::JS_Error> CFXJS_Engine::Execute(
const WideString& script) {
v8::Isolate::Scope isolate_scope(GetIsolate());
v8::TryCatch try_catch(GetIsolate());
@@ -576,10 +599,10 @@
std::tie(line, column) = GetLineAndColumnFromError(msg, context);
return IJS_Runtime::JS_Error(line, column, WideString::FromUTF8(*error));
}
- return pdfium::nullopt;
+ return absl::nullopt;
}
-v8::Local<v8::Object> CFXJS_Engine::NewFXJSBoundObject(int nObjDefnID,
+v8::Local<v8::Object> CFXJS_Engine::NewFXJSBoundObject(uint32_t nObjDefnID,
FXJSOBJTYPE type) {
v8::Isolate::Scope isolate_scope(GetIsolate());
v8::Local<v8::Context> context = GetIsolate()->GetCurrentContext();
@@ -595,15 +618,13 @@
if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj))
return v8::Local<v8::Object>();
- CFXJS_PerObjectData* pObjData = new CFXJS_PerObjectData(nObjDefnID);
- CFXJS_PerObjectData::SetInObject(pObjData, obj);
- if (pObjDef->m_pConstructor)
- pObjDef->m_pConstructor(this, obj);
-
+ CFXJS_PerObjectData::SetNewDataInObject(nObjDefnID, obj);
+ pObjDef->RunConstructor(this, obj, obj);
if (type == FXJSOBJTYPE_DYNAMIC) {
auto* pIsolateData = FXJS_PerIsolateData::Get(GetIsolate());
- if (pIsolateData->m_pDynamicObjsMap)
- pIsolateData->m_pDynamicObjsMap->SetAndMakeWeak(pObjData, obj);
+ V8TemplateMap* pObjsMap = pIsolateData->GetDynamicObjsMap();
+ if (pObjsMap)
+ pObjsMap->SetAndMakeWeak(obj);
}
return obj;
}
@@ -619,7 +640,7 @@
}
void CFXJS_Engine::Error(const WideString& message) {
- GetIsolate()->ThrowException(NewString(message.AsStringView()));
+ fxv8::ThrowExceptionHelper(GetIsolate(), message.AsStringView());
}
v8::Local<v8::Context> CFXJS_Engine::GetV8Context() {
@@ -627,10 +648,11 @@
}
// static
-CJS_Object* CFXJS_Engine::GetObjectPrivate(v8::Local<v8::Object> pObj) {
+CJS_Object* CFXJS_Engine::GetObjectPrivate(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj) {
auto* pData = CFXJS_PerObjectData::GetFromObject(pObj);
if (pData)
- return pData->m_pPrivate.get();
+ return pData->GetPrivate();
if (pObj.IsEmpty())
return nullptr;
@@ -645,16 +667,16 @@
if (!pProtoData)
return nullptr;
- auto* pIsolateData = FXJS_PerIsolateData::Get(v8::Isolate::GetCurrent());
+ auto* pIsolateData = FXJS_PerIsolateData::Get(pIsolate);
if (!pIsolateData)
return nullptr;
CFXJS_ObjDefinition* pObjDef =
- pIsolateData->ObjDefinitionForID(pProtoData->m_ObjDefID);
- if (!pObjDef || pObjDef->m_ObjType != FXJSOBJTYPE_GLOBAL)
+ pIsolateData->ObjDefinitionForID(pProtoData->GetObjDefnID());
+ if (!pObjDef || pObjDef->GetObjType() != FXJSOBJTYPE_GLOBAL)
return nullptr;
- return pProtoData->m_pPrivate.get();
+ return pProtoData->GetPrivate();
}
v8::Local<v8::Array> CFXJS_Engine::GetConstArray(const WideString& name) {
diff --git a/fxjs/cfxjs_engine.h b/fxjs/cfxjs_engine.h
index 933c250..b0011fc 100644
--- a/fxjs/cfxjs_engine.h
+++ b/fxjs/cfxjs_engine.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -17,21 +17,21 @@
#include <functional>
#include <map>
#include <memory>
+#include <utility>
#include <vector>
-#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/widestring.h"
#include "fxjs/cfx_v8.h"
#include "fxjs/ijs_runtime.h"
-#include "v8/include/v8.h"
+#include "v8/include/v8-forward.h"
+#include "v8/include/v8-function-callback.h"
+#include "v8/include/v8-persistent-handle.h"
+#include "v8/include/v8-template.h"
class CFXJS_ObjDefinition;
class CJS_Object;
class V8TemplateMap;
-// CFXJS_ENGINE places no restrictions on this class; it merely passes it
-// on to caller-provided methods.
-class IJS_EventContext; // A description of the event that caused JS execution.
-
enum FXJSOBJTYPE {
FXJSOBJTYPE_DYNAMIC = 0, // Created by native method and returned to JS.
FXJSOBJTYPE_STATIC, // Created by init and hung off of global object.
@@ -51,16 +51,22 @@
static void SetUp(v8::Isolate* pIsolate);
static FXJS_PerIsolateData* Get(v8::Isolate* pIsolate);
- int MaxObjDefinitionID() const;
- CFXJS_ObjDefinition* ObjDefinitionForID(int id) const;
- int AssignIDForObjDefinition(std::unique_ptr<CFXJS_ObjDefinition> pDefn);
+ uint32_t CurrentMaxObjDefinitionID() const;
+ CFXJS_ObjDefinition* ObjDefinitionForID(uint32_t id) const;
+ uint32_t AssignIDForObjDefinition(std::unique_ptr<CFXJS_ObjDefinition> pDefn);
+ V8TemplateMap* GetDynamicObjsMap() { return m_pDynamicObjsMap.get(); }
+ ExtensionIface* GetExtension() { return m_pExtension.get(); }
+ void SetExtension(std::unique_ptr<ExtensionIface> extension) {
+ m_pExtension = std::move(extension);
+ }
+ private:
+ explicit FXJS_PerIsolateData(v8::Isolate* pIsolate);
+
+ const wchar_t* const m_Tag; // Raw, always a literal.
std::vector<std::unique_ptr<CFXJS_ObjDefinition>> m_ObjectDefnArray;
std::unique_ptr<V8TemplateMap> m_pDynamicObjsMap;
- std::unique_ptr<ExtensionIface> m_pFXJSERuntimeData;
-
- protected:
- explicit FXJS_PerIsolateData(v8::Isolate* pIsolate);
+ std::unique_ptr<ExtensionIface> m_pExtension;
};
void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate);
@@ -79,35 +85,39 @@
explicit CFXJS_Engine(v8::Isolate* pIsolate);
~CFXJS_Engine() override;
- using Constructor =
- std::function<void(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj)>;
+ using Constructor = std::function<void(CFXJS_Engine* pEngine,
+ v8::Local<v8::Object> obj,
+ v8::Local<v8::Object> proxy)>;
using Destructor = std::function<void(v8::Local<v8::Object> obj)>;
- static int GetObjDefnID(v8::Local<v8::Object> pObj);
- static CJS_Object* GetObjectPrivate(v8::Local<v8::Object> pObj);
+ static uint32_t GetObjDefnID(v8::Local<v8::Object> pObj);
+ static CJS_Object* GetObjectPrivate(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj);
static void SetObjectPrivate(v8::Local<v8::Object> pObj,
std::unique_ptr<CJS_Object> p);
static void FreeObjectPrivate(v8::Local<v8::Object> pObj);
- // Always returns a valid, newly-created objDefnID.
- int DefineObj(const char* sObjName,
- FXJSOBJTYPE eObjType,
- Constructor pConstructor,
- Destructor pDestructor);
+ // Always returns a valid (i.e. non-zero), newly-created objDefnID.
+ uint32_t DefineObj(const char* sObjName,
+ FXJSOBJTYPE eObjType,
+ Constructor pConstructor,
+ Destructor pDestructor);
- void DefineObjMethod(int nObjDefnID,
+ void DefineObjMethod(uint32_t nObjDefnID,
const char* sMethodName,
v8::FunctionCallback pMethodCall);
- void DefineObjProperty(int nObjDefnID,
+ void DefineObjProperty(uint32_t nObjDefnID,
const char* sPropName,
v8::AccessorGetterCallback pPropGet,
v8::AccessorSetterCallback pPropPut);
- void DefineObjAllProperties(int nObjDefnID,
- v8::GenericNamedPropertyQueryCallback pPropQurey,
- v8::GenericNamedPropertyGetterCallback pPropGet,
- v8::GenericNamedPropertySetterCallback pPropPut,
- v8::GenericNamedPropertyDeleterCallback pPropDel);
- void DefineObjConst(int nObjDefnID,
+ void DefineObjAllProperties(
+ uint32_t nObjDefnID,
+ v8::GenericNamedPropertyQueryCallback pPropQurey,
+ v8::GenericNamedPropertyGetterCallback pPropGet,
+ v8::GenericNamedPropertySetterCallback pPropPut,
+ v8::GenericNamedPropertyDeleterCallback pPropDel,
+ v8::GenericNamedPropertyEnumeratorCallback pPropEnum);
+ void DefineObjConst(uint32_t nObjDefnID,
const char* sConstName,
v8::Local<v8::Value> pDefault);
void DefineGlobalMethod(const char* sMethodName,
@@ -120,10 +130,11 @@
void ReleaseEngine();
// Called after FXJS_InitializeEngine call made.
- Optional<IJS_Runtime::JS_Error> Execute(const WideString& script);
+ absl::optional<IJS_Runtime::JS_Error> Execute(const WideString& script);
v8::Local<v8::Object> GetThisObj();
- v8::Local<v8::Object> NewFXJSBoundObject(int nObjDefnID, FXJSOBJTYPE type);
+ v8::Local<v8::Object> NewFXJSBoundObject(uint32_t nObjDefnID,
+ FXJSOBJTYPE type);
void Error(const WideString& message);
v8::Local<v8::Context> GetV8Context();
diff --git a/fxjs/cfxjs_engine_embeddertest.cpp b/fxjs/cfxjs_engine_embeddertest.cpp
index c18171e..70e84ab 100644
--- a/fxjs/cfxjs_engine_embeddertest.cpp
+++ b/fxjs/cfxjs_engine_embeddertest.cpp
@@ -1,11 +1,16 @@
-// Copyright 2015 PDFium Authors. All rights reserved.
+// Copyright 2015 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fxjs/cfxjs_engine.h"
+#include "testing/external_engine_embedder_test.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/js_embedder_test.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-isolate.h"
+#include "v8/include/v8-local-handle.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-value.h"
namespace {
@@ -19,7 +24,7 @@
} // namespace
-using CFXJSEngineEmbedderTest = JSEmbedderTest;
+class CFXJSEngineEmbedderTest : public ExternalEngineEmbedderTest {};
void CheckAssignmentInEngineContext(CFXJS_Engine* current_engine,
double expected) {
@@ -35,7 +40,8 @@
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(GetV8Context());
- Optional<IJS_Runtime::JS_Error> err = engine()->Execute(WideString(kScript1));
+ absl::optional<IJS_Runtime::JS_Error> err =
+ engine()->Execute(WideString(kScript1));
EXPECT_FALSE(err);
CheckAssignmentInEngineContext(engine(), kExpected1);
}
@@ -52,7 +58,7 @@
v8::Context::Scope context_scope(GetV8Context());
{
- Optional<IJS_Runtime::JS_Error> err =
+ absl::optional<IJS_Runtime::JS_Error> err =
engine()->Execute(WideString(kScript0));
EXPECT_FALSE(err);
CheckAssignmentInEngineContext(engine(), kExpected0);
@@ -60,7 +66,8 @@
{
// engine1 executing in engine1's context doesn't affect main.
v8::Context::Scope context_scope1(engine1.GetV8Context());
- Optional<IJS_Runtime::JS_Error> err = engine1.Execute(WideString(kScript1));
+ absl::optional<IJS_Runtime::JS_Error> err =
+ engine1.Execute(WideString(kScript1));
EXPECT_FALSE(err);
CheckAssignmentInEngineContext(engine(), kExpected0);
CheckAssignmentInEngineContext(&engine1, kExpected1);
@@ -68,7 +75,8 @@
{
// engine1 executing in engine2's context doesn't affect engine1.
v8::Context::Scope context_scope2(engine2.GetV8Context());
- Optional<IJS_Runtime::JS_Error> err = engine1.Execute(WideString(kScript2));
+ absl::optional<IJS_Runtime::JS_Error> err =
+ engine1.Execute(WideString(kScript2));
EXPECT_FALSE(err);
CheckAssignmentInEngineContext(engine(), kExpected0);
CheckAssignmentInEngineContext(&engine1, kExpected1);
@@ -83,7 +91,7 @@
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(GetV8Context());
- Optional<IJS_Runtime::JS_Error> err =
+ absl::optional<IJS_Runtime::JS_Error> err =
engine()->Execute(L"functoon(x) { return x+1; }");
EXPECT_TRUE(err);
EXPECT_STREQ(L"SyntaxError: Unexpected token '{'", err->exception.c_str());
@@ -96,11 +104,12 @@
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(GetV8Context());
- Optional<IJS_Runtime::JS_Error> err =
+ absl::optional<IJS_Runtime::JS_Error> err =
engine()->Execute(L"let a = 3;\nundefined.colour");
EXPECT_TRUE(err);
- EXPECT_EQ(L"TypeError: Cannot read property 'colour' of undefined",
- err->exception);
+ EXPECT_EQ(
+ L"TypeError: Cannot read properties of undefined (reading 'colour')",
+ err->exception);
EXPECT_EQ(2, err->line);
EXPECT_EQ(10, err->column);
}
diff --git a/fxjs/cfxjs_engine_unittest.cpp b/fxjs/cfxjs_engine_unittest.cpp
index e0f7301..8d6c36b 100644
--- a/fxjs/cfxjs_engine_unittest.cpp
+++ b/fxjs/cfxjs_engine_unittest.cpp
@@ -1,4 +1,4 @@
-// Copyright 2018 PDFium Authors. All rights reserved.
+// Copyright 2018 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,22 +6,23 @@
#include <memory>
-#include "fxjs/cfx_v8_unittest.h"
#include "fxjs/cjs_object.h"
+#include "testing/fxv8_unittest.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/base/ptr_util.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-isolate.h"
class FXJSEngineUnitTest : public FXV8UnitTest {
public:
FXJSEngineUnitTest() = default;
~FXJSEngineUnitTest() override = default;
+ // FXV8UnitTest:
void SetUp() override {
FXV8UnitTest::SetUp();
FXJS_Initialize(1, isolate());
- engine_ = pdfium::MakeUnique<CFXJS_Engine>(isolate());
+ engine_ = std::make_unique<CFXJS_Engine>(isolate());
}
-
void TearDown() override { FXJS_Release(); }
CFXJS_Engine* engine() const { return engine_.get(); }
@@ -36,15 +37,22 @@
static bool temp_destroyed = false;
TEST_F(FXJSEngineUnitTest, GC) {
+ // Reset variables since there might be multiple iterations.
+ perm_created = false;
+ perm_destroyed = false;
+ temp_created = false;
+ temp_destroyed = false;
+
v8::Isolate::Scope isolate_scope(isolate());
v8::HandleScope handle_scope(isolate());
- // Object: 0
+ // Object: 1
engine()->DefineObj(
"perm", FXJSOBJTYPE_DYNAMIC,
- [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) {
+ [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj,
+ v8::Local<v8::Object> proxy) {
pEngine->SetObjectPrivate(obj,
- pdfium::MakeUnique<CJS_Object>(obj, nullptr));
+ std::make_unique<CJS_Object>(proxy, nullptr));
perm_created = true;
},
[](v8::Local<v8::Object> obj) {
@@ -52,12 +60,13 @@
CFXJS_Engine::SetObjectPrivate(obj, nullptr);
});
- // Object: 1
+ // Object: 2
engine()->DefineObj(
"temp", FXJSOBJTYPE_DYNAMIC,
- [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) {
+ [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj,
+ v8::Local<v8::Object> proxy) {
pEngine->SetObjectPrivate(obj,
- pdfium::MakeUnique<CJS_Object>(obj, nullptr));
+ std::make_unique<CJS_Object>(proxy, nullptr));
temp_created = true;
},
[](v8::Local<v8::Object> obj) {
@@ -69,7 +78,7 @@
v8::Context::Scope context_scope(engine()->GetV8Context());
v8::Local<v8::Object> perm =
- engine()->NewFXJSBoundObject(0, FXJSOBJTYPE_DYNAMIC);
+ engine()->NewFXJSBoundObject(1, FXJSOBJTYPE_DYNAMIC);
EXPECT_FALSE(perm.IsEmpty());
EXPECT_TRUE(perm_created);
EXPECT_FALSE(perm_destroyed);
@@ -77,13 +86,13 @@
{
v8::HandleScope inner_handle_scope(isolate());
v8::Local<v8::Object> temp =
- engine()->NewFXJSBoundObject(1, FXJSOBJTYPE_DYNAMIC);
+ engine()->NewFXJSBoundObject(2, FXJSOBJTYPE_DYNAMIC);
EXPECT_FALSE(temp.IsEmpty());
EXPECT_TRUE(temp_created);
EXPECT_FALSE(temp_destroyed);
}
- Optional<IJS_Runtime::JS_Error> err = engine()->Execute(L"gc();");
+ absl::optional<IJS_Runtime::JS_Error> err = engine()->Execute(L"gc();");
EXPECT_FALSE(err);
EXPECT_TRUE(perm_created);
diff --git a/fxjs/cjs_annot.cpp b/fxjs/cjs_annot.cpp
index 292e586..cee6111 100644
--- a/fxjs/cjs_annot.cpp
+++ b/fxjs/cjs_annot.cpp
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,7 +7,6 @@
#include "fxjs/cjs_annot.h"
#include "constants/annotation_flags.h"
-#include "fpdfsdk/cpdfsdk_baannot.h"
#include "fxjs/cjs_event_context.h"
#include "fxjs/cjs_object.h"
#include "fxjs/js_define.h"
@@ -18,12 +17,12 @@
{"name", get_name_static, set_name_static},
{"type", get_type_static, set_type_static}};
-int CJS_Annot::ObjDefnID = -1;
+uint32_t CJS_Annot::ObjDefnID = 0;
const char CJS_Annot::kName[] = "Annot";
// static
-int CJS_Annot::GetObjDefnID() {
+uint32_t CJS_Annot::GetObjDefnID() {
return ObjDefnID;
}
@@ -47,7 +46,7 @@
if (!m_pAnnot)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- CPDF_Annot* pPDFAnnot = m_pAnnot->AsBAAnnot()->GetPDFAnnot();
+ CPDF_Annot* pPDFAnnot = m_pAnnot->GetPDFAnnot();
return CJS_Result::Success(pRuntime->NewBoolean(pPDFAnnot->IsHidden()));
}
@@ -56,7 +55,7 @@
// May invalidate m_pAnnot.
bool bHidden = pRuntime->ToBoolean(vp);
- CPDFSDK_BAAnnot* pBAAnnot = ToBAAnnot(m_pAnnot.Get());
+ CPDFSDK_BAAnnot* pBAAnnot = m_pAnnot.Get();
if (!pBAAnnot)
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -77,7 +76,7 @@
}
CJS_Result CJS_Annot::get_name(CJS_Runtime* pRuntime) {
- CPDFSDK_BAAnnot* pBAAnnot = ToBAAnnot(m_pAnnot.Get());
+ CPDFSDK_BAAnnot* pBAAnnot = m_pAnnot.Get();
if (!pBAAnnot)
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -89,7 +88,7 @@
// May invalidate m_pAnnot.
WideString annotName = pRuntime->ToWideString(vp);
- CPDFSDK_BAAnnot* pBAAnnot = ToBAAnnot(m_pAnnot.Get());
+ CPDFSDK_BAAnnot* pBAAnnot = m_pAnnot.Get();
if (!pBAAnnot)
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -98,14 +97,12 @@
}
CJS_Result CJS_Annot::get_type(CJS_Runtime* pRuntime) {
- CPDFSDK_BAAnnot* pBAAnnot = ToBAAnnot(m_pAnnot.Get());
+ CPDFSDK_BAAnnot* pBAAnnot = m_pAnnot.Get();
if (!pBAAnnot)
return CJS_Result::Failure(JSMessage::kBadObjectError);
return CJS_Result::Success(pRuntime->NewString(
- WideString::FromDefANSI(
- CPDF_Annot::AnnotSubtypeToString(pBAAnnot->GetAnnotSubtype())
- .AsStringView())
+ CPDF_Annot::AnnotSubtypeToString(pBAAnnot->GetAnnotSubtype())
.AsStringView()));
}
diff --git a/fxjs/cjs_annot.h b/fxjs/cjs_annot.h
index ceb2615..0e53407 100644
--- a/fxjs/cjs_annot.h
+++ b/fxjs/cjs_annot.h
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,14 +7,13 @@
#ifndef FXJS_CJS_ANNOT_H_
#define FXJS_CJS_ANNOT_H_
+#include "fpdfsdk/cpdfsdk_baannot.h"
#include "fxjs/cjs_object.h"
#include "fxjs/js_define.h"
-class CPDFSDK_BAAnnot;
-
class CJS_Annot final : public CJS_Object {
public:
- static int GetObjDefnID();
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
CJS_Annot(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
@@ -27,7 +26,7 @@
JS_STATIC_PROP(type, type, CJS_Annot)
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const char kName[];
static const JSPropertySpec PropertySpecs[];
@@ -40,7 +39,7 @@
CJS_Result get_type(CJS_Runtime* pRuntime);
CJS_Result set_type(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp);
- ObservedPtr<CPDFSDK_Annot> m_pAnnot;
+ ObservedPtr<CPDFSDK_BAAnnot> m_pAnnot;
};
#endif // FXJS_CJS_ANNOT_H_
diff --git a/fxjs/cjs_app.cpp b/fxjs/cjs_app.cpp
index 992fd98..0784e7e 100644
--- a/fxjs/cjs_app.cpp
+++ b/fxjs/cjs_app.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,24 +6,33 @@
#include "fxjs/cjs_app.h"
+#include <stdint.h>
+
+#include <algorithm>
#include <utility>
+#include "core/fxcrt/fixed_zeroed_data_vector.h"
+#include "core/fxcrt/stl_util.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_interactiveform.h"
#include "fxjs/cjs_document.h"
#include "fxjs/cjs_timerobj.h"
#include "fxjs/global_timer.h"
#include "fxjs/ijs_event_context.h"
#include "fxjs/js_resources.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
+#include "v8/include/v8-container.h"
-#define JS_STR_VIEWERTYPE L"pdfium"
-#define JS_STR_VIEWERVARIATION L"Full"
-#define JS_STR_PLATFORM L"WIN"
-#define JS_STR_LANGUAGE L"ENU"
-#define JS_NUM_VIEWERVERSION 8
-#define JS_NUM_VIEWERVERSION_XFA 11
-#define JS_NUM_FORMSVERSION 7
+namespace {
+
+constexpr wchar_t kStrViewerType[] = L"pdfium";
+constexpr wchar_t kStrViewerVariation[] = L"Full";
+constexpr wchar_t kStrPlatform[] = L"WIN";
+constexpr wchar_t kStrLanguage[] = L"ENU";
+constexpr int kNumViewerVersion = 8;
+constexpr int kNumViewerVersionXfa = 11;
+constexpr int kNumFormsVersion = 7;
+
+} // namespace
const JSPropertySpec CJS_App::PropertySpecs[] = {
{"activeDocs", get_active_docs_static, set_active_docs_static},
@@ -64,12 +73,12 @@
{"setInterval", setInterval_static},
{"setTimeOut", setTimeOut_static}};
-int CJS_App::ObjDefnID = -1;
+uint32_t CJS_App::ObjDefnID = 0;
const char CJS_App::kName[] = "app";
// static
-int CJS_App::GetObjDefnID() {
+uint32_t CJS_App::GetObjDefnID() {
return ObjDefnID;
}
@@ -88,7 +97,7 @@
CJS_Result CJS_App::get_active_docs(CJS_Runtime* pRuntime) {
v8::Local<v8::Object> pObj = pRuntime->GetThisObj();
- auto pJSDocument = JSGetObject<CJS_Document>(pObj);
+ auto pJSDocument = JSGetObject<CJS_Document>(pRuntime->GetIsolate(), pObj);
if (!pJSDocument)
return CJS_Result::Failure(JSMessage::kObjectTypeError);
v8::Local<v8::Array> aDocs = pRuntime->NewArray();
@@ -117,7 +126,7 @@
}
CJS_Result CJS_App::get_forms_version(CJS_Runtime* pRuntime) {
- return CJS_Result::Success(pRuntime->NewNumber(JS_NUM_FORMSVERSION));
+ return CJS_Result::Success(pRuntime->NewNumber(kNumFormsVersion));
}
CJS_Result CJS_App::set_forms_version(CJS_Runtime* pRuntime,
@@ -126,7 +135,7 @@
}
CJS_Result CJS_App::get_viewer_type(CJS_Runtime* pRuntime) {
- return CJS_Result::Success(pRuntime->NewString(JS_STR_VIEWERTYPE));
+ return CJS_Result::Success(pRuntime->NewString(kStrViewerType));
}
CJS_Result CJS_App::set_viewer_type(CJS_Runtime* pRuntime,
@@ -135,7 +144,7 @@
}
CJS_Result CJS_App::get_viewer_variation(CJS_Runtime* pRuntime) {
- return CJS_Result::Success(pRuntime->NewString(JS_STR_VIEWERVARIATION));
+ return CJS_Result::Success(pRuntime->NewString(kStrViewerVariation));
}
CJS_Result CJS_App::set_viewer_variation(CJS_Runtime* pRuntime,
@@ -147,8 +156,8 @@
CPDF_Document::Extension* pContext =
pRuntime->GetFormFillEnv()->GetDocExtension();
int version = pContext && pContext->ContainsExtensionForm()
- ? JS_NUM_VIEWERVERSION_XFA
- : JS_NUM_VIEWERVERSION;
+ ? kNumViewerVersionXfa
+ : kNumViewerVersion;
return CJS_Result::Success(pRuntime->NewNumber(version));
}
@@ -164,7 +173,7 @@
if (!platform.IsEmpty())
return CJS_Result::Success(pRuntime->NewString(platform.AsStringView()));
}
- return CJS_Result::Success(pRuntime->NewString(JS_STR_PLATFORM));
+ return CJS_Result::Success(pRuntime->NewString(kStrPlatform));
}
CJS_Result CJS_App::set_platform(CJS_Runtime* pRuntime,
@@ -179,7 +188,7 @@
if (!language.IsEmpty())
return CJS_Result::Success(pRuntime->NewString(language.AsStringView()));
}
- return CJS_Result::Success(pRuntime->NewString(JS_STR_LANGUAGE));
+ return CJS_Result::Success(pRuntime->NewString(kStrLanguage));
}
CJS_Result CJS_App::set_language(CJS_Runtime* pRuntime,
@@ -250,7 +259,7 @@
swTitle = JSGetStringFromID(JSMessage::kAlert);
pRuntime->BeginBlock();
- pFormFillEnv->KillFocusAnnot(0);
+ pFormFillEnv->KillFocusAnnot({});
v8::Local<v8::Value> ret = pRuntime->NewNumber(
pFormFillEnv->JS_appAlert(swMsg, swTitle, iType, iIcon));
pRuntime->EndBlock();
@@ -302,7 +311,7 @@
return CJS_Result::Failure(JSMessage::kInvalidInputError);
uint32_t dwInterval = params.size() > 1 ? pRuntime->ToInt32(params[1]) : 1000;
- auto timerRef = pdfium::MakeUnique<GlobalTimer>(
+ auto timerRef = std::make_unique<GlobalTimer>(
this, pRuntime, GlobalTimer::Type::kRepeating, script, dwInterval, 0);
GlobalTimer* pTimerRef = timerRef.get();
m_Timers.insert(std::move(timerRef));
@@ -312,8 +321,8 @@
if (pRetObj.IsEmpty())
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto* pJS_TimerObj =
- static_cast<CJS_TimerObj*>(CFXJS_Engine::GetObjectPrivate(pRetObj));
+ auto* pJS_TimerObj = static_cast<CJS_TimerObj*>(
+ CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pRetObj));
pJS_TimerObj->SetTimer(pTimerRef);
return CJS_Result::Success(pRetObj);
@@ -330,9 +339,9 @@
return CJS_Result::Failure(JSMessage::kInvalidInputError);
uint32_t dwTimeOut = params.size() > 1 ? pRuntime->ToInt32(params[1]) : 1000;
- auto timerRef = pdfium::MakeUnique<GlobalTimer>(this, pRuntime,
- GlobalTimer::Type::kOneShot,
- script, dwTimeOut, dwTimeOut);
+ auto timerRef =
+ std::make_unique<GlobalTimer>(this, pRuntime, GlobalTimer::Type::kOneShot,
+ script, dwTimeOut, dwTimeOut);
GlobalTimer* pTimerRef = timerRef.get();
m_Timers.insert(std::move(timerRef));
@@ -341,8 +350,8 @@
if (pRetObj.IsEmpty())
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto* pJS_TimerObj =
- static_cast<CJS_TimerObj*>(CFXJS_Engine::GetObjectPrivate(pRetObj));
+ auto* pJS_TimerObj = static_cast<CJS_TimerObj*>(
+ CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pRetObj));
pJS_TimerObj->SetTimer(pTimerRef);
return CJS_Result::Success(pRetObj);
@@ -374,7 +383,7 @@
return;
v8::Local<v8::Object> pObj = pRuntime->ToObject(param);
- auto pTimer = JSGetObject<CJS_TimerObj>(pObj);
+ auto pTimer = JSGetObject<CJS_TimerObj>(pRuntime->GetIsolate(), pObj);
if (!pTimer)
return;
@@ -394,7 +403,7 @@
}
void CJS_App::CancelProc(GlobalTimer* pTimer) {
- m_Timers.erase(pdfium::FakeUniquePtr<GlobalTimer>(pTimer));
+ m_Timers.erase(fxcrt::MakeFakeUniquePtr(pTimer));
}
void CJS_App::RunJsScript(CJS_Runtime* pRuntime, const WideString& wsScript) {
@@ -453,8 +462,8 @@
cMsg = pRuntime->ToWideString(newParams[5]);
pRuntime->BeginBlock();
- pRuntime->GetFormFillEnv()->JS_docmailForm(nullptr, 0, bUI, cTo, cSubject,
- cCc, cBcc, cMsg);
+ pRuntime->GetFormFillEnv()->JS_docmailForm(pdfium::span<const uint8_t>(), bUI,
+ cTo, cSubject, cCc, cBcc, cMsg);
pRuntime->EndBlock();
return CJS_Result::Success();
}
@@ -541,18 +550,20 @@
if (IsExpandedParamKnown(newParams[4]))
swLabel = pRuntime->ToWideString(newParams[4]);
- const int MAX_INPUT_BYTES = 2048;
- std::vector<uint8_t> pBuff(MAX_INPUT_BYTES + 2);
- int nLengthBytes = pRuntime->GetFormFillEnv()->JS_appResponse(
- swQuestion, swTitle, swDefault, swLabel, bPassword, pBuff.data(),
- MAX_INPUT_BYTES);
-
- if (nLengthBytes < 0 || nLengthBytes > MAX_INPUT_BYTES)
+ constexpr int kMaxWideChars = 1024;
+ constexpr int kMaxBytes = kMaxWideChars * sizeof(uint16_t);
+ FixedZeroedDataVector<uint16_t> buffer(kMaxWideChars);
+ pdfium::span<uint16_t> buffer_span = buffer.writable_span();
+ int byte_length = pRuntime->GetFormFillEnv()->JS_appResponse(
+ swQuestion, swTitle, swDefault, swLabel, bPassword,
+ pdfium::as_writable_bytes(buffer_span));
+ if (byte_length < 0 || byte_length > kMaxBytes)
return CJS_Result::Failure(JSMessage::kParamTooLongError);
+ buffer_span = buffer_span.first(
+ std::min<size_t>(kMaxWideChars, byte_length / sizeof(uint16_t)));
return CJS_Result::Success(pRuntime->NewString(
- WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.data()),
- nLengthBytes / sizeof(uint16_t))
+ WideString::FromUTF16LE(buffer_span.data(), buffer_span.size())
.AsStringView()));
}
diff --git a/fxjs/cjs_app.h b/fxjs/cjs_app.h
index 524a7f0..23b5c1f 100644
--- a/fxjs/cjs_app.h
+++ b/fxjs/cjs_app.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -19,7 +19,7 @@
class CJS_App final : public CJS_Object {
public:
- static int GetObjDefnID();
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
CJS_App(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
@@ -66,7 +66,7 @@
JS_STATIC_METHOD(setTimeOut, CJS_App)
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const char kName[];
static const JSPropertySpec PropertySpecs[];
static const JSMethodSpec MethodSpecs[];
diff --git a/fxjs/cjs_border.cpp b/fxjs/cjs_border.cpp
index 35204d7..b8edd09 100644
--- a/fxjs/cjs_border.cpp
+++ b/fxjs/cjs_border.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -13,7 +13,7 @@
{"i", JSConstSpec::String, 0, "inset"},
{"u", JSConstSpec::String, 0, "underline"}};
-int CJS_Border::ObjDefnID = -1;
+uint32_t CJS_Border::ObjDefnID = 0;
// static
void CJS_Border::DefineJSObjects(CFXJS_Engine* pEngine) {
diff --git a/fxjs/cjs_border.h b/fxjs/cjs_border.h
index 0a306f7..29a9251 100644
--- a/fxjs/cjs_border.h
+++ b/fxjs/cjs_border.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
CJS_Border() = delete;
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const JSConstSpec ConstSpecs[];
};
diff --git a/fxjs/cjs_color.cpp b/fxjs/cjs_color.cpp
index 2b75e75..22b31fc 100644
--- a/fxjs/cjs_color.cpp
+++ b/fxjs/cjs_color.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,10 +11,11 @@
#include "core/fxge/cfx_color.h"
#include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
#include "fxjs/cjs_object.h"
#include "fxjs/cjs_runtime.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_define.h"
+#include "v8/include/v8-container.h"
const JSPropertySpec CJS_Color::PropertySpecs[] = {
{"black", get_black_static, set_black_static},
@@ -33,11 +34,11 @@
const JSMethodSpec CJS_Color::MethodSpecs[] = {{"convert", convert_static},
{"equal", equal_static}};
-int CJS_Color::ObjDefnID = -1;
+uint32_t CJS_Color::ObjDefnID = 0;
const char CJS_Color::kName[] = "color";
// static
-int CJS_Color::GetObjDefnID() {
+uint32_t CJS_Color::GetObjDefnID() {
return ObjDefnID;
}
@@ -54,23 +55,23 @@
const CFX_Color& color) {
v8::Local<v8::Array> array;
switch (color.nColorType) {
- case CFX_Color::kTransparent:
+ case CFX_Color::Type::kTransparent:
array = pRuntime->NewArray();
pRuntime->PutArrayElement(array, 0, pRuntime->NewString("T"));
break;
- case CFX_Color::kGray:
+ case CFX_Color::Type::kGray:
array = pRuntime->NewArray();
pRuntime->PutArrayElement(array, 0, pRuntime->NewString("G"));
pRuntime->PutArrayElement(array, 1, pRuntime->NewNumber(color.fColor1));
break;
- case CFX_Color::kRGB:
+ case CFX_Color::Type::kRGB:
array = pRuntime->NewArray();
pRuntime->PutArrayElement(array, 0, pRuntime->NewString("RGB"));
pRuntime->PutArrayElement(array, 1, pRuntime->NewNumber(color.fColor1));
pRuntime->PutArrayElement(array, 2, pRuntime->NewNumber(color.fColor2));
pRuntime->PutArrayElement(array, 3, pRuntime->NewNumber(color.fColor3));
break;
- case CFX_Color::kCMYK:
+ case CFX_Color::Type::kCMYK:
array = pRuntime->NewArray();
pRuntime->PutArrayElement(array, 0, pRuntime->NewString("CMYK"));
pRuntime->PutArrayElement(array, 1, pRuntime->NewNumber(color.fColor1));
@@ -85,14 +86,14 @@
// static
CFX_Color CJS_Color::ConvertArrayToPWLColor(CJS_Runtime* pRuntime,
v8::Local<v8::Array> array) {
- int nArrayLen = pRuntime->GetArrayLength(array);
- if (nArrayLen < 1)
+ size_t nArrayLen = pRuntime->GetArrayLength(array);
+ if (nArrayLen == 0)
return CFX_Color();
WideString sSpace =
pRuntime->ToWideString(pRuntime->GetArrayElement(array, 0));
if (sSpace.EqualsASCII("T"))
- return CFX_Color(CFX_Color::kTransparent);
+ return CFX_Color(CFX_Color::Type::kTransparent);
float d1 = 0;
if (nArrayLen > 1) {
@@ -100,7 +101,7 @@
pRuntime->ToDouble(pRuntime->GetArrayElement(array, 1)));
}
if (sSpace.EqualsASCII("G"))
- return CFX_Color(CFX_Color::kGray, d1);
+ return CFX_Color(CFX_Color::Type::kGray, d1);
float d2 = 0;
float d3 = 0;
@@ -113,7 +114,7 @@
pRuntime->ToDouble(pRuntime->GetArrayElement(array, 3)));
}
if (sSpace.EqualsASCII("RGB"))
- return CFX_Color(CFX_Color::kRGB, d1, d2, d3);
+ return CFX_Color(CFX_Color::Type::kRGB, d1, d2, d3);
float d4 = 0;
if (nArrayLen > 4) {
@@ -121,25 +122,25 @@
pRuntime->ToDouble(pRuntime->GetArrayElement(array, 4)));
}
if (sSpace.EqualsASCII("CMYK"))
- return CFX_Color(CFX_Color::kCMYK, d1, d2, d3, d4);
+ return CFX_Color(CFX_Color::Type::kCMYK, d1, d2, d3, d4);
return CFX_Color();
}
CJS_Color::CJS_Color(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime)
: CJS_Object(pObject, pRuntime),
- m_crTransparent(CFX_Color::kTransparent),
- m_crBlack(CFX_Color::kGray, 0),
- m_crWhite(CFX_Color::kGray, 1),
- m_crRed(CFX_Color::kRGB, 1, 0, 0),
- m_crGreen(CFX_Color::kRGB, 0, 1, 0),
- m_crBlue(CFX_Color::kRGB, 0, 0, 1),
- m_crCyan(CFX_Color::kCMYK, 1, 0, 0, 0),
- m_crMagenta(CFX_Color::kCMYK, 0, 1, 0, 0),
- m_crYellow(CFX_Color::kCMYK, 0, 0, 1, 0),
- m_crDKGray(CFX_Color::kGray, 0.25),
- m_crGray(CFX_Color::kGray, 0.5),
- m_crLTGray(CFX_Color::kGray, 0.75) {}
+ m_crTransparent(CFX_Color::Type::kTransparent),
+ m_crBlack(CFX_Color::Type::kGray, 0),
+ m_crWhite(CFX_Color::Type::kGray, 1),
+ m_crRed(CFX_Color::Type::kRGB, 1, 0, 0),
+ m_crGreen(CFX_Color::Type::kRGB, 0, 1, 0),
+ m_crBlue(CFX_Color::Type::kRGB, 0, 0, 1),
+ m_crCyan(CFX_Color::Type::kCMYK, 1, 0, 0, 0),
+ m_crMagenta(CFX_Color::Type::kCMYK, 0, 1, 0, 0),
+ m_crYellow(CFX_Color::Type::kCMYK, 0, 0, 1, 0),
+ m_crDKGray(CFX_Color::Type::kGray, 0.25),
+ m_crGray(CFX_Color::Type::kGray, 0.5),
+ m_crLTGray(CFX_Color::Type::kGray, 0.75) {}
CJS_Color::~CJS_Color() = default;
@@ -273,19 +274,19 @@
if (params.size() < 2)
return CJS_Result::Failure(JSMessage::kParamError);
- if (params[0].IsEmpty() || !params[0]->IsArray())
+ if (!fxv8::IsArray(params[0]))
return CJS_Result::Failure(JSMessage::kTypeError);
WideString sDestSpace = pRuntime->ToWideString(params[1]);
- int nColorType = CFX_Color::kTransparent;
+ CFX_Color::Type nColorType = CFX_Color::Type::kTransparent;
if (sDestSpace.EqualsASCII("T"))
- nColorType = CFX_Color::kTransparent;
+ nColorType = CFX_Color::Type::kTransparent;
else if (sDestSpace.EqualsASCII("G"))
- nColorType = CFX_Color::kGray;
+ nColorType = CFX_Color::Type::kGray;
else if (sDestSpace.EqualsASCII("RGB"))
- nColorType = CFX_Color::kRGB;
+ nColorType = CFX_Color::Type::kRGB;
else if (sDestSpace.EqualsASCII("CMYK"))
- nColorType = CFX_Color::kCMYK;
+ nColorType = CFX_Color::Type::kCMYK;
CFX_Color color =
ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[0]));
@@ -302,10 +303,8 @@
if (params.size() < 2)
return CJS_Result::Failure(JSMessage::kParamError);
- if (params[0].IsEmpty() || !params[0]->IsArray() || params[1].IsEmpty() ||
- !params[1]->IsArray()) {
+ if (!fxv8::IsArray(params[0]) || !fxv8::IsArray(params[1]))
return CJS_Result::Failure(JSMessage::kTypeError);
- }
CFX_Color color1 =
ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[0]));
@@ -313,7 +312,7 @@
ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[1]));
// Relies on higher values having more components.
- int32_t best = std::max(color1.nColorType, color2.nColorType);
+ CFX_Color::Type best = std::max(color1.nColorType, color2.nColorType);
return CJS_Result::Success(pRuntime->NewBoolean(
color1.ConvertColorType(best) == color2.ConvertColorType(best)));
}
diff --git a/fxjs/cjs_color.h b/fxjs/cjs_color.h
index 03aa735..b768709 100644
--- a/fxjs/cjs_color.h
+++ b/fxjs/cjs_color.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,12 +9,13 @@
#include <vector>
+#include "core/fxge/cfx_color.h"
#include "fxjs/cjs_object.h"
#include "fxjs/js_define.h"
class CJS_Color final : public CJS_Object {
public:
- static int GetObjDefnID();
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
static v8::Local<v8::Array> ConvertPWLColorToArray(CJS_Runtime* pRuntime,
const CFX_Color& color);
@@ -41,7 +42,7 @@
JS_STATIC_METHOD(equal, CJS_Color)
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const char kName[];
static const JSPropertySpec PropertySpecs[];
static const JSMethodSpec MethodSpecs[];
diff --git a/fxjs/cjs_console.cpp b/fxjs/cjs_console.cpp
index c696bbd..91c2ca0 100644
--- a/fxjs/cjs_console.cpp
+++ b/fxjs/cjs_console.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,7 +9,6 @@
#include <vector>
#include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
#include "fxjs/cjs_object.h"
#include "fxjs/js_define.h"
@@ -18,11 +17,11 @@
{"println", println_static},
{"show", show_static}};
-int CJS_Console::ObjDefnID = -1;
+uint32_t CJS_Console::ObjDefnID = 0;
const char CJS_Console::kName[] = "console";
// static
-int CJS_Console::GetObjDefnID() {
+uint32_t CJS_Console::GetObjDefnID() {
return ObjDefnID;
}
diff --git a/fxjs/cjs_console.h b/fxjs/cjs_console.h
index 2bc118a..5608d55 100644
--- a/fxjs/cjs_console.h
+++ b/fxjs/cjs_console.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJS_Console final : public CJS_Object {
public:
- static int GetObjDefnID();
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
CJS_Console(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
@@ -26,7 +26,7 @@
JS_STATIC_METHOD(show, CJS_Console)
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const char kName[];
static const JSMethodSpec MethodSpecs[];
diff --git a/fxjs/cjs_delaydata.cpp b/fxjs/cjs_delaydata.cpp
index d7e1f78..12b34fa 100644
--- a/fxjs/cjs_delaydata.cpp
+++ b/fxjs/cjs_delaydata.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,4 +9,4 @@
CJS_DelayData::CJS_DelayData(FIELD_PROP prop, int idx, const WideString& name)
: eProp(prop), nControlIndex(idx), sFieldName(name) {}
-CJS_DelayData::~CJS_DelayData() {}
+CJS_DelayData::~CJS_DelayData() = default;
diff --git a/fxjs/cjs_delaydata.h b/fxjs/cjs_delaydata.h
index f4c7820..861dbab 100644
--- a/fxjs/cjs_delaydata.h
+++ b/fxjs/cjs_delaydata.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -20,9 +20,9 @@
FIELD_PROP eProp;
int nControlIndex;
+ int32_t num = 0;
+ bool b = false;
WideString sFieldName;
- int32_t num;
- bool b;
ByteString bytestring;
WideString widestring;
CFX_FloatRect rect;
diff --git a/fxjs/cjs_display.cpp b/fxjs/cjs_display.cpp
index 71d6c02..0e0ee26 100644
--- a/fxjs/cjs_display.cpp
+++ b/fxjs/cjs_display.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,7 +12,7 @@
{"noPrint", JSConstSpec::Number, 2, 0},
{"noView", JSConstSpec::Number, 3, 0}};
-int CJS_Display::ObjDefnID = -1;
+uint32_t CJS_Display::ObjDefnID = 0;
// static
void CJS_Display::DefineJSObjects(CFXJS_Engine* pEngine) {
diff --git a/fxjs/cjs_display.h b/fxjs/cjs_display.h
index 59b6e9c..7de5368 100644
--- a/fxjs/cjs_display.h
+++ b/fxjs/cjs_display.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
CJS_Display() = delete;
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const JSConstSpec ConstSpecs[];
};
diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp
index 9294f17..5a842ce 100644
--- a/fxjs/cjs_document.cpp
+++ b/fxjs/cjs_document.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,18 +6,22 @@
#include "fxjs/cjs_document.h"
+#include <stdint.h>
+
#include <utility>
+#include "constants/access_permissions.h"
+#include "core/fpdfapi/page/cpdf_pageimagecache.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
#include "core/fpdfapi/page/cpdf_textobject.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_name.h"
#include "core/fpdfapi/parser/cpdf_string.h"
-#include "core/fpdfapi/render/cpdf_pagerendercache.h"
#include "core/fpdfdoc/cpdf_interactiveform.h"
#include "core/fpdfdoc/cpdf_nametree.h"
#include "fpdfsdk/cpdfsdk_annotiteration.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_interactiveform.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "fxjs/cjs_annot.h"
@@ -27,6 +31,8 @@
#include "fxjs/cjs_field.h"
#include "fxjs/cjs_icon.h"
#include "fxjs/js_resources.h"
+#include "third_party/base/check.h"
+#include "v8/include/v8-container.h"
const JSPropertySpec CJS_Document::PropertySpecs[] = {
{"ADBE", get_ADBE_static, set_ADBE_static},
@@ -108,11 +114,11 @@
{"submitForm", submitForm_static},
{"syncAnnotScan", syncAnnotScan_static}};
-int CJS_Document::ObjDefnID = -1;
+uint32_t CJS_Document::ObjDefnID = 0;
const char CJS_Document::kName[] = "Document";
// static
-int CJS_Document::GetObjDefnID() {
+uint32_t CJS_Document::GetObjDefnID() {
return ObjDefnID;
}
@@ -255,8 +261,8 @@
if (pFieldObj.IsEmpty())
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto* pJSField =
- static_cast<CJS_Field*>(CFXJS_Engine::GetObjectPrivate(pFieldObj));
+ auto* pJSField = static_cast<CJS_Field*>(
+ CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pFieldObj));
if (!pJSField)
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -340,8 +346,8 @@
cMsg = pRuntime->ToWideString(newParams[5]);
pRuntime->BeginBlock();
- m_pFormFillEnv->JS_docmailForm(nullptr, 0, bUI, cTo, cSubject, cCc, cBcc,
- cMsg);
+ m_pFormFillEnv->JS_docmailForm(pdfium::span<const uint8_t>(), bUI, cTo,
+ cSubject, cCc, cBcc, cMsg);
pRuntime->EndBlock();
return CJS_Result::Success();
}
@@ -354,7 +360,9 @@
const std::vector<v8::Local<v8::Value>>& params) {
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- if (!m_pFormFillEnv->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
+
+ using pdfium::access_permissions::kExtractForAccessibility;
+ if (!m_pFormFillEnv->HasPermissions(kExtractForAccessibility))
return CJS_Result::Failure(JSMessage::kPermissionError);
CPDFSDK_InteractiveForm* pInteractiveForm = GetSDKInteractiveForm();
@@ -389,10 +397,9 @@
if (IsExpandedParamKnown(newParams[5]))
cMsg = pRuntime->ToWideString(newParams[5]);
- std::vector<char> mutable_buf(sTextBuf.begin(), sTextBuf.end());
pRuntime->BeginBlock();
- m_pFormFillEnv->JS_docmailForm(mutable_buf.data(), mutable_buf.size(), bUI,
- cTo, cSubject, cCc, cBcc, cMsg);
+ m_pFormFillEnv->JS_docmailForm(sTextBuf.raw_span(), bUI, cTo, cSubject, cCc,
+ cBcc, cMsg);
pRuntime->EndBlock();
return CJS_Result::Success();
}
@@ -439,8 +446,7 @@
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- CJS_EventRecorder* pHandler =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pHandler = pRuntime->GetCurrentEventContext();
if (!pHandler->IsUserGesture())
return CJS_Result::Failure(JSMessage::kUserGestureRequiredError);
@@ -460,30 +466,30 @@
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- if (!(m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY) ||
- m_pFormFillEnv->GetPermissions(FPDFPERM_ANNOT_FORM))) {
+ if (!m_pFormFillEnv->HasPermissions(
+ pdfium::access_permissions::kModifyContent |
+ pdfium::access_permissions::kModifyAnnotation)) {
return CJS_Result::Failure(JSMessage::kPermissionError);
}
WideString sFieldName = pRuntime->ToWideString(params[0]);
CPDFSDK_InteractiveForm* pInteractiveForm = GetSDKInteractiveForm();
- std::vector<ObservedPtr<CPDFSDK_Annot>> widgets;
+ std::vector<ObservedPtr<CPDFSDK_Widget>> widgets;
pInteractiveForm->GetWidgets(sFieldName, &widgets);
if (widgets.empty())
return CJS_Result::Success();
- for (const auto& pAnnot : widgets) {
- CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot.Get());
+ for (const auto& pWidget : widgets) {
if (!pWidget)
continue;
IPDF_Page* pPage = pWidget->GetPage();
- ASSERT(pPage);
+ DCHECK(pPage);
// If there is currently no pageview associated with the page being used
// do not create one. We may be in the process of tearing down the document
// and creating a new pageview at this point will cause bad things.
- CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(pPage, false);
+ CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(pPage);
if (!pPageView)
continue;
@@ -506,15 +512,17 @@
const std::vector<v8::Local<v8::Value>>& params) {
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- if (!(m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY) ||
- m_pFormFillEnv->GetPermissions(FPDFPERM_ANNOT_FORM) ||
- m_pFormFillEnv->GetPermissions(FPDFPERM_FILL_FORM))) {
+
+ if (!m_pFormFillEnv->HasPermissions(
+ pdfium::access_permissions::kModifyContent |
+ pdfium::access_permissions::kModifyAnnotation |
+ pdfium::access_permissions::kFillForm)) {
return CJS_Result::Failure(JSMessage::kPermissionError);
}
CPDF_InteractiveForm* pPDFForm = GetCoreInteractiveForm();
if (params.empty()) {
- pPDFForm->ResetForm(NotificationOption::kNotify);
+ pPDFForm->ResetForm();
m_pFormFillEnv->SetChangeMark();
return CJS_Result::Success();
}
@@ -531,12 +539,13 @@
for (size_t i = 0; i < pRuntime->GetArrayLength(array); ++i) {
WideString swVal =
pRuntime->ToWideString(pRuntime->GetArrayElement(array, i));
- for (int j = 0, jsz = pPDFForm->CountFields(swVal); j < jsz; ++j)
+ const size_t jsz = pPDFForm->CountFields(swVal);
+ for (size_t j = 0; j < jsz; ++j)
aFields.push_back(pPDFForm->GetField(j, swVal));
}
if (!aFields.empty()) {
- pPDFForm->ResetForm(aFields, true, NotificationOption::kNotify);
+ pPDFForm->ResetForm(aFields, true);
m_pFormFillEnv->SetChangeMark();
}
@@ -565,8 +574,7 @@
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- CJS_EventRecorder* pHandler =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pHandler = pRuntime->GetCurrentEventContext();
if (!pHandler->IsUserGesture())
return CJS_Result::Failure(JSMessage::kUserGestureRequiredError);
@@ -597,7 +605,7 @@
if (pRuntime->GetArrayLength(aFields) == 0 && bEmpty) {
if (pPDFForm->CheckRequiredFields(nullptr, true)) {
pRuntime->BeginBlock();
- GetSDKInteractiveForm()->SubmitForm(strURL, false);
+ GetSDKInteractiveForm()->SubmitForm(strURL);
pRuntime->EndBlock();
}
return CJS_Result::Success();
@@ -607,7 +615,8 @@
for (size_t i = 0; i < pRuntime->GetArrayLength(aFields); ++i) {
WideString sName =
pRuntime->ToWideString(pRuntime->GetArrayElement(aFields, i));
- for (int j = 0, jsz = pPDFForm->CountFields(sName); j < jsz; ++j) {
+ const size_t jsz = pPDFForm->CountFields(sName);
+ for (size_t j = 0; j < jsz; ++j) {
CPDF_FormField* pField = pPDFForm->GetField(j, sName);
if (!bEmpty && pField->GetValue().IsEmpty())
continue;
@@ -643,14 +652,16 @@
CJS_Result CJS_Document::set_author(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- return setPropertyInternal(pRuntime, vp, "Author");
+ // Read-only.
+ return CJS_Result::Success();
}
CJS_Result CJS_Document::get_info(CJS_Runtime* pRuntime) {
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- const auto* pDictionary = m_pFormFillEnv->GetPDFDocument()->GetInfo();
+ RetainPtr<const CPDF_Dictionary> pDictionary =
+ m_pFormFillEnv->GetPDFDocument()->GetInfo();
if (!pDictionary)
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -685,11 +696,10 @@
pRuntime->NewString(cwTrapped.AsStringView()));
// PutObjectProperty() calls below may re-enter JS and change info dict.
- auto pCopy = pDictionary->Clone();
- CPDF_DictionaryLocker locker(ToDictionary(pCopy.Get()));
+ CPDF_DictionaryLocker locker(ToDictionary(pDictionary->Clone()));
for (const auto& it : locker) {
const ByteString& bsKey = it.first;
- CPDF_Object* pValueObj = it.second.Get();
+ const RetainPtr<CPDF_Object>& pValueObj = it.second;
if (pValueObj->IsString() || pValueObj->IsName()) {
pRuntime->PutObjectProperty(
pObj, bsKey.AsStringView(),
@@ -716,38 +726,23 @@
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- CPDF_Dictionary* pDictionary = m_pFormFillEnv->GetPDFDocument()->GetInfo();
+ RetainPtr<CPDF_Dictionary> pDictionary =
+ m_pFormFillEnv->GetPDFDocument()->GetInfo();
if (!pDictionary)
return CJS_Result::Failure(JSMessage::kBadObjectError);
+
return CJS_Result::Success(pRuntime->NewString(
pDictionary->GetUnicodeTextFor(propName).AsStringView()));
}
-CJS_Result CJS_Document::setPropertyInternal(CJS_Runtime* pRuntime,
- v8::Local<v8::Value> vp,
- const ByteString& propName) {
- if (!m_pFormFillEnv)
- return CJS_Result::Failure(JSMessage::kBadObjectError);
-
- CPDF_Dictionary* pDictionary = m_pFormFillEnv->GetPDFDocument()->GetInfo();
- if (!pDictionary)
- return CJS_Result::Failure(JSMessage::kBadObjectError);
-
- if (!m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY))
- return CJS_Result::Failure(JSMessage::kPermissionError);
-
- pDictionary->SetNewFor<CPDF_String>(propName, pRuntime->ToWideString(vp));
- m_pFormFillEnv->SetChangeMark();
- return CJS_Result::Success();
-}
-
CJS_Result CJS_Document::get_creation_date(CJS_Runtime* pRuntime) {
return getPropertyInternal(pRuntime, "CreationDate");
}
CJS_Result CJS_Document::set_creation_date(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- return setPropertyInternal(pRuntime, vp, "CreationDate");
+ // Read-only.
+ return CJS_Result::Success();
}
CJS_Result CJS_Document::get_creator(CJS_Runtime* pRuntime) {
@@ -756,7 +751,8 @@
CJS_Result CJS_Document::set_creator(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- return setPropertyInternal(pRuntime, vp, "Creator");
+ // Read-only.
+ return CJS_Result::Success();
}
CJS_Result CJS_Document::get_delay(CJS_Runtime* pRuntime) {
@@ -769,7 +765,9 @@
v8::Local<v8::Value> vp) {
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- if (!m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY))
+
+ using pdfium::access_permissions::kModifyContent;
+ if (!m_pFormFillEnv->HasPermissions(kModifyContent))
return CJS_Result::Failure(JSMessage::kPermissionError);
m_bDelay = pRuntime->ToBoolean(vp);
@@ -792,7 +790,8 @@
CJS_Result CJS_Document::set_keywords(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- return setPropertyInternal(pRuntime, vp, "Keywords");
+ // Read-only.
+ return CJS_Result::Success();
}
CJS_Result CJS_Document::get_mod_date(CJS_Runtime* pRuntime) {
@@ -801,7 +800,8 @@
CJS_Result CJS_Document::set_mod_date(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- return setPropertyInternal(pRuntime, vp, "ModDate");
+ // Read-only.
+ return CJS_Result::Success();
}
CJS_Result CJS_Document::get_producer(CJS_Runtime* pRuntime) {
@@ -810,7 +810,8 @@
CJS_Result CJS_Document::set_producer(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- return setPropertyInternal(pRuntime, vp, "Producer");
+ // Read-only.
+ return CJS_Result::Success();
}
CJS_Result CJS_Document::get_subject(CJS_Runtime* pRuntime) {
@@ -819,7 +820,8 @@
CJS_Result CJS_Document::set_subject(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- return setPropertyInternal(pRuntime, vp, "Subject");
+ // Read-only.
+ return CJS_Result::Success();
}
CJS_Result CJS_Document::get_title(CJS_Runtime* pRuntime) {
@@ -830,9 +832,8 @@
CJS_Result CJS_Document::set_title(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- if (!m_pFormFillEnv)
- return CJS_Result::Failure(JSMessage::kBadObjectError);
- return setPropertyInternal(pRuntime, vp, "Title");
+ // Read-only.
+ return CJS_Result::Success();
}
CJS_Result CJS_Document::get_num_pages(CJS_Runtime* pRuntime) {
@@ -935,9 +936,10 @@
if (wsFilePath[i - 1] == L'\\' || wsFilePath[i - 1] == L'/')
break;
}
- if (i > 0 && i < wsFilePath.GetLength())
- return CJS_Result::Success(pRuntime->NewString(wsFilePath.c_str() + i));
-
+ if (i > 0 && i < wsFilePath.GetLength()) {
+ return CJS_Result::Success(
+ pRuntime->NewString(wsFilePath.AsStringView().Substr(i)));
+ }
return CJS_Result::Success(pRuntime->NewString(""));
}
@@ -1005,13 +1007,13 @@
int nPageNo = pRuntime->ToInt32(params[0]);
WideString swAnnotName = pRuntime->ToWideString(params[1]);
- CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(nPageNo);
+ CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageViewAtIndex(nPageNo);
if (!pPageView)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- CPDFSDK_AnnotIteration annotIteration(pPageView, false);
+ CPDFSDK_AnnotIteration annot_iteration(pPageView);
CPDFSDK_BAAnnot* pSDKBAAnnot = nullptr;
- for (const auto& pSDKAnnotCur : annotIteration) {
+ for (const auto& pSDKAnnotCur : annot_iteration) {
auto* pBAAnnot = pSDKAnnotCur->AsBAAnnot();
if (pBAAnnot && pBAAnnot->GetAnnotName() == swAnnotName) {
pSDKBAAnnot = pBAAnnot;
@@ -1026,8 +1028,8 @@
if (pObj.IsEmpty())
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto* pJS_Annot =
- static_cast<CJS_Annot*>(CFXJS_Engine::GetObjectPrivate(pObj));
+ auto* pJS_Annot = static_cast<CJS_Annot*>(
+ CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pObj));
if (!pJS_Annot)
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -1047,12 +1049,12 @@
int nPageNo = m_pFormFillEnv->GetPageCount();
v8::Local<v8::Array> annots = pRuntime->NewArray();
for (int i = 0; i < nPageNo; ++i) {
- CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(i);
+ CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageViewAtIndex(i);
if (!pPageView)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- CPDFSDK_AnnotIteration annotIteration(pPageView, false);
- for (const auto& pSDKAnnotCur : annotIteration) {
+ CPDFSDK_AnnotIteration annot_iteration(pPageView);
+ for (const auto& pSDKAnnotCur : annot_iteration) {
if (!pSDKAnnotCur)
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -1061,8 +1063,8 @@
if (pObj.IsEmpty())
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto* pJS_Annot =
- static_cast<CJS_Annot*>(CFXJS_Engine::GetObjectPrivate(pObj));
+ auto* pJS_Annot = static_cast<CJS_Annot*>(
+ CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pObj));
pJS_Annot->SetSDKAnnot(pSDKAnnotCur->AsBAAnnot());
pRuntime->PutArrayElement(
annots, i,
@@ -1107,7 +1109,7 @@
return CJS_Result::Failure(JSMessage::kTypeError);
v8::Local<v8::Object> pObj = pRuntime->ToObject(params[1]);
- if (!JSGetObject<CJS_Icon>(pObj))
+ if (!JSGetObject<CJS_Icon>(pRuntime->GetIsolate(), pObj))
return CJS_Result::Failure(JSMessage::kTypeError);
WideString swIconName = pRuntime->ToWideString(params[0]);
@@ -1129,8 +1131,8 @@
if (pObj.IsEmpty())
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto* pJS_Icon =
- static_cast<CJS_Icon*>(CFXJS_Engine::GetObjectPrivate(pObj));
+ auto* pJS_Icon = static_cast<CJS_Icon*>(
+ CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pObj));
pJS_Icon->SetIconName(name);
pRuntime->PutArrayElement(Icons, i++,
pJS_Icon
@@ -1161,7 +1163,8 @@
if (pObj.IsEmpty())
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto* pJSIcon = static_cast<CJS_Icon*>(CFXJS_Engine::GetObjectPrivate(pObj));
+ auto* pJSIcon = static_cast<CJS_Icon*>(
+ CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pObj));
if (!pJSIcon)
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -1198,9 +1201,10 @@
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- if (!(m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY) ||
- m_pFormFillEnv->GetPermissions(FPDFPERM_ANNOT_FORM) ||
- m_pFormFillEnv->GetPermissions(FPDFPERM_FILL_FORM))) {
+ if (!m_pFormFillEnv->HasPermissions(
+ pdfium::access_permissions::kModifyContent |
+ pdfium::access_permissions::kModifyAnnotation |
+ pdfium::access_permissions::kFillForm)) {
return CJS_Result::Failure(JSMessage::kPermissionError);
}
@@ -1222,7 +1226,9 @@
const std::vector<v8::Local<v8::Value>>& params) {
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- if (!m_pFormFillEnv->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
+
+ using pdfium::access_permissions::kExtractForAccessibility;
+ if (!m_pFormFillEnv->HasPermissions(kExtractForAccessibility))
return CJS_Result::Failure(JSMessage::kPermissionError);
// TODO(tsepez): check maximum allowable params.
@@ -1235,12 +1241,13 @@
if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
return CJS_Result::Failure(JSMessage::kValueError);
- CPDF_Dictionary* pPageDict = pDocument->GetPageDictionary(nPageNo);
+ RetainPtr<CPDF_Dictionary> pPageDict =
+ pDocument->GetMutablePageDictionary(nPageNo);
if (!pPageDict)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto page = pdfium::MakeRetain<CPDF_Page>(pDocument, pPageDict);
- page->SetRenderCache(pdfium::MakeUnique<CPDF_PageRenderCache>(page.Get()));
+ auto page = pdfium::MakeRetain<CPDF_Page>(pDocument, std::move(pPageDict));
+ page->AddPageImageCache();
page->ParseContent();
int nWords = 0;
@@ -1267,8 +1274,11 @@
const std::vector<v8::Local<v8::Value>>& params) {
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- if (!m_pFormFillEnv->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
+
+ using pdfium::access_permissions::kExtractForAccessibility;
+ if (!m_pFormFillEnv->HasPermissions(kExtractForAccessibility))
return CJS_Result::Failure(JSMessage::kBadObjectError);
+
return CJS_Result::Failure(JSMessage::kNotSupportedError);
}
@@ -1277,7 +1287,9 @@
const std::vector<v8::Local<v8::Value>>& params) {
if (!m_pFormFillEnv)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- if (!m_pFormFillEnv->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
+
+ using pdfium::access_permissions::kExtractForAccessibility;
+ if (!m_pFormFillEnv->HasPermissions(kExtractForAccessibility))
return CJS_Result::Failure(JSMessage::kPermissionError);
int nPageNo = params.size() > 0 ? pRuntime->ToInt32(params[0]) : 0;
@@ -1285,12 +1297,13 @@
if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
return CJS_Result::Failure(JSMessage::kValueError);
- CPDF_Dictionary* pPageDict = pDocument->GetPageDictionary(nPageNo);
+ RetainPtr<CPDF_Dictionary> pPageDict =
+ pDocument->GetMutablePageDictionary(nPageNo);
if (!pPageDict)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto page = pdfium::MakeRetain<CPDF_Page>(pDocument, pPageDict);
- page->SetRenderCache(pdfium::MakeUnique<CPDF_PageRenderCache>(page.Get()));
+ auto page = pdfium::MakeRetain<CPDF_Page>(pDocument, std::move(pPageDict));
+ page->AddPageImageCache();
page->ParseContent();
int nWords = 0;
@@ -1370,23 +1383,16 @@
return CJS_Result::Failure(JSMessage::kBadObjectError);
CPDF_Document* pDocument = m_pFormFillEnv->GetPDFDocument();
- CPDF_NameTree nameTree(pDocument, "Dests");
- CPDF_Array* destArray =
- nameTree.LookupNamedDest(pDocument, pRuntime->ToWideString(params[0]));
- if (!destArray)
+ RetainPtr<const CPDF_Array> dest_array = CPDF_NameTree::LookupNamedDest(
+ pDocument, pRuntime->ToByteString(params[0]));
+ if (!dest_array)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- CPDF_Dest dest(destArray);
- const CPDF_Array* arrayObject = dest.GetArray();
- std::vector<float> scrollPositionArray;
- if (arrayObject) {
- for (size_t i = 2; i < arrayObject->size(); i++)
- scrollPositionArray.push_back(arrayObject->GetNumberAt(i));
- }
+ CPDF_Dest dest(std::move(dest_array));
+ std::vector<float> positions = dest.GetScrollPositionArray();
pRuntime->BeginBlock();
m_pFormFillEnv->DoGoToAction(dest.GetDestPageIndex(pDocument),
- dest.GetZoomMode(), scrollPositionArray.data(),
- scrollPositionArray.size());
+ dest.GetZoomMode(), positions);
pRuntime->EndBlock();
return CJS_Result::Success();
}
diff --git a/fxjs/cjs_document.h b/fxjs/cjs_document.h
index 49448fc..d410a5e 100644
--- a/fxjs/cjs_document.h
+++ b/fxjs/cjs_document.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -17,12 +17,11 @@
class CPDFSDK_InteractiveForm;
class CPDF_InteractiveForm;
-class CPDF_TextObject;
struct CJS_DelayData;
class CJS_Document final : public CJS_Object, public Observable {
public:
- static int GetObjDefnID();
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
CJS_Document(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
@@ -112,7 +111,7 @@
JS_STATIC_METHOD(syncAnnotScan, CJS_Document)
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const char kName[];
static const JSPropertySpec PropertySpecs[];
static const JSMethodSpec MethodSpecs[];
@@ -303,9 +302,6 @@
CJS_Result getPropertyInternal(CJS_Runtime* pRuntime,
const ByteString& propName);
- CJS_Result setPropertyInternal(CJS_Runtime* pRuntime,
- v8::Local<v8::Value> vp,
- const ByteString& propName);
CPDF_InteractiveForm* GetCoreInteractiveForm();
CPDFSDK_InteractiveForm* GetSDKInteractiveForm();
diff --git a/fxjs/cjs_event.cpp b/fxjs/cjs_event.cpp
index a16ee6c..6b89038 100644
--- a/fxjs/cjs_event.cpp
+++ b/fxjs/cjs_event.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,7 +7,6 @@
#include "fxjs/cjs_event.h"
#include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
#include "fxjs/cjs_field.h"
#include "fxjs/cjs_object.h"
#include "fxjs/js_define.h"
@@ -34,11 +33,11 @@
{"value", get_value_static, set_value_static},
{"willCommit", get_will_commit_static, set_will_commit_static}};
-int CJS_Event::ObjDefnID = -1;
+uint32_t CJS_Event::ObjDefnID = 0;
const char CJS_Event::kName[] = "event";
// static
-int CJS_Event::GetObjDefnID() {
+uint32_t CJS_Event::GetObjDefnID() {
return ObjDefnID;
}
@@ -55,27 +54,22 @@
CJS_Event::~CJS_Event() = default;
CJS_Result CJS_Event::get_change(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(
pRuntime->NewString(pEvent->Change().AsStringView()));
}
CJS_Result CJS_Event::set_change(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
-
if (vp->IsString()) {
- WideString& wChange = pEvent->Change();
- wChange = pRuntime->ToWideString(vp);
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
+ pEvent->Change() = pRuntime->ToWideString(vp);
}
return CJS_Result::Success();
}
CJS_Result CJS_Event::get_change_ex(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(
pRuntime->NewString(pEvent->ChangeEx().AsStringView()));
}
@@ -86,8 +80,7 @@
}
CJS_Result CJS_Event::get_commit_key(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(pRuntime->NewNumber(pEvent->CommitKey()));
}
@@ -97,8 +90,7 @@
}
CJS_Result CJS_Event::get_field_full(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (pEvent->Name() != "Keystroke")
return CJS_Result::Failure(L"unrecognized event");
@@ -111,8 +103,7 @@
}
CJS_Result CJS_Event::get_key_down(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(pRuntime->NewBoolean(pEvent->KeyDown()));
}
@@ -122,8 +113,7 @@
}
CJS_Result CJS_Event::get_modifier(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(pRuntime->NewBoolean(pEvent->Modifier()));
}
@@ -133,8 +123,7 @@
}
CJS_Result CJS_Event::get_name(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(pRuntime->NewString(pEvent->Name()));
}
@@ -143,14 +132,12 @@
}
CJS_Result CJS_Event::get_rc(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(pRuntime->NewBoolean(pEvent->Rc()));
}
CJS_Result CJS_Event::set_rc(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
pEvent->Rc() = pRuntime->ToBoolean(vp);
return CJS_Result::Success();
}
@@ -183,8 +170,7 @@
}
CJS_Result CJS_Event::get_sel_end(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (pEvent->Name() != "Keystroke")
return CJS_Result::Success();
@@ -193,8 +179,7 @@
CJS_Result CJS_Event::set_sel_end(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (pEvent->Name() == "Keystroke")
pEvent->SetSelEnd(pRuntime->ToInt32(vp));
@@ -202,8 +187,7 @@
}
CJS_Result CJS_Event::get_sel_start(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (pEvent->Name() != "Keystroke")
return CJS_Result::Success();
@@ -212,8 +196,7 @@
CJS_Result CJS_Event::set_sel_start(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (pEvent->Name() == "Keystroke")
pEvent->SetSelStart(pRuntime->ToInt32(vp));
@@ -221,8 +204,7 @@
}
CJS_Result CJS_Event::get_shift(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(pRuntime->NewBoolean(pEvent->Shift()));
}
@@ -256,8 +238,7 @@
}
CJS_Result CJS_Event::get_target_name(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(
pRuntime->NewString(pEvent->TargetName().AsStringView()));
}
@@ -268,8 +249,7 @@
}
CJS_Result CJS_Event::get_type(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(pRuntime->NewString(pEvent->Type()));
}
@@ -278,8 +258,7 @@
}
CJS_Result CJS_Event::get_value(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (pEvent->Type() != "Field")
return CJS_Result::Failure(L"Bad event type.");
@@ -292,8 +271,7 @@
CJS_Result CJS_Event::set_value(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (pEvent->Type() != "Field")
return CJS_Result::Failure(L"Bad event type.");
@@ -311,8 +289,7 @@
}
CJS_Result CJS_Event::get_will_commit(CJS_Runtime* pRuntime) {
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
return CJS_Result::Success(pRuntime->NewBoolean(pEvent->WillCommit()));
}
diff --git a/fxjs/cjs_event.h b/fxjs/cjs_event.h
index b2fa4dc..fc9bec2 100644
--- a/fxjs/cjs_event.h
+++ b/fxjs/cjs_event.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,7 +12,7 @@
class CJS_Event final : public CJS_Object {
public:
- static int GetObjDefnID();
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
CJS_Event(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
@@ -40,7 +40,7 @@
JS_STATIC_PROP(willCommit, will_commit, CJS_Event)
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const char kName[];
static const JSPropertySpec PropertySpecs[];
diff --git a/fxjs/cjs_event_context.cpp b/fxjs/cjs_event_context.cpp
index 27e8120..65eee9d 100644
--- a/fxjs/cjs_event_context.cpp
+++ b/fxjs/cjs_event_context.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,27 +6,23 @@
#include "fxjs/cjs_event_context.h"
+#include "core/fpdfdoc/cpdf_formfield.h"
#include "core/fxcrt/autorestorer.h"
-#include "fxjs/cjs_eventrecorder.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fxjs/cjs_field.h"
#include "fxjs/cjs_runtime.h"
#include "fxjs/js_define.h"
#include "fxjs/js_resources.h"
-#include "third_party/base/ptr_util.h"
+#include "third_party/base/check.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-isolate.h"
CJS_EventContext::CJS_EventContext(CJS_Runtime* pRuntime)
- : m_pRuntime(pRuntime),
- m_pEventRecorder(pdfium::MakeUnique<CJS_EventRecorder>()) {
- ASSERT(pRuntime);
-}
+ : m_pRuntime(pRuntime), m_pFormFillEnv(pRuntime->GetFormFillEnv()) {}
CJS_EventContext::~CJS_EventContext() = default;
-CPDFSDK_FormFillEnvironment* CJS_EventContext::GetFormFillEnv() {
- return m_pRuntime->GetFormFillEnv();
-}
-
-Optional<IJS_Runtime::JS_Error> CJS_EventContext::RunScript(
+absl::optional<IJS_Runtime::JS_Error> CJS_EventContext::RunScript(
const WideString& script) {
v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate());
v8::HandleScope handle_scope(m_pRuntime->GetIsolate());
@@ -41,20 +37,19 @@
AutoRestorer<bool> restorer(&m_bBusy);
m_bBusy = true;
- ASSERT(m_pEventRecorder->IsValid());
- CJS_Runtime::FieldEvent event(m_pEventRecorder->TargetName(),
- m_pEventRecorder->EventType());
+ DCHECK(IsValid());
+ CJS_Runtime::FieldEvent event(TargetName(), EventKind());
if (!m_pRuntime->AddEventToSet(event)) {
return IJS_Runtime::JS_Error(
1, 1, JSGetStringFromID(JSMessage::kDuplicateEventError));
}
- Optional<IJS_Runtime::JS_Error> err;
+ absl::optional<IJS_Runtime::JS_Error> err;
if (script.GetLength() > 0)
err = m_pRuntime->ExecuteScript(script);
m_pRuntime->RemoveEventFromSet(event);
- m_pEventRecorder->Destroy();
+ Destroy();
return err;
}
@@ -69,17 +64,14 @@
if (pFieldObj.IsEmpty())
return nullptr;
- auto* pFormFillEnv = m_pEventRecorder->GetFormFillEnvironment();
- if (!pFormFillEnv)
- pFormFillEnv = GetFormFillEnv();
-
- auto* pJSDocument =
- static_cast<CJS_Document*>(CFXJS_Engine::GetObjectPrivate(pDocObj));
+ auto* pFormFillEnv = GetFormFillEnv();
+ auto* pJSDocument = static_cast<CJS_Document*>(
+ CFXJS_Engine::GetObjectPrivate(m_pRuntime->GetIsolate(), pDocObj));
pJSDocument->SetFormFillEnv(pFormFillEnv);
- auto* pJSField =
- static_cast<CJS_Field*>(CFXJS_Engine::GetObjectPrivate(pFieldObj));
- pJSField->AttachField(pJSDocument, m_pEventRecorder->SourceName());
+ auto* pJSField = static_cast<CJS_Field*>(
+ CFXJS_Engine::GetObjectPrivate(m_pRuntime->GetIsolate(), pFieldObj));
+ pJSField->AttachField(pJSDocument, SourceName());
return pJSField;
}
@@ -94,137 +86,149 @@
if (pFieldObj.IsEmpty())
return nullptr;
- auto* pFormFillEnv = m_pEventRecorder->GetFormFillEnvironment();
- if (!pFormFillEnv)
- pFormFillEnv = GetFormFillEnv();
-
- auto* pJSDocument =
- static_cast<CJS_Document*>(CFXJS_Engine::GetObjectPrivate(pDocObj));
+ auto* pFormFillEnv = GetFormFillEnv();
+ auto* pJSDocument = static_cast<CJS_Document*>(
+ CFXJS_Engine::GetObjectPrivate(m_pRuntime->GetIsolate(), pDocObj));
pJSDocument->SetFormFillEnv(pFormFillEnv);
- auto* pJSField =
- static_cast<CJS_Field*>(CFXJS_Engine::GetObjectPrivate(pFieldObj));
- pJSField->AttachField(pJSDocument, m_pEventRecorder->TargetName());
+ auto* pJSField = static_cast<CJS_Field*>(
+ CFXJS_Engine::GetObjectPrivate(m_pRuntime->GetIsolate(), pFieldObj));
+ pJSField->AttachField(pJSDocument, TargetName());
return pJSField;
}
-void CJS_EventContext::OnApp_Init() {
- m_pEventRecorder->OnApp_Init();
+void CJS_EventContext::OnDoc_Open(const WideString& strTargetName) {
+ Initialize(Kind::kDocOpen);
+ m_strTargetName = strTargetName;
}
-void CJS_EventContext::OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString& strTargetName) {
- m_pEventRecorder->OnDoc_Open(pFormFillEnv, strTargetName);
+void CJS_EventContext::OnDoc_WillPrint() {
+ Initialize(Kind::kDocWillPrint);
}
-void CJS_EventContext::OnDoc_WillPrint(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnDoc_WillPrint(pFormFillEnv);
+void CJS_EventContext::OnDoc_DidPrint() {
+ Initialize(Kind::kDocDidPrint);
}
-void CJS_EventContext::OnDoc_DidPrint(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnDoc_DidPrint(pFormFillEnv);
+void CJS_EventContext::OnDoc_WillSave() {
+ Initialize(Kind::kDocWillSave);
}
-void CJS_EventContext::OnDoc_WillSave(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnDoc_WillSave(pFormFillEnv);
+void CJS_EventContext::OnDoc_DidSave() {
+ Initialize(Kind::kDocDidSave);
}
-void CJS_EventContext::OnDoc_DidSave(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnDoc_DidSave(pFormFillEnv);
+void CJS_EventContext::OnDoc_WillClose() {
+ Initialize(Kind::kDocWillClose);
}
-void CJS_EventContext::OnDoc_WillClose(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnDoc_WillClose(pFormFillEnv);
+void CJS_EventContext::OnPage_Open() {
+ Initialize(Kind::kPageOpen);
}
-void CJS_EventContext::OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnPage_Open(pFormFillEnv);
+void CJS_EventContext::OnPage_Close() {
+ Initialize(Kind::kPageClose);
}
-void CJS_EventContext::OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnPage_Close(pFormFillEnv);
+void CJS_EventContext::OnPage_InView() {
+ Initialize(Kind::kPageInView);
}
-void CJS_EventContext::OnPage_InView(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnPage_InView(pFormFillEnv);
-}
-
-void CJS_EventContext::OnPage_OutView(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnPage_OutView(pFormFillEnv);
-}
-
-void CJS_EventContext::OnField_MouseDown(bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget) {
- m_pEventRecorder->OnField_MouseDown(bModifier, bShift, pTarget);
+void CJS_EventContext::OnPage_OutView() {
+ Initialize(Kind::kPageOutView);
}
void CJS_EventContext::OnField_MouseEnter(bool bModifier,
bool bShift,
CPDF_FormField* pTarget) {
- m_pEventRecorder->OnField_MouseEnter(bModifier, bShift, pTarget);
+ Initialize(Kind::kFieldMouseEnter);
+ m_bModifier = bModifier;
+ m_bShift = bShift;
+ m_strTargetName = pTarget->GetFullName();
}
void CJS_EventContext::OnField_MouseExit(bool bModifier,
bool bShift,
CPDF_FormField* pTarget) {
- m_pEventRecorder->OnField_MouseExit(bModifier, bShift, pTarget);
+ Initialize(Kind::kFieldMouseExit);
+ m_bModifier = bModifier;
+ m_bShift = bShift;
+ m_strTargetName = pTarget->GetFullName();
+}
+
+void CJS_EventContext::OnField_MouseDown(bool bModifier,
+ bool bShift,
+ CPDF_FormField* pTarget) {
+ Initialize(Kind::kFieldMouseDown);
+ m_bModifier = bModifier;
+ m_bShift = bShift;
+ m_strTargetName = pTarget->GetFullName();
}
void CJS_EventContext::OnField_MouseUp(bool bModifier,
bool bShift,
CPDF_FormField* pTarget) {
- m_pEventRecorder->OnField_MouseUp(bModifier, bShift, pTarget);
+ Initialize(Kind::kFieldMouseUp);
+ m_bModifier = bModifier;
+ m_bShift = bShift;
+ m_strTargetName = pTarget->GetFullName();
}
void CJS_EventContext::OnField_Focus(bool bModifier,
bool bShift,
CPDF_FormField* pTarget,
- WideString* Value) {
- m_pEventRecorder->OnField_Focus(bModifier, bShift, pTarget, Value);
+ WideString* pValue) {
+ DCHECK(pValue);
+ Initialize(Kind::kFieldFocus);
+ m_bModifier = bModifier;
+ m_bShift = bShift;
+ m_strTargetName = pTarget->GetFullName();
+ m_pValue = pValue;
}
void CJS_EventContext::OnField_Blur(bool bModifier,
bool bShift,
CPDF_FormField* pTarget,
- WideString* Value) {
- m_pEventRecorder->OnField_Blur(bModifier, bShift, pTarget, Value);
-}
-
-void CJS_EventContext::OnField_Calculate(CPDF_FormField* pSource,
- CPDF_FormField* pTarget,
- WideString* pValue,
- bool* pRc) {
- m_pEventRecorder->OnField_Calculate(pSource, pTarget, pValue, pRc);
-}
-
-void CJS_EventContext::OnField_Format(CPDF_FormField* pTarget,
- WideString* Value) {
- m_pEventRecorder->OnField_Format(pTarget, Value);
+ WideString* pValue) {
+ DCHECK(pValue);
+ Initialize(Kind::kFieldBlur);
+ m_bModifier = bModifier;
+ m_bShift = bShift;
+ m_strTargetName = pTarget->GetFullName();
+ m_pValue = pValue;
}
void CJS_EventContext::OnField_Keystroke(WideString* strChange,
const WideString& strChangeEx,
- bool bKeyDown,
+ bool KeyDown,
bool bModifier,
- int* nSelEnd,
- int* nSelStart,
+ int* pSelEnd,
+ int* pSelStart,
bool bShift,
CPDF_FormField* pTarget,
- WideString* Value,
+ WideString* pValue,
bool bWillCommit,
bool bFieldFull,
- bool* bRc) {
- m_pEventRecorder->OnField_Keystroke(
- strChange, strChangeEx, bKeyDown, bModifier, nSelEnd, nSelStart, bShift,
- pTarget, Value, bWillCommit, bFieldFull, bRc);
+ bool* pbRc) {
+ DCHECK(pValue);
+ DCHECK(pbRc);
+ DCHECK(pSelStart);
+ DCHECK(pSelEnd);
+
+ Initialize(Kind::kFieldKeystroke);
+ m_nCommitKey = 0;
+ m_pWideStrChange = strChange;
+ m_WideStrChangeEx = strChangeEx;
+ m_bKeyDown = KeyDown;
+ m_bModifier = bModifier;
+ m_pISelEnd = pSelEnd;
+ m_pISelStart = pSelStart;
+ m_bShift = bShift;
+ m_strTargetName = pTarget->GetFullName();
+ m_pValue = pValue;
+ m_bWillCommit = bWillCommit;
+ m_pbRc = pbRc;
+ m_bFieldFull = bFieldFull;
}
void CJS_EventContext::OnField_Validate(WideString* strChange,
@@ -233,94 +237,190 @@
bool bModifier,
bool bShift,
CPDF_FormField* pTarget,
- WideString* Value,
- bool* bRc) {
- m_pEventRecorder->OnField_Validate(strChange, strChangeEx, bKeyDown,
- bModifier, bShift, pTarget, Value, bRc);
+ WideString* pValue,
+ bool* pbRc) {
+ DCHECK(pValue);
+ DCHECK(pbRc);
+ Initialize(Kind::kFieldValidate);
+ m_pWideStrChange = strChange;
+ m_WideStrChangeEx = strChangeEx;
+ m_bKeyDown = bKeyDown;
+ m_bModifier = bModifier;
+ m_bShift = bShift;
+ m_strTargetName = pTarget->GetFullName();
+ m_pValue = pValue;
+ m_pbRc = pbRc;
}
-void CJS_EventContext::OnScreen_Focus(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- m_pEventRecorder->OnScreen_Focus(bModifier, bShift, pScreen);
+void CJS_EventContext::OnField_Calculate(CPDF_FormField* pSource,
+ CPDF_FormField* pTarget,
+ WideString* pValue,
+ bool* pRc) {
+ DCHECK(pValue);
+ DCHECK(pRc);
+ Initialize(Kind::kFieldCalculate);
+ if (pSource)
+ m_strSourceName = pSource->GetFullName();
+ m_strTargetName = pTarget->GetFullName();
+ m_pValue = pValue;
+ m_pbRc = pRc;
}
-void CJS_EventContext::OnScreen_Blur(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- m_pEventRecorder->OnScreen_Blur(bModifier, bShift, pScreen);
-}
-
-void CJS_EventContext::OnScreen_Open(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- m_pEventRecorder->OnScreen_Open(bModifier, bShift, pScreen);
-}
-
-void CJS_EventContext::OnScreen_Close(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- m_pEventRecorder->OnScreen_Close(bModifier, bShift, pScreen);
-}
-
-void CJS_EventContext::OnScreen_MouseDown(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- m_pEventRecorder->OnScreen_MouseDown(bModifier, bShift, pScreen);
-}
-
-void CJS_EventContext::OnScreen_MouseUp(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- m_pEventRecorder->OnScreen_MouseUp(bModifier, bShift, pScreen);
-}
-
-void CJS_EventContext::OnScreen_MouseEnter(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- m_pEventRecorder->OnScreen_MouseEnter(bModifier, bShift, pScreen);
-}
-
-void CJS_EventContext::OnScreen_MouseExit(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- m_pEventRecorder->OnScreen_MouseExit(bModifier, bShift, pScreen);
-}
-
-void CJS_EventContext::OnScreen_InView(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- m_pEventRecorder->OnScreen_InView(bModifier, bShift, pScreen);
-}
-
-void CJS_EventContext::OnScreen_OutView(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- m_pEventRecorder->OnScreen_OutView(bModifier, bShift, pScreen);
-}
-
-void CJS_EventContext::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) {
- m_pEventRecorder->OnBookmark_MouseUp(pBookMark);
-}
-
-void CJS_EventContext::OnLink_MouseUp(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnLink_MouseUp(pFormFillEnv);
-}
-
-void CJS_EventContext::OnConsole_Exec() {
- m_pEventRecorder->OnConsole_Exec();
+void CJS_EventContext::OnField_Format(CPDF_FormField* pTarget,
+ WideString* pValue) {
+ DCHECK(pValue);
+ Initialize(Kind::kFieldFormat);
+ m_nCommitKey = 0;
+ m_strTargetName = pTarget->GetFullName();
+ m_pValue = pValue;
+ m_bWillCommit = true;
}
void CJS_EventContext::OnExternal_Exec() {
- m_pEventRecorder->OnExternal_Exec();
+ Initialize(Kind::kExternalExec);
}
-void CJS_EventContext::OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- m_pEventRecorder->OnBatchExec(pFormFillEnv);
+void CJS_EventContext::Initialize(Kind kind) {
+ m_eKind = kind;
+ m_strTargetName.clear();
+ m_strSourceName.clear();
+ m_pWideStrChange = nullptr;
+ m_WideStrChangeDu.clear();
+ m_WideStrChangeEx.clear();
+ m_nCommitKey = -1;
+ m_bKeyDown = false;
+ m_bModifier = false;
+ m_bShift = false;
+ m_pISelEnd = nullptr;
+ m_nSelEndDu = 0;
+ m_pISelStart = nullptr;
+ m_nSelStartDu = 0;
+ m_bWillCommit = false;
+ m_pValue = nullptr;
+ m_bFieldFull = false;
+ m_pbRc = nullptr;
+ m_bRcDu = false;
+ m_bValid = true;
}
-void CJS_EventContext::OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString& strTargetName) {
- m_pEventRecorder->OnMenu_Exec(pFormFillEnv, strTargetName);
+void CJS_EventContext::Destroy() {
+ m_bValid = false;
+}
+
+bool CJS_EventContext::IsUserGesture() const {
+ switch (m_eKind) {
+ case Kind::kFieldMouseDown:
+ case Kind::kFieldMouseUp:
+ case Kind::kFieldKeystroke:
+ return true;
+ default:
+ return false;
+ }
+}
+
+WideString& CJS_EventContext::Change() {
+ return m_pWideStrChange ? *m_pWideStrChange : m_WideStrChangeDu;
+}
+
+ByteStringView CJS_EventContext::Name() const {
+ switch (m_eKind) {
+ case Kind::kDocDidPrint:
+ return "DidPrint";
+ case Kind::kDocDidSave:
+ return "DidSave";
+ case Kind::kDocOpen:
+ return "Open";
+ case Kind::kDocWillClose:
+ return "WillClose";
+ case Kind::kDocWillPrint:
+ return "WillPrint";
+ case Kind::kDocWillSave:
+ return "WillSave";
+ case Kind::kExternalExec:
+ return "Exec";
+ case Kind::kFieldFocus:
+ return "Focus";
+ case Kind::kFieldBlur:
+ return "Blur";
+ case Kind::kFieldMouseDown:
+ return "Mouse Down";
+ case Kind::kFieldMouseUp:
+ return "Mouse Up";
+ case Kind::kFieldMouseEnter:
+ return "Mouse Enter";
+ case Kind::kFieldMouseExit:
+ return "Mouse Exit";
+ case Kind::kFieldCalculate:
+ return "Calculate";
+ case Kind::kFieldFormat:
+ return "Format";
+ case Kind::kFieldKeystroke:
+ return "Keystroke";
+ case Kind::kFieldValidate:
+ return "Validate";
+ case Kind::kPageOpen:
+ return "Open";
+ case Kind::kPageClose:
+ return "Close";
+ case Kind::kPageInView:
+ return "InView";
+ case Kind::kPageOutView:
+ return "OutView";
+ default:
+ return "";
+ }
+}
+
+ByteStringView CJS_EventContext::Type() const {
+ switch (m_eKind) {
+ case Kind::kDocDidPrint:
+ case Kind::kDocDidSave:
+ case Kind::kDocOpen:
+ case Kind::kDocWillClose:
+ case Kind::kDocWillPrint:
+ case Kind::kDocWillSave:
+ return "Doc";
+ case Kind::kExternalExec:
+ return "External";
+ case Kind::kFieldBlur:
+ case Kind::kFieldFocus:
+ case Kind::kFieldMouseDown:
+ case Kind::kFieldMouseUp:
+ case Kind::kFieldMouseEnter:
+ case Kind::kFieldMouseExit:
+ case Kind::kFieldCalculate:
+ case Kind::kFieldFormat:
+ case Kind::kFieldKeystroke:
+ case Kind::kFieldValidate:
+ return "Field";
+ case Kind::kPageOpen:
+ case Kind::kPageClose:
+ case Kind::kPageInView:
+ case Kind::kPageOutView:
+ return "Page";
+ default:
+ return "";
+ }
+}
+
+bool& CJS_EventContext::Rc() {
+ return m_pbRc ? *m_pbRc : m_bRcDu;
+}
+
+int CJS_EventContext::SelEnd() const {
+ return m_pISelEnd ? *m_pISelEnd : m_nSelEndDu;
+}
+
+int CJS_EventContext::SelStart() const {
+ return m_pISelStart ? *m_pISelStart : m_nSelStartDu;
+}
+
+void CJS_EventContext::SetSelEnd(int value) {
+ int& target = m_pISelEnd ? *m_pISelEnd : m_nSelEndDu;
+ target = value;
+}
+
+void CJS_EventContext::SetSelStart(int value) {
+ int& target = m_pISelStart ? *m_pISelStart : m_nSelStartDu;
+ target = value;
}
diff --git a/fxjs/cjs_event_context.h b/fxjs/cjs_event_context.h
index 6a953e6..a0b266b 100644
--- a/fxjs/cjs_event_context.h
+++ b/fxjs/cjs_event_context.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,37 +7,58 @@
#ifndef FXJS_CJS_EVENT_CONTEXT_H_
#define FXJS_CJS_EVENT_CONTEXT_H_
-#include <memory>
-
#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/observed_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fxjs/ijs_event_context.h"
-class CJS_EventRecorder;
class CJS_Field;
class CJS_Runtime;
-class CPDFSDK_FormFillEnvironment;
class CJS_EventContext final : public IJS_EventContext {
public:
+ enum class Kind : uint8_t {
+ kUnknown,
+ kDocOpen,
+ kDocWillPrint,
+ kDocDidPrint,
+ kDocWillSave,
+ kDocDidSave,
+ kDocWillClose,
+ kPageOpen,
+ kPageClose,
+ kPageInView,
+ kPageOutView,
+ kFieldMouseDown,
+ kFieldMouseUp,
+ kFieldMouseEnter,
+ kFieldMouseExit,
+ kFieldFocus,
+ kFieldBlur,
+ kFieldKeystroke,
+ kFieldValidate,
+ kFieldCalculate,
+ kFieldFormat,
+ kExternalExec,
+ };
+
explicit CJS_EventContext(CJS_Runtime* pRuntime);
~CJS_EventContext() override;
// IJS_EventContext
- Optional<IJS_Runtime::JS_Error> RunScript(const WideString& script) override;
- void OnApp_Init() override;
- void OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString& strTargetName) override;
- void OnDoc_WillPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
- void OnDoc_DidPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
- void OnDoc_WillSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
- void OnDoc_DidSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
- void OnDoc_WillClose(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
- void OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
- void OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
- void OnPage_InView(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
- void OnPage_OutView(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
+ absl::optional<IJS_Runtime::JS_Error> RunScript(
+ const WideString& script) override;
+ void OnDoc_Open(const WideString& strTargetName) override;
+ void OnDoc_WillPrint() override;
+ void OnDoc_DidPrint() override;
+ void OnDoc_WillSave() override;
+ void OnDoc_DidSave() override;
+ void OnDoc_WillClose() override;
+ void OnPage_Open() override;
+ void OnPage_Close() override;
+ void OnPage_InView() override;
+ void OnPage_OutView() override;
void OnField_MouseDown(bool bModifier,
bool bShift,
CPDF_FormField* pTarget) override;
@@ -83,54 +104,72 @@
CPDF_FormField* pTarget,
WideString* Value,
bool* bRc) override;
- void OnScreen_Focus(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override;
- void OnScreen_Blur(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override;
- void OnScreen_Open(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override;
- void OnScreen_Close(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override;
- void OnScreen_MouseDown(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override;
- void OnScreen_MouseUp(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override;
- void OnScreen_MouseEnter(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override;
- void OnScreen_MouseExit(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override;
- void OnScreen_InView(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override;
- void OnScreen_OutView(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override;
- void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) override;
- void OnLink_MouseUp(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
- void OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString& strTargetName) override;
- void OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv) override;
- void OnConsole_Exec() override;
void OnExternal_Exec() override;
- CJS_Runtime* GetJSRuntime() const { return m_pRuntime.Get(); }
- CJS_EventRecorder* GetEventRecorder() const { return m_pEventRecorder.get(); }
- CPDFSDK_FormFillEnvironment* GetFormFillEnv();
+ CJS_Runtime* GetJSRuntime() const { return m_pRuntime; }
+ CPDFSDK_FormFillEnvironment* GetFormFillEnv() const {
+ return m_pFormFillEnv.Get();
+ }
CJS_Field* SourceField();
CJS_Field* TargetField();
+ Kind EventKind() const { return m_eKind; }
+ bool IsValid() const { return m_bValid; }
+ bool IsUserGesture() const;
+ WideString& Change();
+ WideString ChangeEx() const { return m_WideStrChangeEx; }
+ WideString SourceName() const { return m_strSourceName; }
+ WideString TargetName() const { return m_strTargetName; }
+ int CommitKey() const { return m_nCommitKey; }
+ bool FieldFull() const { return m_bFieldFull; }
+ bool KeyDown() const { return m_bKeyDown; }
+ bool Modifier() const { return m_bModifier; }
+ ByteStringView Name() const;
+ ByteStringView Type() const;
+ bool& Rc();
+ int SelEnd() const;
+ int SelStart() const;
+ void SetSelEnd(int value);
+ void SetSelStart(int value);
+ bool Shift() const { return m_bShift; }
+ bool HasValue() const { return !!m_pValue; }
+ WideString& Value() { return *m_pValue; }
+ bool WillCommit() const { return m_bWillCommit; }
+
+ void SetValueForTest(WideString* pStr) { m_pValue = pStr; }
+ void SetRCForTest(bool* pRC) { m_pbRc = pRC; }
+ void SetStrChangeForTest(WideString* pStrChange) {
+ m_pWideStrChange = pStrChange;
+ }
+ void ResetWillCommitForTest() { m_bWillCommit = false; }
+
private:
+ void Initialize(Kind kind);
+ void Destroy();
+
UnownedPtr<CJS_Runtime> const m_pRuntime;
- std::unique_ptr<CJS_EventRecorder> m_pEventRecorder;
+ ObservedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
+ Kind m_eKind = Kind::kUnknown;
bool m_bBusy = false;
+ bool m_bValid = false;
+ UnownedPtr<WideString> m_pValue;
+ WideString m_strSourceName;
+ WideString m_strTargetName;
+ WideString m_WideStrChangeDu;
+ WideString m_WideStrChangeEx;
+ UnownedPtr<WideString> m_pWideStrChange;
+ int m_nCommitKey = -1;
+ bool m_bKeyDown = false;
+ bool m_bModifier = false;
+ bool m_bShift = false;
+ int m_nSelEndDu = 0;
+ int m_nSelStartDu = 0;
+ UnownedPtr<int> m_pISelEnd;
+ UnownedPtr<int> m_pISelStart;
+ bool m_bWillCommit = false;
+ bool m_bFieldFull = false;
+ bool m_bRcDu = false;
+ UnownedPtr<bool> m_pbRc;
};
#endif // FXJS_CJS_EVENT_CONTEXT_H_
diff --git a/fxjs/cjs_event_context_stub.cpp b/fxjs/cjs_event_context_stub.cpp
index 82530e4..b8d0518 100644
--- a/fxjs/cjs_event_context_stub.cpp
+++ b/fxjs/cjs_event_context_stub.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,7 +6,11 @@
#include "fxjs/cjs_event_context_stub.h"
-Optional<IJS_Runtime::JS_Error> CJS_EventContextStub::RunScript(
+CJS_EventContextStub::CJS_EventContextStub() = default;
+
+CJS_EventContextStub::~CJS_EventContextStub() = default;
+
+absl::optional<IJS_Runtime::JS_Error> CJS_EventContextStub::RunScript(
const WideString& script) {
return IJS_Runtime::JS_Error(1, 1, L"JavaScript support not present");
}
diff --git a/fxjs/cjs_event_context_stub.h b/fxjs/cjs_event_context_stub.h
index 06d0184..5c9b50a 100644
--- a/fxjs/cjs_event_context_stub.h
+++ b/fxjs/cjs_event_context_stub.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,24 +11,23 @@
class CJS_EventContextStub final : public IJS_EventContext {
public:
- CJS_EventContextStub() {}
- ~CJS_EventContextStub() override {}
+ CJS_EventContextStub();
+ ~CJS_EventContextStub() override;
// IJS_EventContext:
- Optional<IJS_Runtime::JS_Error> RunScript(const WideString& script) override;
+ absl::optional<IJS_Runtime::JS_Error> RunScript(
+ const WideString& script) override;
- void OnApp_Init() override {}
- void OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString& strTargetName) override {}
- void OnDoc_WillPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
- void OnDoc_DidPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
- void OnDoc_WillSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
- void OnDoc_DidSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
- void OnDoc_WillClose(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
- void OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
- void OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
- void OnPage_InView(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
- void OnPage_OutView(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
+ void OnDoc_Open(const WideString& strTargetName) override {}
+ void OnDoc_WillPrint() override {}
+ void OnDoc_DidPrint() override {}
+ void OnDoc_WillSave() override {}
+ void OnDoc_DidSave() override {}
+ void OnDoc_WillClose() override {}
+ void OnPage_Open() override {}
+ void OnPage_Close() override {}
+ void OnPage_InView() override {}
+ void OnPage_OutView() override {}
void OnField_MouseDown(bool bModifier,
bool bShift,
CPDF_FormField* pTarget) override {}
@@ -74,42 +73,6 @@
CPDF_FormField* pTarget,
WideString* Value,
bool* bRc) override {}
- void OnScreen_Focus(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override {}
- void OnScreen_Blur(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override {}
- void OnScreen_Open(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override {}
- void OnScreen_Close(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override {}
- void OnScreen_MouseDown(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override {}
- void OnScreen_MouseUp(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override {}
- void OnScreen_MouseEnter(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override {}
- void OnScreen_MouseExit(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override {}
- void OnScreen_InView(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override {}
- void OnScreen_OutView(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) override {}
- void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) override {}
- void OnLink_MouseUp(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
- void OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString&) override {}
- void OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv) override {}
- void OnConsole_Exec() override {}
void OnExternal_Exec() override {}
};
diff --git a/fxjs/cjs_eventrecorder.cpp b/fxjs/cjs_eventrecorder.cpp
deleted file mode 100644
index 59febf0..0000000
--- a/fxjs/cjs_eventrecorder.cpp
+++ /dev/null
@@ -1,558 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "fxjs/cjs_eventrecorder.h"
-
-#include "core/fpdfdoc/cpdf_bookmark.h"
-#include "core/fpdfdoc/cpdf_formfield.h"
-
-CJS_EventRecorder::CJS_EventRecorder() = default;
-
-CJS_EventRecorder::~CJS_EventRecorder() = default;
-
-void CJS_EventRecorder::OnApp_Init() {
- Initialize(JET_APP_INIT);
-}
-
-void CJS_EventRecorder::OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString& strTargetName) {
- Initialize(JET_DOC_OPEN);
- m_pTargetFormFillEnv.Reset(pFormFillEnv);
- m_strTargetName = strTargetName;
-}
-
-void CJS_EventRecorder::OnDoc_WillPrint(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- Initialize(JET_DOC_WILLPRINT);
- m_pTargetFormFillEnv.Reset(pFormFillEnv);
-}
-
-void CJS_EventRecorder::OnDoc_DidPrint(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- Initialize(JET_DOC_DIDPRINT);
- m_pTargetFormFillEnv.Reset(pFormFillEnv);
-}
-
-void CJS_EventRecorder::OnDoc_WillSave(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- Initialize(JET_DOC_WILLSAVE);
- m_pTargetFormFillEnv.Reset(pFormFillEnv);
-}
-
-void CJS_EventRecorder::OnDoc_DidSave(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- Initialize(JET_DOC_DIDSAVE);
- m_pTargetFormFillEnv.Reset(pFormFillEnv);
-}
-
-void CJS_EventRecorder::OnDoc_WillClose(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- Initialize(JET_DOC_WILLCLOSE);
- m_pTargetFormFillEnv.Reset(pFormFillEnv);
-}
-
-void CJS_EventRecorder::OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- Initialize(JET_PAGE_OPEN);
- m_pTargetFormFillEnv.Reset(pFormFillEnv);
-}
-
-void CJS_EventRecorder::OnPage_Close(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- Initialize(JET_PAGE_CLOSE);
- m_pTargetFormFillEnv.Reset(pFormFillEnv);
-}
-
-void CJS_EventRecorder::OnPage_InView(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- Initialize(JET_PAGE_INVIEW);
- m_pTargetFormFillEnv.Reset(pFormFillEnv);
-}
-
-void CJS_EventRecorder::OnPage_OutView(
- CPDFSDK_FormFillEnvironment* pFormFillEnv) {
- Initialize(JET_PAGE_OUTVIEW);
- m_pTargetFormFillEnv.Reset(pFormFillEnv);
-}
-
-void CJS_EventRecorder::OnField_MouseEnter(bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget) {
- Initialize(JET_FIELD_MOUSEENTER);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
-
- m_strTargetName = pTarget->GetFullName();
-}
-
-void CJS_EventRecorder::OnField_MouseExit(bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget) {
- Initialize(JET_FIELD_MOUSEEXIT);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_strTargetName = pTarget->GetFullName();
-}
-
-void CJS_EventRecorder::OnField_MouseDown(bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget) {
- Initialize(JET_FIELD_MOUSEDOWN);
- m_eEventType = JET_FIELD_MOUSEDOWN;
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_strTargetName = pTarget->GetFullName();
-}
-
-void CJS_EventRecorder::OnField_MouseUp(bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget) {
- Initialize(JET_FIELD_MOUSEUP);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_strTargetName = pTarget->GetFullName();
-}
-
-void CJS_EventRecorder::OnField_Focus(bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget,
- WideString* pValue) {
- ASSERT(pValue);
- Initialize(JET_FIELD_FOCUS);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_strTargetName = pTarget->GetFullName();
- m_pValue = pValue;
-}
-
-void CJS_EventRecorder::OnField_Blur(bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget,
- WideString* pValue) {
- ASSERT(pValue);
- Initialize(JET_FIELD_BLUR);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_strTargetName = pTarget->GetFullName();
- m_pValue = pValue;
-}
-
-void CJS_EventRecorder::OnField_Keystroke(WideString* strChange,
- const WideString& strChangeEx,
- bool KeyDown,
- bool bModifier,
- int* pSelEnd,
- int* pSelStart,
- bool bShift,
- CPDF_FormField* pTarget,
- WideString* pValue,
- bool bWillCommit,
- bool bFieldFull,
- bool* pbRc) {
- ASSERT(pValue);
- ASSERT(pbRc);
- ASSERT(pSelStart);
- ASSERT(pSelEnd);
-
- Initialize(JET_FIELD_KEYSTROKE);
-
- m_nCommitKey = 0;
- m_pWideStrChange = strChange;
- m_WideStrChangeEx = strChangeEx;
- m_bKeyDown = KeyDown;
- m_bModifier = bModifier;
- m_pISelEnd = pSelEnd;
- m_pISelStart = pSelStart;
- m_bShift = bShift;
- m_strTargetName = pTarget->GetFullName();
- m_pValue = pValue;
- m_bWillCommit = bWillCommit;
- m_pbRc = pbRc;
- m_bFieldFull = bFieldFull;
-}
-
-void CJS_EventRecorder::OnField_Validate(WideString* strChange,
- const WideString& strChangeEx,
- bool bKeyDown,
- bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget,
- WideString* pValue,
- bool* pbRc) {
- ASSERT(pValue);
- ASSERT(pbRc);
-
- Initialize(JET_FIELD_VALIDATE);
-
- m_pWideStrChange = strChange;
- m_WideStrChangeEx = strChangeEx;
- m_bKeyDown = bKeyDown;
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_strTargetName = pTarget->GetFullName();
- m_pValue = pValue;
- m_pbRc = pbRc;
-}
-
-void CJS_EventRecorder::OnField_Calculate(CPDF_FormField* pSource,
- CPDF_FormField* pTarget,
- WideString* pValue,
- bool* pRc) {
- ASSERT(pValue);
- ASSERT(pRc);
-
- Initialize(JET_FIELD_CALCULATE);
-
- if (pSource)
- m_strSourceName = pSource->GetFullName();
- m_strTargetName = pTarget->GetFullName();
- m_pValue = pValue;
- m_pbRc = pRc;
-}
-
-void CJS_EventRecorder::OnField_Format(CPDF_FormField* pTarget,
- WideString* pValue) {
- ASSERT(pValue);
- Initialize(JET_FIELD_FORMAT);
-
- m_nCommitKey = 0;
- m_strTargetName = pTarget->GetFullName();
- m_pValue = pValue;
- m_bWillCommit = true;
-}
-
-void CJS_EventRecorder::OnScreen_Focus(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- Initialize(JET_SCREEN_FOCUS);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_Blur(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- Initialize(JET_SCREEN_BLUR);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_Open(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- Initialize(JET_SCREEN_OPEN);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_Close(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- Initialize(JET_SCREEN_CLOSE);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_MouseDown(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- Initialize(JET_SCREEN_MOUSEDOWN);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_MouseUp(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- Initialize(JET_SCREEN_MOUSEUP);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_MouseEnter(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- Initialize(JET_SCREEN_MOUSEENTER);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_MouseExit(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- Initialize(JET_SCREEN_MOUSEEXIT);
-
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_InView(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- Initialize(JET_SCREEN_INVIEW);
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_OutView(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) {
- Initialize(JET_SCREEN_OUTVIEW);
- m_bModifier = bModifier;
- m_bShift = bShift;
- m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnLink_MouseUp(
- CPDFSDK_FormFillEnvironment* pTargetFormFillEnv) {
- Initialize(JET_LINK_MOUSEUP);
- m_pTargetFormFillEnv.Reset(pTargetFormFillEnv);
-}
-
-void CJS_EventRecorder::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) {
- Initialize(JET_BOOKMARK_MOUSEUP);
- m_pTargetBookMark = pBookMark;
-}
-
-void CJS_EventRecorder::OnMenu_Exec(
- CPDFSDK_FormFillEnvironment* pTargetFormFillEnv,
- const WideString& strTargetName) {
- Initialize(JET_MENU_EXEC);
- m_pTargetFormFillEnv.Reset(pTargetFormFillEnv);
- m_strTargetName = strTargetName;
-}
-
-void CJS_EventRecorder::OnExternal_Exec() {
- Initialize(JET_EXTERNAL_EXEC);
-}
-
-void CJS_EventRecorder::OnBatchExec(
- CPDFSDK_FormFillEnvironment* pTargetFormFillEnv) {
- Initialize(JET_BATCH_EXEC);
- m_pTargetFormFillEnv.Reset(pTargetFormFillEnv);
-}
-
-void CJS_EventRecorder::OnConsole_Exec() {
- Initialize(JET_CONSOLE_EXEC);
-}
-
-void CJS_EventRecorder::Initialize(JS_EVENT_T type) {
- m_eEventType = type;
- m_strTargetName.clear();
- m_strSourceName.clear();
- m_pWideStrChange = nullptr;
- m_WideStrChangeDu.clear();
- m_WideStrChangeEx.clear();
- m_nCommitKey = -1;
- m_bKeyDown = false;
- m_bModifier = false;
- m_bShift = false;
- m_pISelEnd = nullptr;
- m_nSelEndDu = 0;
- m_pISelStart = nullptr;
- m_nSelStartDu = 0;
- m_bWillCommit = false;
- m_pValue = nullptr;
- m_bFieldFull = false;
- m_pbRc = nullptr;
- m_bRcDu = false;
- m_pTargetBookMark = nullptr;
- m_pTargetFormFillEnv.Reset();
- m_pTargetAnnot.Reset();
- m_bValid = true;
-}
-
-void CJS_EventRecorder::Destroy() {
- m_bValid = false;
-}
-
-bool CJS_EventRecorder::IsUserGesture() const {
- switch (m_eEventType) {
- case JET_FIELD_MOUSEDOWN:
- case JET_FIELD_MOUSEUP:
- case JET_SCREEN_MOUSEDOWN:
- case JET_SCREEN_MOUSEUP:
- case JET_BOOKMARK_MOUSEUP:
- case JET_LINK_MOUSEUP:
- case JET_FIELD_KEYSTROKE:
- return true;
- default:
- return false;
- }
-}
-
-WideString& CJS_EventRecorder::Change() {
- return m_pWideStrChange ? *m_pWideStrChange : m_WideStrChangeDu;
-}
-
-ByteStringView CJS_EventRecorder::Name() const {
- switch (m_eEventType) {
- case JET_APP_INIT:
- return "Init";
- case JET_BATCH_EXEC:
- return "Exec";
- case JET_BOOKMARK_MOUSEUP:
- return "Mouse Up";
- case JET_CONSOLE_EXEC:
- return "Exec";
- case JET_DOC_DIDPRINT:
- return "DidPrint";
- case JET_DOC_DIDSAVE:
- return "DidSave";
- case JET_DOC_OPEN:
- return "Open";
- case JET_DOC_WILLCLOSE:
- return "WillClose";
- case JET_DOC_WILLPRINT:
- return "WillPrint";
- case JET_DOC_WILLSAVE:
- return "WillSave";
- case JET_EXTERNAL_EXEC:
- return "Exec";
- case JET_FIELD_FOCUS:
- case JET_SCREEN_FOCUS:
- return "Focus";
- case JET_FIELD_BLUR:
- case JET_SCREEN_BLUR:
- return "Blur";
- case JET_FIELD_MOUSEDOWN:
- case JET_SCREEN_MOUSEDOWN:
- return "Mouse Down";
- case JET_FIELD_MOUSEUP:
- case JET_SCREEN_MOUSEUP:
- return "Mouse Up";
- case JET_FIELD_MOUSEENTER:
- case JET_SCREEN_MOUSEENTER:
- return "Mouse Enter";
- case JET_FIELD_MOUSEEXIT:
- case JET_SCREEN_MOUSEEXIT:
- return "Mouse Exit";
- case JET_FIELD_CALCULATE:
- return "Calculate";
- case JET_FIELD_FORMAT:
- return "Format";
- case JET_FIELD_KEYSTROKE:
- return "Keystroke";
- case JET_FIELD_VALIDATE:
- return "Validate";
- case JET_LINK_MOUSEUP:
- return "Mouse Up";
- case JET_MENU_EXEC:
- return "Exec";
- case JET_PAGE_OPEN:
- case JET_SCREEN_OPEN:
- return "Open";
- case JET_PAGE_CLOSE:
- case JET_SCREEN_CLOSE:
- return "Close";
- case JET_SCREEN_INVIEW:
- case JET_PAGE_INVIEW:
- return "InView";
- case JET_PAGE_OUTVIEW:
- case JET_SCREEN_OUTVIEW:
- return "OutView";
- default:
- return "";
- }
-}
-
-ByteStringView CJS_EventRecorder::Type() const {
- switch (m_eEventType) {
- case JET_APP_INIT:
- return "App";
- case JET_BATCH_EXEC:
- return "Batch";
- case JET_BOOKMARK_MOUSEUP:
- return "BookMark";
- case JET_CONSOLE_EXEC:
- return "Console";
- case JET_DOC_DIDPRINT:
- case JET_DOC_DIDSAVE:
- case JET_DOC_OPEN:
- case JET_DOC_WILLCLOSE:
- case JET_DOC_WILLPRINT:
- case JET_DOC_WILLSAVE:
- return "Doc";
- case JET_EXTERNAL_EXEC:
- return "External";
- case JET_FIELD_BLUR:
- case JET_FIELD_FOCUS:
- case JET_FIELD_MOUSEDOWN:
- case JET_FIELD_MOUSEENTER:
- case JET_FIELD_MOUSEEXIT:
- case JET_FIELD_MOUSEUP:
- case JET_FIELD_CALCULATE:
- case JET_FIELD_FORMAT:
- case JET_FIELD_KEYSTROKE:
- case JET_FIELD_VALIDATE:
- return "Field";
- case JET_SCREEN_FOCUS:
- case JET_SCREEN_BLUR:
- case JET_SCREEN_OPEN:
- case JET_SCREEN_CLOSE:
- case JET_SCREEN_MOUSEDOWN:
- case JET_SCREEN_MOUSEUP:
- case JET_SCREEN_MOUSEENTER:
- case JET_SCREEN_MOUSEEXIT:
- case JET_SCREEN_INVIEW:
- case JET_SCREEN_OUTVIEW:
- return "Screen";
- case JET_LINK_MOUSEUP:
- return "Link";
- case JET_MENU_EXEC:
- return "Menu";
- case JET_PAGE_OPEN:
- case JET_PAGE_CLOSE:
- case JET_PAGE_INVIEW:
- case JET_PAGE_OUTVIEW:
- return "Page";
- default:
- return "";
- }
-}
-
-bool& CJS_EventRecorder::Rc() {
- return m_pbRc ? *m_pbRc : m_bRcDu;
-}
-
-int CJS_EventRecorder::SelEnd() const {
- return m_pISelEnd ? *m_pISelEnd : m_nSelEndDu;
-}
-
-int CJS_EventRecorder::SelStart() const {
- return m_pISelStart ? *m_pISelStart : m_nSelStartDu;
-}
-
-void CJS_EventRecorder::SetSelEnd(int value) {
- int& target = m_pISelEnd ? *m_pISelEnd : m_nSelEndDu;
- target = value;
-}
-
-void CJS_EventRecorder::SetSelStart(int value) {
- int& target = m_pISelStart ? *m_pISelStart : m_nSelStartDu;
- target = value;
-}
diff --git a/fxjs/cjs_eventrecorder.h b/fxjs/cjs_eventrecorder.h
deleted file mode 100644
index acf9856..0000000
--- a/fxjs/cjs_eventrecorder.h
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef FXJS_CJS_EVENTRECORDER_H_
-#define FXJS_CJS_EVENTRECORDER_H_
-
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-#include "core/fxcrt/unowned_ptr.h"
-#include "fpdfsdk/cpdfsdk_annot.h"
-#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
-
-class CPDF_Bookmark;
-class CPDF_FormField;
-
-enum JS_EVENT_T {
- JET_UNKNOWN,
- JET_APP_INIT,
- JET_DOC_OPEN,
- JET_DOC_WILLPRINT,
- JET_DOC_DIDPRINT,
- JET_DOC_WILLSAVE,
- JET_DOC_DIDSAVE,
- JET_DOC_WILLCLOSE,
- JET_PAGE_OPEN,
- JET_PAGE_CLOSE,
- JET_PAGE_INVIEW,
- JET_PAGE_OUTVIEW,
- JET_FIELD_MOUSEDOWN,
- JET_FIELD_MOUSEUP,
- JET_FIELD_MOUSEENTER,
- JET_FIELD_MOUSEEXIT,
- JET_FIELD_FOCUS,
- JET_FIELD_BLUR,
- JET_FIELD_KEYSTROKE,
- JET_FIELD_VALIDATE,
- JET_FIELD_CALCULATE,
- JET_FIELD_FORMAT,
- JET_SCREEN_FOCUS,
- JET_SCREEN_BLUR,
- JET_SCREEN_OPEN,
- JET_SCREEN_CLOSE,
- JET_SCREEN_MOUSEDOWN,
- JET_SCREEN_MOUSEUP,
- JET_SCREEN_MOUSEENTER,
- JET_SCREEN_MOUSEEXIT,
- JET_SCREEN_INVIEW,
- JET_SCREEN_OUTVIEW,
- JET_BATCH_EXEC,
- JET_MENU_EXEC,
- JET_CONSOLE_EXEC,
- JET_EXTERNAL_EXEC,
- JET_BOOKMARK_MOUSEUP,
- JET_LINK_MOUSEUP
-};
-
-class CJS_EventRecorder {
- public:
- CJS_EventRecorder();
- ~CJS_EventRecorder();
-
- void OnApp_Init();
-
- void OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString& strTargetName);
- void OnDoc_WillPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv);
- void OnDoc_DidPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv);
- void OnDoc_WillSave(CPDFSDK_FormFillEnvironment* pFormFillEnv);
- void OnDoc_DidSave(CPDFSDK_FormFillEnvironment* pFormFillEnv);
- void OnDoc_WillClose(CPDFSDK_FormFillEnvironment* pFormFillEnv);
-
- void OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv);
- void OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv);
- void OnPage_InView(CPDFSDK_FormFillEnvironment* pFormFillEnv);
- void OnPage_OutView(CPDFSDK_FormFillEnvironment* pFormFillEnv);
-
- void OnField_Calculate(CPDF_FormField* pSource,
- CPDF_FormField* pTarget,
- WideString* Value,
- bool* pbRc);
- void OnField_Format(CPDF_FormField* pTarget, WideString* Value);
- void OnField_Keystroke(WideString* strChange,
- const WideString& strChangeEx,
- bool KeyDown,
- bool bModifier,
- int* nSelEnd,
- int* nSelStart,
- bool bShift,
- CPDF_FormField* pTarget,
- WideString* Value,
- bool bWillCommit,
- bool bFieldFull,
- bool* bRc);
- void OnField_Validate(WideString* strChange,
- const WideString& strChangeEx,
- bool bKeyDown,
- bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget,
- WideString* Value,
- bool* bRc);
- void OnField_MouseDown(bool bModifier, bool bShift, CPDF_FormField* pTarget);
- void OnField_MouseEnter(bool bModifier, bool bShift, CPDF_FormField* pTarget);
- void OnField_MouseExit(bool bModifier, bool bShift, CPDF_FormField* pTarget);
- void OnField_MouseUp(bool bModifier, bool bShift, CPDF_FormField* pTarget);
- void OnField_Blur(bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget,
- WideString* Value);
- void OnField_Focus(bool bModifier,
- bool bShift,
- CPDF_FormField* pTarget,
- WideString* Value);
-
- void OnScreen_Focus(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
- void OnScreen_Blur(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
- void OnScreen_Open(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
- void OnScreen_Close(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
- void OnScreen_MouseDown(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
- void OnScreen_MouseUp(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
- void OnScreen_MouseEnter(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
- void OnScreen_MouseExit(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
- void OnScreen_InView(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
- void OnScreen_OutView(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-
- void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark);
- void OnLink_MouseUp(CPDFSDK_FormFillEnvironment* pFormFillEnv);
-
- void OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString& strTargetName);
- void OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv);
- void OnConsole_Exec();
- void OnExternal_Exec();
-
- void Destroy();
-
- JS_EVENT_T EventType() const { return m_eEventType; }
- bool IsValid() const { return m_bValid; }
- bool IsUserGesture() const;
- WideString& Change();
- WideString ChangeEx() const { return m_WideStrChangeEx; }
- WideString SourceName() const { return m_strSourceName; }
- WideString TargetName() const { return m_strTargetName; }
- int CommitKey() const { return m_nCommitKey; }
- bool FieldFull() const { return m_bFieldFull; }
- bool KeyDown() const { return m_bKeyDown; }
- bool Modifier() const { return m_bModifier; }
- ByteStringView Name() const;
- ByteStringView Type() const;
- bool& Rc();
- int SelEnd() const;
- int SelStart() const;
- void SetSelEnd(int value);
- void SetSelStart(int value);
- bool Shift() const { return m_bShift; }
- bool HasValue() const { return !!m_pValue; }
- WideString& Value() { return *m_pValue; }
- bool WillCommit() const { return m_bWillCommit; }
- CPDFSDK_FormFillEnvironment* GetFormFillEnvironment() const {
- return m_pTargetFormFillEnv.Get();
- }
-
- void SetValueForTest(WideString* pStr) { m_pValue = pStr; }
- void SetRCForTest(bool* pRC) { m_pbRc = pRC; }
- void SetStrChangeForTest(WideString* pStrChange) {
- m_pWideStrChange = pStrChange;
- }
- void ResetWillCommitForTest() { m_bWillCommit = false; }
-
- private:
- void Initialize(JS_EVENT_T type);
-
- JS_EVENT_T m_eEventType = JET_UNKNOWN;
- bool m_bValid = false;
- UnownedPtr<WideString> m_pValue;
- WideString m_strSourceName;
- WideString m_strTargetName;
- WideString m_WideStrChangeDu;
- WideString m_WideStrChangeEx;
- UnownedPtr<WideString> m_pWideStrChange;
- int m_nCommitKey = -1;
- bool m_bKeyDown = false;
- bool m_bModifier = false;
- bool m_bShift = false;
- int m_nSelEndDu = 0;
- int m_nSelStartDu = 0;
- UnownedPtr<int> m_pISelEnd;
- UnownedPtr<int> m_pISelStart;
- bool m_bWillCommit = false;
- bool m_bFieldFull = false;
- bool m_bRcDu = false;
- UnownedPtr<bool> m_pbRc;
- UnownedPtr<CPDF_Bookmark> m_pTargetBookMark;
- ObservedPtr<CPDFSDK_FormFillEnvironment> m_pTargetFormFillEnv;
- ObservedPtr<CPDFSDK_Annot> m_pTargetAnnot;
-};
-
-#endif // FXJS_CJS_EVENTRECORDER_H_
diff --git a/fxjs/cjs_field.cpp b/fxjs/cjs_field.cpp
index b6aa9bb..53b3449 100644
--- a/fxjs/cjs_field.cpp
+++ b/fxjs/cjs_field.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,12 +10,14 @@
#include <memory>
#include <utility>
+#include "constants/access_permissions.h"
#include "constants/annotation_flags.h"
#include "constants/form_flags.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfdoc/cpdf_formcontrol.h"
#include "core/fpdfdoc/cpdf_formfield.h"
#include "core/fpdfdoc/cpdf_interactiveform.h"
-#include "fpdfsdk/cpdfsdk_helpers.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_interactiveform.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "fpdfsdk/cpdfsdk_widget.h"
@@ -23,11 +25,22 @@
#include "fxjs/cjs_delaydata.h"
#include "fxjs/cjs_document.h"
#include "fxjs/cjs_icon.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
-#include "third_party/base/ptr_util.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/base/check.h"
+#include "third_party/base/notreached.h"
+#include "v8/include/v8-container.h"
namespace {
+constexpr wchar_t kCheckSelector = L'4';
+constexpr wchar_t kCircleSelector = L'l';
+constexpr wchar_t kCrossSelector = L'8';
+constexpr wchar_t kDiamondSelector = L'u';
+constexpr wchar_t kSquareSelector = L'n';
+constexpr wchar_t kStarSelector = L'H';
+
bool IsCheckBoxOrRadioButton(const CPDF_FormField* pFormField) {
return pFormField->GetFieldType() == FormFieldType::kCheckBox ||
pFormField->GetFieldType() == FormFieldType::kRadioButton;
@@ -45,121 +58,99 @@
void UpdateFormField(CPDFSDK_FormFillEnvironment* pFormFillEnv,
CPDF_FormField* pFormField,
- bool bChangeMark,
- bool bResetAP,
- bool bRefresh) {
+ bool bResetAP) {
CPDFSDK_InteractiveForm* pForm = pFormFillEnv->GetInteractiveForm();
-
if (bResetAP) {
- std::vector<ObservedPtr<CPDFSDK_Annot>> widgets;
+ std::vector<ObservedPtr<CPDFSDK_Widget>> widgets;
pForm->GetWidgets(pFormField, &widgets);
if (IsComboBoxOrTextField(pFormField)) {
- for (auto& pObserved : widgets) {
- if (pObserved) {
- Optional<WideString> sValue =
- ToCPDFSDKWidget(pObserved.Get())->OnFormat();
- if (pObserved) { // Not redundant, may be clobbered by OnFormat.
- ToCPDFSDKWidget(pObserved.Get())->ResetAppearance(sValue, false);
+ for (auto& pWidget : widgets) {
+ if (pWidget) {
+ absl::optional<WideString> sValue = pWidget->OnFormat();
+ if (pWidget) { // Not redundant, may be clobbered by OnFormat.
+ pWidget->ResetAppearance(sValue, CPDFSDK_Widget::kValueUnchanged);
}
}
}
} else {
- for (auto& pObserved : widgets) {
- if (pObserved)
- ToCPDFSDKWidget(pObserved.Get())->ResetAppearance({}, false);
+ for (auto& pWidget : widgets) {
+ if (pWidget) {
+ pWidget->ResetAppearance(absl::nullopt,
+ CPDFSDK_Widget::kValueUnchanged);
+ }
}
}
}
- if (bRefresh) {
- // Refresh the widget list. The calls in |bResetAP| may have caused widgets
- // to be removed from the list. We need to call |GetWidgets| again to be
- // sure none of the widgets have been deleted.
- std::vector<ObservedPtr<CPDFSDK_Annot>> widgets;
- pForm->GetWidgets(pFormField, &widgets);
-
- // TODO(dsinclair): Determine if all widgets share the same
- // CPDFSDK_InteractiveForm. If that's the case, we can move the code to
- // |GetFormFillEnv| out of the loop.
- for (auto& pObserved : widgets) {
- if (pObserved) {
- CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pObserved.Get());
- pWidget->GetInteractiveForm()->GetFormFillEnv()->UpdateAllViews(
- nullptr, pWidget);
- }
- }
+ // Refresh the widget list. The calls in |bResetAP| may have caused widgets
+ // to be removed from the list. We need to call |GetWidgets| again to be
+ // sure none of the widgets have been deleted.
+ std::vector<ObservedPtr<CPDFSDK_Widget>> widgets;
+ pForm->GetWidgets(pFormField, &widgets);
+ for (auto& pWidget : widgets) {
+ if (pWidget)
+ pFormFillEnv->UpdateAllViews(pWidget.Get());
}
-
- if (bChangeMark)
- pFormFillEnv->SetChangeMark();
+ pFormFillEnv->SetChangeMark();
}
void UpdateFormControl(CPDFSDK_FormFillEnvironment* pFormFillEnv,
CPDF_FormControl* pFormControl,
- bool bChangeMark,
- bool bResetAP,
- bool bRefresh) {
- ASSERT(pFormControl);
-
+ bool bResetAP) {
+ DCHECK(pFormControl);
CPDFSDK_InteractiveForm* pForm = pFormFillEnv->GetInteractiveForm();
CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl);
-
if (pWidget) {
ObservedPtr<CPDFSDK_Widget> observed_widget(pWidget);
if (bResetAP) {
FormFieldType fieldType = pWidget->GetFieldType();
if (fieldType == FormFieldType::kComboBox ||
fieldType == FormFieldType::kTextField) {
- Optional<WideString> sValue = pWidget->OnFormat();
+ absl::optional<WideString> sValue = pWidget->OnFormat();
if (!observed_widget)
return;
- pWidget->ResetAppearance(sValue, false);
+ pWidget->ResetAppearance(sValue, CPDFSDK_Widget::kValueUnchanged);
} else {
- pWidget->ResetAppearance({}, false);
+ pWidget->ResetAppearance(absl::nullopt,
+ CPDFSDK_Widget::kValueUnchanged);
}
if (!observed_widget)
return;
}
-
- if (bRefresh) {
- CPDFSDK_InteractiveForm* pWidgetForm = pWidget->GetInteractiveForm();
- pWidgetForm->GetFormFillEnv()->UpdateAllViews(nullptr, pWidget);
- }
+ pFormFillEnv->UpdateAllViews(pWidget);
}
-
- if (bChangeMark)
- pFormFillEnv->SetChangeMark();
+ pFormFillEnv->SetChangeMark();
}
-// note: iControlNo = -1, means not a widget.
-void ParseFieldName(const WideString& strFieldNameParsed,
- WideString& strFieldName,
- int& iControlNo) {
- auto reverse_it = strFieldNameParsed.rbegin();
- while (reverse_it != strFieldNameParsed.rend()) {
+struct FieldNameData {
+ FieldNameData(WideString field_name_in, int control_index_in)
+ : field_name(field_name_in), control_index(control_index_in) {}
+
+ WideString field_name;
+ int control_index;
+};
+
+absl::optional<FieldNameData> ParseFieldName(const WideString& field_name) {
+ auto reverse_it = field_name.rbegin();
+ while (reverse_it != field_name.rend()) {
if (*reverse_it == L'.')
break;
++reverse_it;
}
- if (reverse_it == strFieldNameParsed.rend()) {
- strFieldName = strFieldNameParsed;
- iControlNo = -1;
- return;
+ if (reverse_it == field_name.rend()) {
+ return absl::nullopt;
}
- WideString suffixal =
- strFieldNameParsed.Last(reverse_it - strFieldNameParsed.rbegin());
- iControlNo = FXSYS_wtoi(suffixal.c_str());
- if (iControlNo == 0) {
+ WideString suffixal = field_name.Last(reverse_it - field_name.rbegin());
+ int control_index = FXSYS_wtoi(suffixal.c_str());
+ if (control_index == 0) {
suffixal.TrimRight(L' ');
if (suffixal != L"0") {
- strFieldName = strFieldNameParsed;
- iControlNo = -1;
- return;
+ return absl::nullopt;
}
}
- strFieldName =
- strFieldNameParsed.First(strFieldNameParsed.rend() - reverse_it - 1);
+ return FieldNameData(field_name.First(field_name.rend() - reverse_it - 1),
+ control_index);
}
std::vector<CPDF_FormField*> GetFormFieldsForName(
@@ -168,13 +159,37 @@
std::vector<CPDF_FormField*> fields;
CPDFSDK_InteractiveForm* pReaderForm = pFormFillEnv->GetInteractiveForm();
CPDF_InteractiveForm* pForm = pReaderForm->GetInteractiveForm();
- for (int i = 0, sz = pForm->CountFields(csFieldName); i < sz; ++i) {
- if (CPDF_FormField* pFormField = pForm->GetField(i, csFieldName))
+ const size_t sz = pForm->CountFields(csFieldName);
+ for (size_t i = 0; i < sz; ++i) {
+ CPDF_FormField* pFormField = pForm->GetField(i, csFieldName);
+ if (pFormField)
fields.push_back(pFormField);
}
return fields;
}
+CFX_Color GetFormControlColor(CPDF_FormControl* pFormControl,
+ const ByteString& entry) {
+ switch (pFormControl->GetColorARGB(entry).color_type) {
+ case CFX_Color::Type::kTransparent:
+ return CFX_Color(CFX_Color::Type::kTransparent);
+ case CFX_Color::Type::kGray:
+ return CFX_Color(CFX_Color::Type::kGray,
+ pFormControl->GetOriginalColorComponent(0, entry));
+ case CFX_Color::Type::kRGB:
+ return CFX_Color(CFX_Color::Type::kRGB,
+ pFormControl->GetOriginalColorComponent(0, entry),
+ pFormControl->GetOriginalColorComponent(1, entry),
+ pFormControl->GetOriginalColorComponent(2, entry));
+ case CFX_Color::Type::kCMYK:
+ return CFX_Color(CFX_Color::Type::kCMYK,
+ pFormControl->GetOriginalColorComponent(0, entry),
+ pFormControl->GetOriginalColorComponent(1, entry),
+ pFormControl->GetOriginalColorComponent(2, entry),
+ pFormControl->GetOriginalColorComponent(3, entry));
+ }
+}
+
bool SetWidgetDisplayStatus(CPDFSDK_Widget* pWidget, int value) {
if (!pWidget)
return false;
@@ -217,20 +232,20 @@
void SetBorderStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv,
const WideString& swFieldName,
int nControlIndex,
- const ByteString& string) {
- ASSERT(pFormFillEnv);
+ const ByteString& bsString) {
+ DCHECK(pFormFillEnv);
- BorderStyle nBorderStyle = BorderStyle::SOLID;
- if (string == "solid")
- nBorderStyle = BorderStyle::SOLID;
- else if (string == "beveled")
- nBorderStyle = BorderStyle::BEVELED;
- else if (string == "dashed")
- nBorderStyle = BorderStyle::DASH;
- else if (string == "inset")
- nBorderStyle = BorderStyle::INSET;
- else if (string == "underline")
- nBorderStyle = BorderStyle::UNDERLINE;
+ BorderStyle nBorderStyle = BorderStyle::kSolid;
+ if (bsString == "solid")
+ nBorderStyle = BorderStyle::kSolid;
+ else if (bsString == "beveled")
+ nBorderStyle = BorderStyle::kBeveled;
+ else if (bsString == "dashed")
+ nBorderStyle = BorderStyle::kDash;
+ else if (bsString == "inset")
+ nBorderStyle = BorderStyle::kInset;
+ else if (bsString == "underline")
+ nBorderStyle = BorderStyle::kUnderline;
else
return;
@@ -250,7 +265,7 @@
}
}
if (bSet)
- UpdateFormField(pFormFillEnv, pFormField, true, true, true);
+ UpdateFormField(pFormFillEnv, pFormField, true);
} else {
if (nControlIndex >= pFormField->CountControls())
return;
@@ -260,7 +275,7 @@
if (pWidget) {
if (pWidget->GetBorderStyle() != nBorderStyle) {
pWidget->SetBorderStyle(nBorderStyle);
- UpdateFormControl(pFormFillEnv, pFormControl, true, true, true);
+ UpdateFormControl(pFormFillEnv, pFormControl, true);
}
}
}
@@ -272,7 +287,7 @@
const WideString& swFieldName,
int nControlIndex,
const std::vector<uint32_t>& array) {
- ASSERT(pFormFillEnv);
+ DCHECK(pFormFillEnv);
std::vector<CPDF_FormField*> FieldArray =
GetFormFieldsForName(pFormFillEnv, swFieldName);
@@ -287,11 +302,11 @@
break;
if (array[i] < static_cast<uint32_t>(pFormField->CountOptions()) &&
!pFormField->IsItemSelected(array[i])) {
- pFormField->SetItemSelection(array[i], true,
+ pFormField->SetItemSelection(array[i],
NotificationOption::kDoNotNotify);
}
}
- UpdateFormField(pFormFillEnv, pFormField, true, true, true);
+ UpdateFormField(pFormFillEnv, pFormField, true);
}
}
@@ -307,7 +322,7 @@
bool bAnySet = false;
for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
CPDF_FormControl* pFormControl = pFormField->GetControl(i);
- ASSERT(pFormControl);
+ DCHECK(pFormControl);
CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl);
if (SetWidgetDisplayStatus(pWidget, number))
@@ -315,7 +330,7 @@
}
if (bAnySet)
- UpdateFormField(pFormFillEnv, pFormField, true, false, true);
+ UpdateFormField(pFormFillEnv, pFormField, false);
} else {
if (nControlIndex >= pFormField->CountControls())
return;
@@ -326,7 +341,7 @@
CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl);
if (SetWidgetDisplayStatus(pWidget, number))
- UpdateFormControl(pFormFillEnv, pFormControl, true, false, true);
+ UpdateFormControl(pFormFillEnv, pFormControl, false);
}
}
}
@@ -351,7 +366,7 @@
bool bSet = false;
for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
CPDF_FormControl* pFormControl = pFormField->GetControl(i);
- ASSERT(pFormControl);
+ DCHECK(pFormControl);
if (CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl)) {
if (number != pWidget->GetBorderWidth()) {
@@ -361,7 +376,7 @@
}
}
if (bSet)
- UpdateFormField(pFormFillEnv, pFormField, true, true, true);
+ UpdateFormField(pFormFillEnv, pFormField, true);
} else {
if (nControlIndex >= pFormField->CountControls())
return;
@@ -370,7 +385,7 @@
if (CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl)) {
if (number != pWidget->GetBorderWidth()) {
pWidget->SetBorderWidth(number);
- UpdateFormControl(pFormFillEnv, pFormControl, true, true, true);
+ UpdateFormControl(pFormFillEnv, pFormControl, true);
}
}
}
@@ -390,7 +405,7 @@
bool bSet = false;
for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
CPDF_FormControl* pFormControl = pFormField->GetControl(i);
- ASSERT(pFormControl);
+ DCHECK(pFormControl);
if (CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl)) {
CFX_FloatRect crRect = rect;
@@ -410,7 +425,7 @@
}
if (bSet)
- UpdateFormField(pFormFillEnv, pFormField, true, true, true);
+ UpdateFormField(pFormFillEnv, pFormField, true);
continue;
}
@@ -428,7 +443,7 @@
if (crRect.left != rcOld.left || crRect.right != rcOld.right ||
crRect.top != rcOld.top || crRect.bottom != rcOld.bottom) {
pWidget->SetRect(crRect);
- UpdateFormControl(pFormFillEnv, pFormControl, true, true, true);
+ UpdateFormControl(pFormFillEnv, pFormControl, true);
}
}
}
@@ -440,7 +455,7 @@
const WideString& swFieldName,
int nControlIndex,
const std::vector<WideString>& strArray) {
- ASSERT(pFormFillEnv);
+ DCHECK(pFormFillEnv);
if (strArray.empty())
return;
@@ -448,7 +463,7 @@
GetFormFieldsForName(pFormFillEnv, swFieldName);
for (CPDF_FormField* pFormField : FieldArray) {
- if (pFormField->GetFullName().Compare(swFieldName) != 0)
+ if (pFormField->GetFullName() != swFieldName)
continue;
switch (pFormField->GetFieldType()) {
@@ -456,14 +471,14 @@
case FormFieldType::kComboBox:
if (pFormField->GetValue() != strArray[0]) {
pFormField->SetValue(strArray[0], NotificationOption::kNotify);
- UpdateFormField(pFormFillEnv, pFormField, true, false, true);
+ UpdateFormField(pFormFillEnv, pFormField, false);
}
break;
case FormFieldType::kCheckBox:
case FormFieldType::kRadioButton:
if (pFormField->GetValue() != strArray[0]) {
pFormField->SetValue(strArray[0], NotificationOption::kNotify);
- UpdateFormField(pFormFillEnv, pFormField, true, false, true);
+ UpdateFormField(pFormFillEnv, pFormField, false);
}
break;
case FormFieldType::kListBox: {
@@ -479,10 +494,9 @@
for (const auto& str : strArray) {
int index = pFormField->FindOption(str);
if (!pFormField->IsItemSelected(index))
- pFormField->SetItemSelection(index, true,
- NotificationOption::kNotify);
+ pFormField->SetItemSelection(index, NotificationOption::kNotify);
}
- UpdateFormField(pFormFillEnv, pFormField, true, false, true);
+ UpdateFormField(pFormFillEnv, pFormField, false);
}
break;
}
@@ -492,6 +506,19 @@
}
}
+wchar_t GetSelectorFromCaptionForFieldType(const WideString& caption,
+ CPDF_FormField::Type type) {
+ if (!caption.IsEmpty())
+ return caption[0];
+
+ switch (type) {
+ case CPDF_FormField::kRadioButton:
+ return kCircleSelector;
+ default:
+ return kCheckSelector;
+ }
+}
+
} // namespace
const JSPropertySpec CJS_Field::PropertySpecs[] = {
@@ -585,11 +612,11 @@
{"signatureSign", signatureSign_static},
{"signatureValidate", signatureValidate_static}};
-int CJS_Field::ObjDefnID = -1;
+uint32_t CJS_Field::ObjDefnID = 0;
const char CJS_Field::kName[] = "Field";
// static
-int CJS_Field::GetObjDefnID() {
+uint32_t CJS_Field::GetObjDefnID() {
return ObjDefnID;
}
@@ -610,9 +637,10 @@
const WideString& csFieldName) {
m_pJSDoc.Reset(pDocument);
m_pFormFillEnv.Reset(pDocument->GetFormFillEnv());
- m_bCanSet = m_pFormFillEnv->GetPermissions(FPDFPERM_FILL_FORM) ||
- m_pFormFillEnv->GetPermissions(FPDFPERM_ANNOT_FORM) ||
- m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY);
+ m_bCanSet = m_pFormFillEnv->HasPermissions(
+ pdfium::access_permissions::kFillForm |
+ pdfium::access_permissions::kModifyAnnotation |
+ pdfium::access_permissions::kModifyContent);
CPDFSDK_InteractiveForm* pRDForm = m_pFormFillEnv->GetInteractiveForm();
CPDF_InteractiveForm* pForm = pRDForm->GetInteractiveForm();
@@ -620,14 +648,12 @@
swFieldNameTemp.Replace(L"..", L".");
if (pForm->CountFields(swFieldNameTemp) <= 0) {
- WideString strFieldName;
- int iControlNo = -1;
- ParseFieldName(swFieldNameTemp, strFieldName, iControlNo);
- if (iControlNo == -1)
+ absl::optional<FieldNameData> parsed_data = ParseFieldName(swFieldNameTemp);
+ if (!parsed_data.has_value())
return false;
- m_FieldName = strFieldName;
- m_nFormControlIndex = iControlNo;
+ m_FieldName = parsed_data.value().field_name;
+ m_nFormControlIndex = parsed_data.value().control_index;
return true;
}
@@ -656,7 +682,7 @@
}
CJS_Result CJS_Field::get_alignment(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -682,7 +708,7 @@
CJS_Result CJS_Field::set_alignment(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
@@ -690,7 +716,7 @@
}
CJS_Result CJS_Field::get_border_style(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -702,15 +728,15 @@
return CJS_Result::Failure(JSMessage::kBadObjectError);
switch (pWidget->GetBorderStyle()) {
- case BorderStyle::SOLID:
+ case BorderStyle::kSolid:
return CJS_Result::Success(pRuntime->NewString("solid"));
- case BorderStyle::DASH:
+ case BorderStyle::kDash:
return CJS_Result::Success(pRuntime->NewString("dashed"));
- case BorderStyle::BEVELED:
+ case BorderStyle::kBeveled:
return CJS_Result::Success(pRuntime->NewString("beveled"));
- case BorderStyle::INSET:
+ case BorderStyle::kInset:
return CJS_Result::Success(pRuntime->NewString("inset"));
- case BorderStyle::UNDERLINE:
+ case BorderStyle::kUnderline:
return CJS_Result::Success(pRuntime->NewString("underline"));
}
return CJS_Result::Success(pRuntime->NewString(""));
@@ -718,11 +744,11 @@
CJS_Result CJS_Field::set_border_style(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
- ByteString byte_str = pRuntime->ToWideString(vp).ToDefANSI();
+ ByteString byte_str = pRuntime->ToByteString(vp);
if (m_bDelay) {
AddDelay_String(FP_BORDERSTYLE, byte_str);
} else {
@@ -733,7 +759,7 @@
}
CJS_Result CJS_Field::get_button_align_x(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -753,14 +779,14 @@
CJS_Result CJS_Field::set_button_align_x(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_button_align_y(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -780,14 +806,14 @@
CJS_Result CJS_Field::set_button_align_y(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_button_fit_bounds(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -806,14 +832,14 @@
CJS_Result CJS_Field::set_button_fit_bounds(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_button_position(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -832,14 +858,14 @@
CJS_Result CJS_Field::set_button_position(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kBadObjectError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_button_scale_how(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -852,20 +878,20 @@
if (!pFormControl)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- return CJS_Result::Success(pRuntime->NewBoolean(
- pFormControl->GetIconFit().IsProportionalScale() ? 0 : 1));
+ return CJS_Result::Success(
+ pRuntime->NewBoolean(!pFormControl->GetIconFit().IsProportionalScale()));
}
CJS_Result CJS_Field::set_button_scale_how(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_button_scale_when(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -879,34 +905,27 @@
return CJS_Result::Failure(JSMessage::kBadObjectError);
CPDF_IconFit IconFit = pFormControl->GetIconFit();
- int ScaleM = IconFit.GetScaleMethod();
- switch (ScaleM) {
- case CPDF_IconFit::Always:
+ CPDF_IconFit::ScaleMethod scale_method = IconFit.GetScaleMethod();
+ switch (scale_method) {
+ case CPDF_IconFit::ScaleMethod::kAlways:
+ case CPDF_IconFit::ScaleMethod::kBigger:
+ case CPDF_IconFit::ScaleMethod::kNever:
+ case CPDF_IconFit::ScaleMethod::kSmaller:
return CJS_Result::Success(
- pRuntime->NewNumber(static_cast<int32_t>(CPDF_IconFit::Always)));
- case CPDF_IconFit::Bigger:
- return CJS_Result::Success(
- pRuntime->NewNumber(static_cast<int32_t>(CPDF_IconFit::Bigger)));
- case CPDF_IconFit::Never:
- return CJS_Result::Success(
- pRuntime->NewNumber(static_cast<int32_t>(CPDF_IconFit::Never)));
- case CPDF_IconFit::Smaller:
- return CJS_Result::Success(
- pRuntime->NewNumber(static_cast<int32_t>(CPDF_IconFit::Smaller)));
+ pRuntime->NewNumber(static_cast<int>(scale_method)));
}
- return CJS_Result::Success();
}
CJS_Result CJS_Field::set_button_scale_when(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_calc_order_index(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -917,20 +936,20 @@
CPDFSDK_InteractiveForm* pRDForm = m_pFormFillEnv->GetInteractiveForm();
CPDF_InteractiveForm* pForm = pRDForm->GetInteractiveForm();
- return CJS_Result::Success(pRuntime->NewNumber(
- static_cast<int32_t>(pForm->FindFieldInCalculationOrder(pFormField))));
+ return CJS_Result::Success(
+ pRuntime->NewNumber(pForm->FindFieldInCalculationOrder(pFormField)));
}
CJS_Result CJS_Field::set_calc_order_index(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_char_limit(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -944,14 +963,14 @@
CJS_Result CJS_Field::set_char_limit(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_comb(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -965,14 +984,14 @@
}
CJS_Result CJS_Field::set_comb(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_commit_on_sel_change(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -988,7 +1007,7 @@
CJS_Result CJS_Field::set_commit_on_sel_change(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
@@ -1027,7 +1046,7 @@
std::vector<uint32_t> array;
if (vp->IsNumber()) {
array.push_back(pRuntime->ToInt32(vp));
- } else if (!vp.IsEmpty() && vp->IsArray()) {
+ } else if (fxv8::IsArray(vp)) {
v8::Local<v8::Array> SelArray = pRuntime->ToArray(vp);
for (size_t i = 0; i < pRuntime->GetArrayLength(SelArray); i++) {
array.push_back(
@@ -1054,7 +1073,7 @@
}
CJS_Result CJS_Field::get_default_value(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -1071,14 +1090,14 @@
CJS_Result CJS_Field::set_default_value(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_do_not_scroll(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -1093,14 +1112,14 @@
CJS_Result CJS_Field::set_do_not_scroll(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_do_not_spell_check(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -1116,21 +1135,12 @@
CJS_Result CJS_Field::set_do_not_spell_check(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
-void CJS_Field::SetDelay(bool bDelay) {
- m_bDelay = bDelay;
-
- if (m_bDelay)
- return;
- if (m_pJSDoc)
- m_pJSDoc->DoFieldDelay(m_FieldName, m_nFormControlIndex);
-}
-
CJS_Result CJS_Field::get_delay(CJS_Runtime* pRuntime) {
return CJS_Result::Success(pRuntime->NewBoolean(m_bDelay));
}
@@ -1253,7 +1263,7 @@
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
- if (vp.IsEmpty() || !vp->IsArray())
+ if (!fxv8::IsArray(vp))
return CJS_Result::Failure(JSMessage::kBadObjectError);
return CJS_Result::Success();
@@ -1295,30 +1305,7 @@
if (!pFormControl)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- int iColorType;
- pFormControl->GetBackgroundColor(iColorType);
-
- CFX_Color color;
- if (iColorType == CFX_Color::kTransparent) {
- color = CFX_Color(CFX_Color::kTransparent);
- } else if (iColorType == CFX_Color::kGray) {
- color = CFX_Color(CFX_Color::kGray,
- pFormControl->GetOriginalBackgroundColor(0));
- } else if (iColorType == CFX_Color::kRGB) {
- color =
- CFX_Color(CFX_Color::kRGB, pFormControl->GetOriginalBackgroundColor(0),
- pFormControl->GetOriginalBackgroundColor(1),
- pFormControl->GetOriginalBackgroundColor(2));
- } else if (iColorType == CFX_Color::kCMYK) {
- color =
- CFX_Color(CFX_Color::kCMYK, pFormControl->GetOriginalBackgroundColor(0),
- pFormControl->GetOriginalBackgroundColor(1),
- pFormControl->GetOriginalBackgroundColor(2),
- pFormControl->GetOriginalBackgroundColor(3));
- } else {
- return CJS_Result::Failure(JSMessage::kValueError);
- }
-
+ CFX_Color color = GetFormControlColor(pFormControl, pdfium::appearance::kBG);
v8::Local<v8::Value> array =
CJS_Color::ConvertPWLColorToArray(pRuntime, color);
if (array.IsEmpty())
@@ -1333,7 +1320,7 @@
return CJS_Result::Failure(JSMessage::kBadObjectError);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
- if (vp.IsEmpty() || !vp->IsArray())
+ if (!fxv8::IsArray(vp))
return CJS_Result::Failure(JSMessage::kBadObjectError);
return CJS_Result::Success();
}
@@ -1369,7 +1356,7 @@
}
CJS_Result CJS_Field::get_highlight(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -1384,15 +1371,15 @@
int eHM = pFormControl->GetHighlightingMode();
switch (eHM) {
- case CPDF_FormControl::None:
+ case CPDF_FormControl::kNone:
return CJS_Result::Success(pRuntime->NewString("none"));
- case CPDF_FormControl::Push:
+ case CPDF_FormControl::kPush:
return CJS_Result::Success(pRuntime->NewString("push"));
- case CPDF_FormControl::Invert:
+ case CPDF_FormControl::kInvert:
return CJS_Result::Success(pRuntime->NewString("invert"));
- case CPDF_FormControl::Outline:
+ case CPDF_FormControl::kOutline:
return CJS_Result::Success(pRuntime->NewString("outline"));
- case CPDF_FormControl::Toggle:
+ case CPDF_FormControl::kToggle:
return CJS_Result::Success(pRuntime->NewString("toggle"));
}
return CJS_Result::Success();
@@ -1400,7 +1387,7 @@
CJS_Result CJS_Field::set_highlight(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
@@ -1441,7 +1428,7 @@
}
CJS_Result CJS_Field::get_multiline(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -1456,14 +1443,14 @@
CJS_Result CJS_Field::set_multiline(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_multiple_selection(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -1478,7 +1465,7 @@
CJS_Result CJS_Field::set_multiple_selection(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
@@ -1517,25 +1504,20 @@
if (!pFormField)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- std::vector<ObservedPtr<CPDFSDK_Annot>> widgets;
+ std::vector<ObservedPtr<CPDFSDK_Widget>> widgets;
m_pFormFillEnv->GetInteractiveForm()->GetWidgets(pFormField, &widgets);
if (widgets.empty())
return CJS_Result::Success(pRuntime->NewNumber(-1));
v8::Local<v8::Array> PageArray = pRuntime->NewArray();
int i = 0;
- for (const auto& pObserved : widgets) {
- if (!pObserved)
- return CJS_Result::Failure(JSMessage::kBadObjectError);
-
- auto* pWidget = ToCPDFSDKWidget(pObserved.Get());
- CPDFSDK_PageView* pPageView = pWidget->GetPageView();
- if (!pPageView)
+ for (const auto& pWidget : widgets) {
+ if (!pWidget)
return CJS_Result::Failure(JSMessage::kBadObjectError);
pRuntime->PutArrayElement(
PageArray, i,
- pRuntime->NewNumber(static_cast<int32_t>(pPageView->GetPageIndex())));
+ pRuntime->NewNumber(pWidget->GetPageView()->GetPageIndex()));
++i;
}
return CJS_Result::Success(PageArray);
@@ -1546,7 +1528,7 @@
}
CJS_Result CJS_Field::get_password(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -1561,7 +1543,7 @@
CJS_Result CJS_Field::set_password(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
@@ -1611,7 +1593,7 @@
}
if (bSet)
- UpdateFormField(m_pFormFillEnv.Get(), pFormField, true, false, true);
+ UpdateFormField(m_pFormFillEnv.Get(), pFormField, false);
continue;
}
@@ -1631,8 +1613,7 @@
if (dwFlags != pWidget->GetFlags()) {
pWidget->SetFlags(dwFlags);
UpdateFormControl(m_pFormFillEnv.Get(),
- pFormField->GetControl(m_nFormControlIndex), true,
- false, true);
+ pFormField->GetControl(m_nFormControlIndex), false);
}
}
}
@@ -1674,11 +1655,21 @@
CJS_Result CJS_Field::set_readonly(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- std::vector<CPDF_FormField*> FieldArray = GetFormFields();
- if (FieldArray.empty())
+ CPDF_FormField* pFormField = GetFirstFormField();
+ if (!pFormField)
return CJS_Result::Failure(JSMessage::kBadObjectError);
+
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
+
+ const bool bReadOnly = pRuntime->ToBoolean(vp);
+ const uint32_t dwFlags = pFormField->GetFieldFlags();
+ const uint32_t dwNewFlags = bReadOnly
+ ? (dwFlags | pdfium::form_flags::kReadOnly)
+ : (dwFlags & ~pdfium::form_flags::kReadOnly);
+ if (dwNewFlags != dwFlags)
+ pFormField->SetFieldFlags(dwNewFlags);
+
return CJS_Result::Success();
}
@@ -1709,24 +1700,23 @@
CJS_Result CJS_Field::set_rect(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
- if (vp.IsEmpty() || !vp->IsArray())
+ if (!fxv8::IsArray(vp))
return CJS_Result::Failure(JSMessage::kValueError);
v8::Local<v8::Array> rcArray = pRuntime->ToArray(vp);
if (pRuntime->GetArrayLength(rcArray) < 4)
return CJS_Result::Failure(JSMessage::kValueError);
- float pArray[4];
- pArray[0] = static_cast<float>(
+ float f0 = static_cast<float>(
pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 0)));
- pArray[1] = static_cast<float>(
+ float f1 = static_cast<float>(
pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 1)));
- pArray[2] = static_cast<float>(
+ float f2 = static_cast<float>(
pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 2)));
- pArray[3] = static_cast<float>(
+ float f3 = static_cast<float>(
pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 3)));
- CFX_FloatRect crRect(pArray);
+ CFX_FloatRect crRect(f0, f1, f2, f3);
if (m_bDelay) {
AddDelay_Rect(FP_RECT, crRect);
} else {
@@ -1758,7 +1748,7 @@
}
CJS_Result CJS_Field::get_rich_text(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -1773,7 +1763,7 @@
CJS_Result CJS_Field::set_rich_text(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
@@ -1789,7 +1779,7 @@
}
CJS_Result CJS_Field::get_rotation(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -1804,7 +1794,7 @@
CJS_Result CJS_Field::set_rotation(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
@@ -1828,28 +1818,7 @@
if (!pFormControl)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- int iColorType;
- pFormControl->GetBorderColor(iColorType);
-
- CFX_Color color;
- if (iColorType == CFX_Color::kTransparent) {
- color = CFX_Color(CFX_Color::kTransparent);
- } else if (iColorType == CFX_Color::kGray) {
- color =
- CFX_Color(CFX_Color::kGray, pFormControl->GetOriginalBorderColor(0));
- } else if (iColorType == CFX_Color::kRGB) {
- color = CFX_Color(CFX_Color::kRGB, pFormControl->GetOriginalBorderColor(0),
- pFormControl->GetOriginalBorderColor(1),
- pFormControl->GetOriginalBorderColor(2));
- } else if (iColorType == CFX_Color::kCMYK) {
- color = CFX_Color(CFX_Color::kCMYK, pFormControl->GetOriginalBorderColor(0),
- pFormControl->GetOriginalBorderColor(1),
- pFormControl->GetOriginalBorderColor(2),
- pFormControl->GetOriginalBorderColor(3));
- } else {
- return CJS_Result::Failure(JSMessage::kObjectTypeError);
- }
-
+ CFX_Color color = GetFormControlColor(pFormControl, pdfium::appearance::kBC);
v8::Local<v8::Value> array =
CJS_Color::ConvertPWLColorToArray(pRuntime, color);
if (array.IsEmpty())
@@ -1861,13 +1830,13 @@
v8::Local<v8::Value> vp) {
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
- if (vp.IsEmpty() || !vp->IsArray())
+ if (!fxv8::IsArray(vp))
return CJS_Result::Failure(JSMessage::kBadObjectError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_style(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -1880,37 +1849,37 @@
if (!pFormControl)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- WideString csWCaption = pFormControl->GetNormalCaption();
- wchar_t selector = !csWCaption.IsEmpty() ? csWCaption[0] : L'4';
+ wchar_t selector = GetSelectorFromCaptionForFieldType(
+ pFormControl->GetNormalCaption(), pFormControl->GetType());
ByteString csBCaption;
switch (selector) {
- case L'l':
+ case kCircleSelector:
csBCaption = "circle";
break;
- case L'8':
+ case kCrossSelector:
csBCaption = "cross";
break;
- case L'u':
+ case kDiamondSelector:
csBCaption = "diamond";
break;
- case L'n':
+ case kSquareSelector:
csBCaption = "square";
break;
- case L'H':
+ case kStarSelector:
csBCaption = "star";
break;
- default: // L'4'
+ case kCheckSelector:
+ default:
csBCaption = "check";
break;
}
- return CJS_Result::Success(pRuntime->NewString(
- WideString::FromDefANSI(csBCaption.AsStringView()).AsStringView()));
+ return CJS_Result::Success(pRuntime->NewString(csBCaption.AsStringView()));
}
CJS_Result CJS_Field::set_style(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
@@ -1934,21 +1903,21 @@
if (!pFormControl)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- Optional<CFX_Color::Type> iColorType;
- FX_ARGB color;
CPDF_DefaultAppearance FieldAppearance = pFormControl->GetDefaultAppearance();
- std::tie(iColorType, color) = FieldAppearance.GetColor();
+ absl::optional<CFX_Color::TypeAndARGB> maybe_type_argb_pair =
+ FieldAppearance.GetColorARGB();
CFX_Color crRet;
- if (!iColorType || *iColorType == CFX_Color::kTransparent) {
- crRet = CFX_Color(CFX_Color::kTransparent);
- } else {
+ if (maybe_type_argb_pair.has_value() &&
+ maybe_type_argb_pair.value().color_type !=
+ CFX_Color::Type::kTransparent) {
int32_t a;
int32_t r;
int32_t g;
int32_t b;
- std::tie(a, r, g, b) = ArgbDecode(color);
- crRet = CFX_Color(CFX_Color::kRGB, r / 255.0f, g / 255.0f, b / 255.0f);
+ std::tie(a, r, g, b) = ArgbDecode(maybe_type_argb_pair.value().argb);
+ crRet =
+ CFX_Color(CFX_Color::Type::kRGB, r / 255.0f, g / 255.0f, b / 255.0f);
}
v8::Local<v8::Value> array =
@@ -1962,13 +1931,13 @@
v8::Local<v8::Value> vp) {
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
- if (vp.IsEmpty() || !vp->IsArray())
+ if (!fxv8::IsArray(vp))
return CJS_Result::Failure(JSMessage::kBadObjectError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_text_font(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -1986,7 +1955,8 @@
return CJS_Result::Failure(JSMessage::kObjectTypeError);
}
- Optional<WideString> wsFontName = pFormControl->GetDefaultControlFontName();
+ absl::optional<WideString> wsFontName =
+ pFormControl->GetDefaultControlFontName();
if (!wsFontName.has_value())
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -1996,17 +1966,17 @@
CJS_Result CJS_Field::set_text_font(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
- if (pRuntime->ToWideString(vp).ToDefANSI().IsEmpty())
+ if (pRuntime->ToByteString(vp).IsEmpty())
return CJS_Result::Failure(JSMessage::kValueError);
return CJS_Result::Success();
}
CJS_Result CJS_Field::get_text_size(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -2024,7 +1994,7 @@
CJS_Result CJS_Field::set_text_size(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
@@ -2062,7 +2032,7 @@
}
CJS_Result CJS_Field::get_user_name(CJS_Runtime* pRuntime) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
CPDF_FormField* pFormField = GetFirstFormField();
if (!pFormField)
@@ -2074,7 +2044,7 @@
CJS_Result CJS_Field::set_user_name(CJS_Runtime* pRuntime,
v8::Local<v8::Value> vp) {
- ASSERT(m_pFormFillEnv);
+ DCHECK(m_pFormFillEnv);
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
return CJS_Result::Success();
@@ -2102,7 +2072,7 @@
iIndex = pFormField->GetSelectedIndex(i);
ElementValue = pRuntime->NewString(
pFormField->GetOptionValue(iIndex).AsStringView());
- if (wcslen(pRuntime->ToWideString(ElementValue).c_str()) == 0) {
+ if (pRuntime->ToWideString(ElementValue).IsEmpty()) {
ElementValue = pRuntime->NewString(
pFormField->GetOptionLabel(iIndex).AsStringView());
}
@@ -2143,7 +2113,7 @@
return CJS_Result::Failure(JSMessage::kReadOnlyError);
std::vector<WideString> strArray;
- if (!vp.IsEmpty() && vp->IsArray()) {
+ if (fxv8::IsArray(vp)) {
v8::Local<v8::Array> ValueArray = pRuntime->ToArray(vp);
for (size_t i = 0; i < pRuntime->GetArrayLength(ValueArray); i++) {
strArray.push_back(
@@ -2214,7 +2184,7 @@
WideString wsFileName = m_pFormFillEnv->JS_fieldBrowse();
if (!wsFileName.IsEmpty()) {
pFormField->SetValue(wsFileName, NotificationOption::kDoNotNotify);
- UpdateFormField(m_pFormFillEnv.Get(), pFormField, true, true, true);
+ UpdateFormField(m_pFormFillEnv.Get(), pFormField, true);
}
return CJS_Result::Success();
}
@@ -2225,8 +2195,7 @@
CJS_Runtime* pRuntime,
const std::vector<v8::Local<v8::Value>>& params) {
int nface = 0;
- int iSize = params.size();
- if (iSize >= 1)
+ if (params.size() >= 1)
nface = pRuntime->ToInt32(params[0]);
CPDF_FormField* pFormField = GetFirstFormField();
@@ -2280,7 +2249,8 @@
if (pObj.IsEmpty())
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto* pJS_Icon = static_cast<CJS_Icon*>(CFXJS_Engine::GetObjectPrivate(pObj));
+ auto* pJS_Icon = static_cast<CJS_Icon*>(
+ CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pObj));
return pJS_Icon ? CJS_Result::Success(pJS_Icon->ToV8Object())
: CJS_Result::Failure(JSMessage::kBadObjectError);
}
@@ -2306,8 +2276,8 @@
CJS_Result CJS_Field::checkThisBox(
CJS_Runtime* pRuntime,
const std::vector<v8::Local<v8::Value>>& params) {
- int iSize = params.size();
- if (iSize < 1)
+ const size_t nSize = params.size();
+ if (nSize == 0)
return CJS_Result::Failure(JSMessage::kParamError);
if (!m_bCanSet)
@@ -2315,7 +2285,7 @@
int nWidget = pRuntime->ToInt32(params[0]);
bool bCheckit = true;
- if (iSize >= 2)
+ if (nSize >= 2)
bCheckit = pRuntime->ToBoolean(params[1]);
CPDF_FormField* pFormField = GetFirstFormField();
@@ -2331,7 +2301,7 @@
// TODO(weili): Check whether anything special needed for radio button.
// (When pFormField->GetFieldType() == FormFieldType::kRadioButton.)
pFormField->CheckControl(nWidget, bCheckit, NotificationOption::kNotify);
- UpdateFormField(m_pFormFillEnv.Get(), pFormField, true, true, true);
+ UpdateFormField(m_pFormFillEnv.Get(), pFormField, true);
return CJS_Result::Success();
}
@@ -2347,8 +2317,7 @@
if (!m_bCanSet)
return CJS_Result::Failure(JSMessage::kReadOnlyError);
- int iSize = params.size();
- if (iSize < 1)
+ if (params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
CPDF_FormField* pFormField = GetFirstFormField();
@@ -2378,7 +2347,7 @@
std::vector<std::unique_ptr<WideString>> swSort;
for (CPDF_FormField* pFormField : FieldArray) {
- swSort.push_back(pdfium::MakeUnique<WideString>(pFormField->GetFullName()));
+ swSort.push_back(std::make_unique<WideString>(pFormField->GetFullName()));
}
std::sort(swSort.begin(), swSort.end(),
@@ -2393,8 +2362,8 @@
if (pObj.IsEmpty())
return CJS_Result::Failure(JSMessage::kBadObjectError);
- auto* pJSField =
- static_cast<CJS_Field*>(CFXJS_Engine::GetObjectPrivate(pObj));
+ auto* pJSField = static_cast<CJS_Field*>(
+ CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pObj));
pJSField->AttachField(m_pJSDoc.Get(), *pStr);
pRuntime->PutArrayElement(FormFieldArray, j++,
pJSField
@@ -2407,13 +2376,13 @@
CJS_Result CJS_Field::getItemAt(
CJS_Runtime* pRuntime,
const std::vector<v8::Local<v8::Value>>& params) {
- int iSize = params.size();
+ const size_t nSize = params.size();
int nIdx = -1;
- if (iSize >= 1)
+ if (nSize >= 1)
nIdx = pRuntime->ToInt32(params[0]);
bool bExport = true;
- if (iSize >= 2)
+ if (nSize >= 2)
bExport = pRuntime->ToBoolean(params[1]);
CPDF_FormField* pFormField = GetFirstFormField();
@@ -2509,18 +2478,16 @@
if (nCount == 1) {
pWidget = pForm->GetWidget(pFormField->GetControl(0));
} else {
- IPDF_Page* pPage = IPDFPageFromFPDFPage(m_pFormFillEnv->GetCurrentPage());
+ IPDF_Page* pPage = m_pFormFillEnv->GetCurrentPage();
if (!pPage)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- if (CPDFSDK_PageView* pCurPageView =
- m_pFormFillEnv->GetPageView(pPage, true)) {
- for (int32_t i = 0; i < nCount; i++) {
- if (CPDFSDK_Widget* pTempWidget =
- pForm->GetWidget(pFormField->GetControl(i))) {
- if (pTempWidget->GetPDFPage() == pCurPageView->GetPDFPage()) {
- pWidget = pTempWidget;
- break;
- }
+ CPDFSDK_PageView* pCurPageView = m_pFormFillEnv->GetOrCreatePageView(pPage);
+ for (int32_t i = 0; i < nCount; i++) {
+ if (CPDFSDK_Widget* pTempWidget =
+ pForm->GetWidget(pFormField->GetControl(i))) {
+ if (pTempWidget->GetPDFPage() == pCurPageView->GetPDFPage()) {
+ pWidget = pTempWidget;
+ break;
}
}
}
@@ -2528,7 +2495,7 @@
if (pWidget) {
ObservedPtr<CPDFSDK_Annot> pObserved(pWidget);
- m_pFormFillEnv->SetFocusAnnot(&pObserved);
+ m_pFormFillEnv->SetFocusAnnot(pObserved);
}
return CJS_Result::Success();
@@ -2581,30 +2548,39 @@
return CJS_Result::Failure(JSMessage::kNotSupportedError);
}
+void CJS_Field::SetDelay(bool bDelay) {
+ m_bDelay = bDelay;
+ if (m_bDelay)
+ return;
+
+ if (m_pJSDoc)
+ m_pJSDoc->DoFieldDelay(m_FieldName, m_nFormControlIndex);
+}
+
void CJS_Field::AddDelay_Int(FIELD_PROP prop, int32_t n) {
auto pNewData =
- pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
+ std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
pNewData->num = n;
m_pJSDoc->AddDelayData(std::move(pNewData));
}
void CJS_Field::AddDelay_Bool(FIELD_PROP prop, bool b) {
auto pNewData =
- pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
+ std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
pNewData->b = b;
m_pJSDoc->AddDelayData(std::move(pNewData));
}
void CJS_Field::AddDelay_String(FIELD_PROP prop, const ByteString& str) {
auto pNewData =
- pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
+ std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
pNewData->bytestring = str;
m_pJSDoc->AddDelayData(std::move(pNewData));
}
void CJS_Field::AddDelay_Rect(FIELD_PROP prop, const CFX_FloatRect& rect) {
auto pNewData =
- pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
+ std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
pNewData->rect = rect;
m_pJSDoc->AddDelayData(std::move(pNewData));
}
@@ -2612,7 +2588,7 @@
void CJS_Field::AddDelay_WordArray(FIELD_PROP prop,
const std::vector<uint32_t>& array) {
auto pNewData =
- pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
+ std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
pNewData->wordarray = array;
m_pJSDoc->AddDelayData(std::move(pNewData));
}
@@ -2620,14 +2596,14 @@
void CJS_Field::AddDelay_WideStringArray(FIELD_PROP prop,
const std::vector<WideString>& array) {
auto pNewData =
- pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
+ std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
pNewData->widestringarray = array;
m_pJSDoc->AddDelayData(std::move(pNewData));
}
void CJS_Field::DoDelay(CPDFSDK_FormFillEnvironment* pFormFillEnv,
CJS_DelayData* pData) {
- ASSERT(pFormFillEnv);
+ DCHECK(pFormFillEnv);
switch (pData->eProp) {
case FP_BORDERSTYLE:
SetBorderStyle(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
diff --git a/fxjs/cjs_field.h b/fxjs/cjs_field.h
index d772e66..7a66277 100644
--- a/fxjs/cjs_field.h
+++ b/fxjs/cjs_field.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -13,8 +13,8 @@
#include "fxjs/cjs_object.h"
#include "fxjs/js_define.h"
+class CFX_FloatRect;
class CPDF_FormControl;
-class CPDFSDK_Widget;
struct CJS_DelayData;
enum FIELD_PROP {
@@ -29,7 +29,7 @@
class CJS_Field final : public CJS_Object {
public:
- static int GetObjDefnID();
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
static void DoDelay(CPDFSDK_FormFillEnvironment* pFormFillEnv,
CJS_DelayData* pData);
@@ -123,7 +123,7 @@
CJS_Result set_text_color(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp);
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const char kName[];
static const JSPropertySpec PropertySpecs[];
static const JSMethodSpec MethodSpecs[];
@@ -349,11 +349,11 @@
CJS_Result signatureValidate(CJS_Runtime* pRuntime,
const std::vector<v8::Local<v8::Value>>& params);
- void SetDelay(bool bDelay);
std::vector<CPDF_FormField*> GetFormFields() const;
CPDF_FormField* GetFirstFormField() const;
CPDF_FormControl* GetSmartFieldControl(CPDF_FormField* pFormField);
+ void SetDelay(bool bDelay);
void AddDelay_Int(FIELD_PROP prop, int32_t n);
void AddDelay_Bool(FIELD_PROP prop, bool b);
void AddDelay_String(FIELD_PROP prop, const ByteString& str);
@@ -361,7 +361,6 @@
void AddDelay_WordArray(FIELD_PROP prop, const std::vector<uint32_t>& array);
void AddDelay_WideStringArray(FIELD_PROP prop,
const std::vector<WideString>& array);
-
void DoDelay();
ObservedPtr<CJS_Document> m_pJSDoc;
diff --git a/fxjs/cjs_font.cpp b/fxjs/cjs_font.cpp
index 0e6e94b..fcf69ac 100644
--- a/fxjs/cjs_font.cpp
+++ b/fxjs/cjs_font.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -22,7 +22,7 @@
{"Symbol", JSConstSpec::String, 0, "Symbol"},
{"ZapfD", JSConstSpec::String, 0, "ZapfDingbats"}};
-int CJS_Font::ObjDefnID = -1;
+uint32_t CJS_Font::ObjDefnID = 0;
// static
void CJS_Font::DefineJSObjects(CFXJS_Engine* pEngine) {
diff --git a/fxjs/cjs_font.h b/fxjs/cjs_font.h
index d3cf159..a4ecca1 100644
--- a/fxjs/cjs_font.h
+++ b/fxjs/cjs_font.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
CJS_Font() = delete;
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const JSConstSpec ConstSpecs[];
};
diff --git a/fxjs/cjs_global.cpp b/fxjs/cjs_global.cpp
index 8ac3181..101dee2 100644
--- a/fxjs/cjs_global.cpp
+++ b/fxjs/cjs_global.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,7 +6,6 @@
#include "fxjs/cjs_global.h"
-#include <map>
#include <memory>
#include <utility>
#include <vector>
@@ -15,110 +14,20 @@
#include "fxjs/cfx_globaldata.h"
#include "fxjs/cfx_keyvalue.h"
#include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
#include "fxjs/cjs_object.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_define.h"
#include "fxjs/js_resources.h"
-#include "third_party/base/ptr_util.h"
+#include "third_party/base/check.h"
+#include "third_party/base/containers/contains.h"
+#include "v8/include/v8-isolate.h"
namespace {
-WideString PropFromV8Prop(v8::Isolate* pIsolate,
- v8::Local<v8::String> property) {
- v8::String::Utf8Value utf8_value(pIsolate, property);
- return WideString::FromUTF8(ByteStringView(*utf8_value, utf8_value.length()));
-}
-
-template <class Alt>
-void JSSpecialPropQuery(const char*,
- v8::Local<v8::String> property,
- const v8::PropertyCallbackInfo<v8::Integer>& info) {
- auto pObj = JSGetObject<Alt>(info.Holder());
- if (!pObj)
- return;
-
- CJS_Runtime* pRuntime = pObj->GetRuntime();
- if (!pRuntime)
- return;
-
- CJS_Result result =
- pObj->QueryProperty(PropFromV8Prop(info.GetIsolate(), property).c_str());
-
- info.GetReturnValue().Set(!result.HasError() ? 4 : 0);
-}
-
-template <class Alt>
-void JSSpecialPropGet(const char* class_name,
- v8::Local<v8::String> property,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- auto pObj = JSGetObject<Alt>(info.Holder());
- if (!pObj)
- return;
-
- CJS_Runtime* pRuntime = pObj->GetRuntime();
- if (!pRuntime)
- return;
-
- CJS_Result result = pObj->GetProperty(
- pRuntime, PropFromV8Prop(info.GetIsolate(), property).c_str());
-
- if (result.HasError()) {
- pRuntime->Error(
- JSFormatErrorString(class_name, "GetProperty", result.Error()));
- return;
- }
- if (result.HasReturn())
- info.GetReturnValue().Set(result.Return());
-}
-
-template <class Alt>
-void JSSpecialPropPut(const char* class_name,
- v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- auto pObj = JSGetObject<Alt>(info.Holder());
- if (!pObj)
- return;
-
- CJS_Runtime* pRuntime = pObj->GetRuntime();
- if (!pRuntime)
- return;
-
- CJS_Result result = pObj->SetProperty(
- pRuntime, PropFromV8Prop(info.GetIsolate(), property).c_str(), value);
-
- if (result.HasError()) {
- pRuntime->Error(
- JSFormatErrorString(class_name, "PutProperty", result.Error()));
- }
-}
-
-template <class Alt>
-void JSSpecialPropDel(const char* class_name,
- v8::Local<v8::String> property,
- const v8::PropertyCallbackInfo<v8::Boolean>& info) {
- auto pObj = JSGetObject<Alt>(info.Holder());
- if (!pObj)
- return;
-
- CJS_Runtime* pRuntime = pObj->GetRuntime();
- if (!pRuntime)
- return;
-
- CJS_Result result = pObj->DelProperty(
- pRuntime, PropFromV8Prop(info.GetIsolate(), property).c_str());
- if (result.HasError()) {
- // TODO(dsinclair): Should this set the pRuntime->Error result?
- // ByteString cbName =
- // ByteString::Format("%s.%s", class_name, "DelProperty");
- }
-}
-
-template <class T>
-v8::Local<v8::String> GetV8StringFromProperty(v8::Local<v8::Name> property,
- const T& info) {
- return property->ToString(info.GetIsolate()->GetCurrentContext())
- .ToLocalChecked();
+ByteString ByteStringFromV8Name(v8::Isolate* pIsolate,
+ v8::Local<v8::Name> name) {
+ CHECK(name->IsString());
+ return fxv8::ToByteString(pIsolate, name.As<v8::String>());
}
} // namespace
@@ -130,7 +39,7 @@
const JSMethodSpec CJS_Global::MethodSpecs[] = {
{"setPersistent", setPersistent_static}};
-int CJS_Global::ObjDefnID = -1;
+uint32_t CJS_Global::ObjDefnID = 0;
// static
void CJS_Global::setPersistent_static(
@@ -143,24 +52,36 @@
void CJS_Global::queryprop_static(
v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Integer>& info) {
- ASSERT(property->IsString());
- JSSpecialPropQuery<CJS_Global>(
- "global",
- v8::Local<v8::String>::New(info.GetIsolate(),
- GetV8StringFromProperty(property, info)),
- info);
+ auto pObj = JSGetObject<CJS_Global>(info.GetIsolate(), info.Holder());
+ if (!pObj)
+ return;
+
+ ByteString bsProp = ByteStringFromV8Name(info.GetIsolate(), property);
+ if (pObj->HasProperty(bsProp))
+ info.GetReturnValue().Set(static_cast<int>(v8::PropertyAttribute::None));
}
// static
void CJS_Global::getprop_static(
v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- ASSERT(property->IsString());
- JSSpecialPropGet<CJS_Global>(
- "global",
- v8::Local<v8::String>::New(info.GetIsolate(),
- GetV8StringFromProperty(property, info)),
- info);
+ auto pObj = JSGetObject<CJS_Global>(info.GetIsolate(), info.Holder());
+ if (!pObj)
+ return;
+
+ CJS_Runtime* pRuntime = pObj->GetRuntime();
+ if (!pRuntime)
+ return;
+
+ ByteString bsProp = ByteStringFromV8Name(info.GetIsolate(), property);
+ CJS_Result result = pObj->GetProperty(pRuntime, bsProp);
+ if (result.HasError()) {
+ pRuntime->Error(
+ JSFormatErrorString("global", "GetProperty", result.Error()));
+ return;
+ }
+ if (result.HasReturn())
+ info.GetReturnValue().Set(result.Return());
}
// static
@@ -168,35 +89,60 @@
v8::Local<v8::Name> property,
v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- ASSERT(property->IsString());
- JSSpecialPropPut<CJS_Global>(
- "global",
- v8::Local<v8::String>::New(info.GetIsolate(),
- GetV8StringFromProperty(property, info)),
- value, info);
+ auto pObj = JSGetObject<CJS_Global>(info.GetIsolate(), info.Holder());
+ if (!pObj)
+ return;
+
+ CJS_Runtime* pRuntime = pObj->GetRuntime();
+ if (!pRuntime)
+ return;
+
+ ByteString bsProp = ByteStringFromV8Name(info.GetIsolate(), property);
+ CJS_Result result = pObj->SetProperty(pRuntime, bsProp, value);
+ if (result.HasError()) {
+ pRuntime->Error(
+ JSFormatErrorString("global", "PutProperty", result.Error()));
+ return;
+ }
+ info.GetReturnValue().Set(value);
}
// static
void CJS_Global::delprop_static(
v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Boolean>& info) {
- ASSERT(property->IsString());
- JSSpecialPropDel<CJS_Global>(
- "global",
- v8::Local<v8::String>::New(info.GetIsolate(),
- GetV8StringFromProperty(property, info)),
- info);
+ auto pObj = JSGetObject<CJS_Global>(info.GetIsolate(), info.Holder());
+ if (!pObj)
+ return;
+
+ ByteString bsProp = ByteStringFromV8Name(info.GetIsolate(), property);
+ if (pObj->DelProperty(bsProp))
+ info.GetReturnValue().Set(true);
+}
+
+void CJS_Global::enumprop_static(
+ const v8::PropertyCallbackInfo<v8::Array>& info) {
+ auto pObj = JSGetObject<CJS_Global>(info.GetIsolate(), info.Holder());
+ if (!pObj)
+ return;
+
+ CJS_Runtime* pRuntime = pObj->GetRuntime();
+ if (!pRuntime)
+ return;
+
+ pObj->EnumProperties(pRuntime, info);
}
// static
void CJS_Global::DefineAllProperties(CFXJS_Engine* pEngine) {
pEngine->DefineObjAllProperties(
ObjDefnID, CJS_Global::queryprop_static, CJS_Global::getprop_static,
- CJS_Global::putprop_static, CJS_Global::delprop_static);
+ CJS_Global::putprop_static, CJS_Global::delprop_static,
+ CJS_Global::enumprop_static);
}
// static
-int CJS_Global::GetObjDefnID() {
+uint32_t CJS_Global::GetObjDefnID() {
return ObjDefnID;
}
@@ -209,38 +155,32 @@
}
CJS_Global::CJS_Global(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime)
- : CJS_Object(pObject, pRuntime) {
- CPDFSDK_FormFillEnvironment* pFormFillEnv = GetRuntime()->GetFormFillEnv();
- m_pFormFillEnv.Reset(pFormFillEnv);
- m_pGlobalData = CFX_GlobalData::GetRetainedInstance(nullptr);
+ : CJS_Object(pObject, pRuntime),
+ m_pGlobalData(CFX_GlobalData::GetRetainedInstance(nullptr)) {
UpdateGlobalPersistentVariables();
}
CJS_Global::~CJS_Global() {
DestroyGlobalPersisitentVariables();
- m_pGlobalData->Release();
+ m_pGlobalData.ExtractAsDangling()->Release();
}
-CJS_Result CJS_Global::QueryProperty(const wchar_t* propname) {
- if (WideString(propname).EqualsASCII("setPersistent"))
- return CJS_Result::Success();
-
- return CJS_Result::Failure(JSMessage::kUnknownProperty);
+bool CJS_Global::HasProperty(const ByteString& propname) {
+ return pdfium::Contains(m_MapGlobal, propname);
}
-CJS_Result CJS_Global::DelProperty(CJS_Runtime* pRuntime,
- const wchar_t* propname) {
- auto it = m_MapGlobal.find(WideString(propname).ToDefANSI());
+bool CJS_Global::DelProperty(const ByteString& propname) {
+ auto it = m_MapGlobal.find(propname);
if (it == m_MapGlobal.end())
- return CJS_Result::Failure(JSMessage::kUnknownProperty);
+ return false;
it->second->bDeleted = true;
- return CJS_Result::Success();
+ return true;
}
CJS_Result CJS_Global::GetProperty(CJS_Runtime* pRuntime,
- const wchar_t* propname) {
- auto it = m_MapGlobal.find(WideString(propname).ToDefANSI());
+ const ByteString& propname) {
+ auto it = m_MapGlobal.find(propname);
if (it == m_MapGlobal.end())
return CJS_Result::Success();
@@ -249,17 +189,17 @@
return CJS_Result::Success();
switch (pData->nType) {
- case CFX_Value::DataType::NUMBER:
+ case CFX_Value::DataType::kNumber:
return CJS_Result::Success(pRuntime->NewNumber(pData->dData));
- case CFX_Value::DataType::BOOLEAN:
+ case CFX_Value::DataType::kBoolean:
return CJS_Result::Success(pRuntime->NewBoolean(pData->bData));
- case CFX_Value::DataType::STRING:
- return CJS_Result::Success(pRuntime->NewString(
- WideString::FromDefANSI(pData->sData.AsStringView()).AsStringView()));
- case CFX_Value::DataType::OBJECT:
+ case CFX_Value::DataType::kString:
+ return CJS_Result::Success(
+ pRuntime->NewString(pData->sData.AsStringView()));
+ case CFX_Value::DataType::kObject:
return CJS_Result::Success(
v8::Local<v8::Object>::New(pRuntime->GetIsolate(), pData->pData));
- case CFX_Value::DataType::NULLOBJ:
+ case CFX_Value::DataType::kNull:
return CJS_Result::Success(pRuntime->NewNull());
default:
break;
@@ -268,46 +208,60 @@
}
CJS_Result CJS_Global::SetProperty(CJS_Runtime* pRuntime,
- const wchar_t* propname,
+ const ByteString& propname,
v8::Local<v8::Value> vp) {
- ByteString sPropName = WideString(propname).ToDefANSI();
if (vp->IsNumber()) {
- return SetGlobalVariables(sPropName, CFX_Value::DataType::NUMBER,
+ return SetGlobalVariables(propname, CFX_Value::DataType::kNumber,
pRuntime->ToDouble(vp), false, ByteString(),
v8::Local<v8::Object>(), false);
}
if (vp->IsBoolean()) {
- return SetGlobalVariables(sPropName, CFX_Value::DataType::BOOLEAN, 0,
+ return SetGlobalVariables(propname, CFX_Value::DataType::kBoolean, 0,
pRuntime->ToBoolean(vp), ByteString(),
v8::Local<v8::Object>(), false);
}
if (vp->IsString()) {
- return SetGlobalVariables(sPropName, CFX_Value::DataType::STRING, 0, false,
- pRuntime->ToWideString(vp).ToDefANSI(),
+ return SetGlobalVariables(propname, CFX_Value::DataType::kString, 0, false,
+ pRuntime->ToByteString(vp),
v8::Local<v8::Object>(), false);
}
if (vp->IsObject()) {
- return SetGlobalVariables(sPropName, CFX_Value::DataType::OBJECT, 0, false,
+ return SetGlobalVariables(propname, CFX_Value::DataType::kObject, 0, false,
ByteString(), pRuntime->ToObject(vp), false);
}
if (vp->IsNull()) {
- return SetGlobalVariables(sPropName, CFX_Value::DataType::NULLOBJ, 0, false,
+ return SetGlobalVariables(propname, CFX_Value::DataType::kNull, 0, false,
ByteString(), v8::Local<v8::Object>(), false);
}
if (vp->IsUndefined()) {
- DelProperty(pRuntime, propname);
+ DelProperty(propname);
return CJS_Result::Success();
}
return CJS_Result::Failure(JSMessage::kObjectTypeError);
}
+void CJS_Global::EnumProperties(
+ CJS_Runtime* pRuntime,
+ const v8::PropertyCallbackInfo<v8::Array>& info) {
+ v8::Local<v8::Array> result = pRuntime->NewArray();
+ int idx = 0;
+ for (const auto& it : m_MapGlobal) {
+ if (it.second->bDeleted)
+ continue;
+ v8::Local<v8::Name> name = pRuntime->NewString(it.first.AsStringView());
+ pRuntime->PutArrayElement(result, idx, name);
+ ++idx;
+ }
+ info.GetReturnValue().Set(result);
+}
+
CJS_Result CJS_Global::setPersistent(
CJS_Runtime* pRuntime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 2)
return CJS_Result::Failure(JSMessage::kParamError);
- auto it = m_MapGlobal.find(pRuntime->ToWideString(params[0]).ToDefANSI());
+ auto it = m_MapGlobal.find(pRuntime->ToByteString(params[0]));
if (it == m_MapGlobal.end() || it->second->bDeleted)
return CJS_Result::Failure(JSMessage::kGlobalNotFoundError);
@@ -323,47 +277,44 @@
for (int i = 0, sz = m_pGlobalData->GetSize(); i < sz; i++) {
CFX_GlobalData::Element* pData = m_pGlobalData->GetAt(i);
switch (pData->data.nType) {
- case CFX_Value::DataType::NUMBER:
- SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::NUMBER,
+ case CFX_Value::DataType::kNumber:
+ SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::kNumber,
pData->data.dData, false, ByteString(),
- v8::Local<v8::Object>(), pData->bPersistent == 1);
+ v8::Local<v8::Object>(), pData->bPersistent);
pRuntime->PutObjectProperty(ToV8Object(),
pData->data.sKey.AsStringView(),
pRuntime->NewNumber(pData->data.dData));
break;
- case CFX_Value::DataType::BOOLEAN:
- SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::BOOLEAN, 0,
+ case CFX_Value::DataType::kBoolean:
+ SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::kBoolean, 0,
pData->data.bData == 1, ByteString(),
- v8::Local<v8::Object>(), pData->bPersistent == 1);
+ v8::Local<v8::Object>(), pData->bPersistent);
pRuntime->PutObjectProperty(
ToV8Object(), pData->data.sKey.AsStringView(),
pRuntime->NewBoolean(pData->data.bData == 1));
break;
- case CFX_Value::DataType::STRING:
- SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::STRING, 0,
+ case CFX_Value::DataType::kString:
+ SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::kString, 0,
false, pData->data.sData, v8::Local<v8::Object>(),
- pData->bPersistent == 1);
+ pData->bPersistent);
pRuntime->PutObjectProperty(
ToV8Object(), pData->data.sKey.AsStringView(),
- pRuntime->NewString(
- WideString::FromUTF8(pData->data.sData.AsStringView())
- .AsStringView()));
+ pRuntime->NewString(pData->data.sData.AsStringView()));
break;
- case CFX_Value::DataType::OBJECT: {
+ case CFX_Value::DataType::kObject: {
v8::Local<v8::Object> pObj = pRuntime->NewObject();
if (!pObj.IsEmpty()) {
PutObjectProperty(pObj, &pData->data);
- SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::OBJECT, 0,
- false, ByteString(), pObj,
- pData->bPersistent == 1);
+ SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::kObject, 0,
+ false, ByteString(), pObj, pData->bPersistent);
pRuntime->PutObjectProperty(ToV8Object(),
pData->data.sKey.AsStringView(), pObj);
}
} break;
- case CFX_Value::DataType::NULLOBJ:
- SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::NULLOBJ, 0,
+ case CFX_Value::DataType::kNull:
+ SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::kNull, 0,
false, ByteString(), v8::Local<v8::Object>(),
- pData->bPersistent == 1);
+ pData->bPersistent);
pRuntime->PutObjectProperty(
ToV8Object(), pData->data.sKey.AsStringView(), pRuntime->NewNull());
break;
@@ -371,7 +322,11 @@
}
}
-void CJS_Global::CommitGlobalPersisitentVariables(CJS_Runtime* pRuntime) {
+void CJS_Global::CommitGlobalPersisitentVariables() {
+ CJS_Runtime* pRuntime = GetRuntime();
+ if (!pRuntime)
+ return;
+
for (const auto& iter : m_MapGlobal) {
ByteString name = iter.first;
JSGlobalData* pData = iter.second.get();
@@ -380,27 +335,26 @@
continue;
}
switch (pData->nType) {
- case CFX_Value::DataType::NUMBER:
+ case CFX_Value::DataType::kNumber:
m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
break;
- case CFX_Value::DataType::BOOLEAN:
+ case CFX_Value::DataType::kBoolean:
m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
break;
- case CFX_Value::DataType::STRING:
+ case CFX_Value::DataType::kString:
m_pGlobalData->SetGlobalVariableString(name, pData->sData);
m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
break;
- case CFX_Value::DataType::OBJECT: {
- std::vector<std::unique_ptr<CFX_KeyValue>> array;
+ case CFX_Value::DataType::kObject: {
v8::Local<v8::Object> obj =
- v8::Local<v8::Object>::New(GetIsolate(), pData->pData);
- ObjectToArray(pRuntime, obj, &array);
- m_pGlobalData->SetGlobalVariableObject(name, std::move(array));
+ v8::Local<v8::Object>::New(pRuntime->GetIsolate(), pData->pData);
+ m_pGlobalData->SetGlobalVariableObject(name,
+ ObjectToArray(pRuntime, obj));
m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
} break;
- case CFX_Value::DataType::NULLOBJ:
+ case CFX_Value::DataType::kNull:
m_pGlobalData->SetGlobalVariableNull(name);
m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
break;
@@ -408,55 +362,56 @@
}
}
-void CJS_Global::ObjectToArray(
+std::vector<std::unique_ptr<CFX_KeyValue>> CJS_Global::ObjectToArray(
CJS_Runtime* pRuntime,
- v8::Local<v8::Object> pObj,
- std::vector<std::unique_ptr<CFX_KeyValue>>* pArray) {
+ v8::Local<v8::Object> pObj) {
+ std::vector<std::unique_ptr<CFX_KeyValue>> array;
std::vector<WideString> pKeyList = pRuntime->GetObjectPropertyNames(pObj);
for (const auto& ws : pKeyList) {
ByteString sKey = ws.ToUTF8();
v8::Local<v8::Value> v =
pRuntime->GetObjectProperty(pObj, sKey.AsStringView());
if (v->IsNumber()) {
- auto pObjElement = pdfium::MakeUnique<CFX_KeyValue>();
- pObjElement->nType = CFX_Value::DataType::NUMBER;
+ auto pObjElement = std::make_unique<CFX_KeyValue>();
+ pObjElement->nType = CFX_Value::DataType::kNumber;
pObjElement->sKey = sKey;
pObjElement->dData = pRuntime->ToDouble(v);
- pArray->push_back(std::move(pObjElement));
+ array.push_back(std::move(pObjElement));
continue;
}
if (v->IsBoolean()) {
- auto pObjElement = pdfium::MakeUnique<CFX_KeyValue>();
- pObjElement->nType = CFX_Value::DataType::BOOLEAN;
+ auto pObjElement = std::make_unique<CFX_KeyValue>();
+ pObjElement->nType = CFX_Value::DataType::kBoolean;
pObjElement->sKey = sKey;
pObjElement->dData = pRuntime->ToBoolean(v);
- pArray->push_back(std::move(pObjElement));
+ array.push_back(std::move(pObjElement));
continue;
}
if (v->IsString()) {
- ByteString sValue = pRuntime->ToWideString(v).ToDefANSI();
- auto pObjElement = pdfium::MakeUnique<CFX_KeyValue>();
- pObjElement->nType = CFX_Value::DataType::STRING;
+ ByteString sValue = pRuntime->ToByteString(v);
+ auto pObjElement = std::make_unique<CFX_KeyValue>();
+ pObjElement->nType = CFX_Value::DataType::kString;
pObjElement->sKey = sKey;
pObjElement->sData = sValue;
- pArray->push_back(std::move(pObjElement));
+ array.push_back(std::move(pObjElement));
continue;
}
if (v->IsObject()) {
- auto pObjElement = pdfium::MakeUnique<CFX_KeyValue>();
- pObjElement->nType = CFX_Value::DataType::OBJECT;
+ auto pObjElement = std::make_unique<CFX_KeyValue>();
+ pObjElement->nType = CFX_Value::DataType::kObject;
pObjElement->sKey = sKey;
- ObjectToArray(pRuntime, pRuntime->ToObject(v), &pObjElement->objData);
- pArray->push_back(std::move(pObjElement));
+ pObjElement->objData = ObjectToArray(pRuntime, pRuntime->ToObject(v));
+ array.push_back(std::move(pObjElement));
continue;
}
if (v->IsNull()) {
- auto pObjElement = pdfium::MakeUnique<CFX_KeyValue>();
- pObjElement->nType = CFX_Value::DataType::NULLOBJ;
+ auto pObjElement = std::make_unique<CFX_KeyValue>();
+ pObjElement->nType = CFX_Value::DataType::kNull;
pObjElement->sKey = sKey;
- pArray->push_back(std::move(pObjElement));
+ array.push_back(std::move(pObjElement));
}
}
+ return array;
}
void CJS_Global::PutObjectProperty(v8::Local<v8::Object> pObj,
@@ -468,22 +423,20 @@
for (size_t i = 0; i < pData->objData.size(); ++i) {
CFX_KeyValue* pObjData = pData->objData.at(i).get();
switch (pObjData->nType) {
- case CFX_Value::DataType::NUMBER:
+ case CFX_Value::DataType::kNumber:
pRuntime->PutObjectProperty(pObj, pObjData->sKey.AsStringView(),
pRuntime->NewNumber(pObjData->dData));
break;
- case CFX_Value::DataType::BOOLEAN:
+ case CFX_Value::DataType::kBoolean:
pRuntime->PutObjectProperty(pObj, pObjData->sKey.AsStringView(),
pRuntime->NewBoolean(pObjData->bData == 1));
break;
- case CFX_Value::DataType::STRING:
+ case CFX_Value::DataType::kString:
pRuntime->PutObjectProperty(
pObj, pObjData->sKey.AsStringView(),
- pRuntime->NewString(
- WideString::FromUTF8(pObjData->sData.AsStringView())
- .AsStringView()));
+ pRuntime->NewString(pObjData->sData.AsStringView()));
break;
- case CFX_Value::DataType::OBJECT: {
+ case CFX_Value::DataType::kObject: {
v8::Local<v8::Object> pNewObj = pRuntime->NewObject();
if (!pNewObj.IsEmpty()) {
PutObjectProperty(pNewObj, pObjData);
@@ -491,7 +444,7 @@
pNewObj);
}
} break;
- case CFX_Value::DataType::NULLOBJ:
+ case CFX_Value::DataType::kNull:
pRuntime->PutObjectProperty(pObj, pObjData->sKey.AsStringView(),
pRuntime->NewNull());
break;
@@ -518,25 +471,25 @@
JSGlobalData* pTemp = it->second.get();
if (pTemp->bDeleted || pTemp->nType != nType) {
pTemp->dData = 0;
- pTemp->bData = 0;
+ pTemp->bData = false;
pTemp->sData.clear();
pTemp->nType = nType;
}
pTemp->bDeleted = false;
switch (nType) {
- case CFX_Value::DataType::NUMBER:
+ case CFX_Value::DataType::kNumber:
pTemp->dData = dData;
break;
- case CFX_Value::DataType::BOOLEAN:
+ case CFX_Value::DataType::kBoolean:
pTemp->bData = bData;
break;
- case CFX_Value::DataType::STRING:
+ case CFX_Value::DataType::kString:
pTemp->sData = sData;
break;
- case CFX_Value::DataType::OBJECT:
+ case CFX_Value::DataType::kObject:
pTemp->pData.Reset(pData->GetIsolate(), pData);
break;
- case CFX_Value::DataType::NULLOBJ:
+ case CFX_Value::DataType::kNull:
break;
default:
return CJS_Result::Failure(JSMessage::kObjectTypeError);
@@ -544,30 +497,30 @@
return CJS_Result::Success();
}
- auto pNewData = pdfium::MakeUnique<JSGlobalData>();
+ auto pNewData = std::make_unique<JSGlobalData>();
switch (nType) {
- case CFX_Value::DataType::NUMBER:
- pNewData->nType = CFX_Value::DataType::NUMBER;
+ case CFX_Value::DataType::kNumber:
+ pNewData->nType = CFX_Value::DataType::kNumber;
pNewData->dData = dData;
pNewData->bPersistent = bDefaultPersistent;
break;
- case CFX_Value::DataType::BOOLEAN:
- pNewData->nType = CFX_Value::DataType::BOOLEAN;
+ case CFX_Value::DataType::kBoolean:
+ pNewData->nType = CFX_Value::DataType::kBoolean;
pNewData->bData = bData;
pNewData->bPersistent = bDefaultPersistent;
break;
- case CFX_Value::DataType::STRING:
- pNewData->nType = CFX_Value::DataType::STRING;
+ case CFX_Value::DataType::kString:
+ pNewData->nType = CFX_Value::DataType::kString;
pNewData->sData = sData;
pNewData->bPersistent = bDefaultPersistent;
break;
- case CFX_Value::DataType::OBJECT:
- pNewData->nType = CFX_Value::DataType::OBJECT;
+ case CFX_Value::DataType::kObject:
+ pNewData->nType = CFX_Value::DataType::kObject;
pNewData->pData.Reset(pData->GetIsolate(), pData);
pNewData->bPersistent = bDefaultPersistent;
break;
- case CFX_Value::DataType::NULLOBJ:
- pNewData->nType = CFX_Value::DataType::NULLOBJ;
+ case CFX_Value::DataType::kNull:
+ pNewData->nType = CFX_Value::DataType::kNull;
pNewData->bPersistent = bDefaultPersistent;
break;
default:
diff --git a/fxjs/cjs_global.h b/fxjs/cjs_global.h
index 2c89188..944c030 100644
--- a/fxjs/cjs_global.h
+++ b/fxjs/cjs_global.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,15 +11,26 @@
#include <memory>
#include <vector>
+#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/cfx_keyvalue.h"
#include "fxjs/cjs_object.h"
#include "fxjs/cjs_result.h"
class CFX_GlobalData;
+// The CJS_Global object is not the V8 global object (i.e. it is not |this|
+// in JavaScript outside of a bound function call). It is a facility for
+// sharing data amongst documents and persisting data within a document
+// between sessions. It is only partially implemented due to security and
+// privacy concerns. It provides access via properties in the usual manner,
+// execpt that these are stored on the C++ side rather than in V8 itself.
+// It is a static object that is available as "global" property of the V8
+// global object and can be manipulated from JavaScript as |global['foo']|
+// for example.
+
class CJS_Global final : public CJS_Object {
public:
- static int GetObjDefnID();
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
static void DefineAllProperties(CFXJS_Engine* pEngine);
@@ -33,6 +44,7 @@
const v8::PropertyCallbackInfo<v8::Value>& info);
static void delprop_static(v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Boolean>& info);
+ static void enumprop_static(const v8::PropertyCallbackInfo<v8::Array>& info);
static void setPersistent_static(
const v8::FunctionCallbackInfo<v8::Value>& info);
@@ -40,16 +52,6 @@
CJS_Global(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
~CJS_Global() override;
- CJS_Result DelProperty(CJS_Runtime* pRuntime, const wchar_t* propname);
-
- CJS_Result setPersistent(CJS_Runtime* pRuntime,
- const std::vector<v8::Local<v8::Value>>& params);
- CJS_Result QueryProperty(const wchar_t* propname);
- CJS_Result GetProperty(CJS_Runtime* pRuntime, const wchar_t* propname);
- CJS_Result SetProperty(CJS_Runtime* pRuntime,
- const wchar_t* propname,
- v8::Local<v8::Value> vp);
-
private:
struct JSGlobalData : public CFX_Value {
public:
@@ -61,11 +63,12 @@
bool bDeleted = false;
};
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const JSMethodSpec MethodSpecs[];
void UpdateGlobalPersistentVariables();
- void CommitGlobalPersisitentVariables(CJS_Runtime* pRuntime);
+ // TODO(crbug.com/pdfium/926): This method is never called.
+ void CommitGlobalPersisitentVariables();
void DestroyGlobalPersisitentVariables();
CJS_Result SetGlobalVariables(const ByteString& propname,
CFX_Value::DataType nType,
@@ -74,15 +77,23 @@
const ByteString& sData,
v8::Local<v8::Object> pData,
bool bDefaultPersistent);
- void ObjectToArray(CJS_Runtime* pRuntime,
- v8::Local<v8::Object> pObj,
- std::vector<std::unique_ptr<CFX_KeyValue>>* pArray);
+ std::vector<std::unique_ptr<CFX_KeyValue>> ObjectToArray(
+ CJS_Runtime* pRuntime,
+ v8::Local<v8::Object> pObj);
void PutObjectProperty(v8::Local<v8::Object> obj, CFX_KeyValue* pData);
+ CJS_Result setPersistent(CJS_Runtime* pRuntime,
+ const std::vector<v8::Local<v8::Value>>& params);
+ bool HasProperty(const ByteString& propname);
+ bool DelProperty(const ByteString& propname);
+ CJS_Result GetProperty(CJS_Runtime* pRuntime, const ByteString& propname);
+ CJS_Result SetProperty(CJS_Runtime* pRuntime,
+ const ByteString& propname,
+ v8::Local<v8::Value> vp);
+ void EnumProperties(CJS_Runtime* pRuntime,
+ const v8::PropertyCallbackInfo<v8::Array>& info);
std::map<ByteString, std::unique_ptr<JSGlobalData>> m_MapGlobal;
- WideString m_sFilePath;
- CFX_GlobalData* m_pGlobalData;
- ObservedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
+ UnownedPtr<CFX_GlobalData> m_pGlobalData;
};
#endif // FXJS_CJS_GLOBAL_H_
diff --git a/fxjs/cjs_globalarrays.cpp b/fxjs/cjs_globalarrays.cpp
index 9cf540e..3dbf62c 100644
--- a/fxjs/cjs_globalarrays.cpp
+++ b/fxjs/cjs_globalarrays.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,21 +6,32 @@
#include "fxjs/cjs_globalarrays.h"
-#define GLOBAL_ARRAY(rt, name, ...) \
- { \
- static const wchar_t* const values[] = {__VA_ARGS__}; \
- v8::Local<v8::Array> array = (rt)->NewArray(); \
- v8::Local<v8::Context> ctx = (rt)->GetIsolate()->GetCurrentContext(); \
- for (size_t i = 0; i < FX_ArraySize(values); ++i) \
- array->Set(ctx, i, (rt)->NewString(values[i])).FromJust(); \
- (rt)->SetConstArray((name), array); \
- (rt)->DefineGlobalConst( \
- (name), [](const v8::FunctionCallbackInfo<v8::Value>& info) { \
- CJS_Object* pObj = CFXJS_Engine::GetObjectPrivate(info.Holder()); \
- CJS_Runtime* pCurrentRuntime = pObj->GetRuntime(); \
- if (pCurrentRuntime) \
- info.GetReturnValue().Set(pCurrentRuntime->GetConstArray(name)); \
- }); \
+#include <iterator>
+
+#include "third_party/base/numerics/safe_conversions.h"
+#include "v8/include/v8-container.h"
+#include "v8/include/v8-isolate.h"
+
+#define GLOBAL_ARRAY(rt, name, ...) \
+ { \
+ static const wchar_t* const values[] = {__VA_ARGS__}; \
+ v8::Local<v8::Array> array = (rt)->NewArray(); \
+ v8::Local<v8::Context> ctx = (rt)->GetIsolate()->GetCurrentContext(); \
+ for (size_t i = 0; i < std::size(values); ++i) { \
+ array \
+ ->Set(ctx, pdfium::base::checked_cast<uint32_t>(i), \
+ (rt)->NewString(values[i])) \
+ .FromJust(); \
+ } \
+ (rt)->SetConstArray((name), array); \
+ (rt)->DefineGlobalConst( \
+ (name), [](const v8::FunctionCallbackInfo<v8::Value>& info) { \
+ CJS_Object* pObj = CFXJS_Engine::GetObjectPrivate(info.GetIsolate(), \
+ info.Holder()); \
+ CJS_Runtime* pCurrentRuntime = pObj->GetRuntime(); \
+ if (pCurrentRuntime) \
+ info.GetReturnValue().Set(pCurrentRuntime->GetConstArray(name)); \
+ }); \
}
// static
diff --git a/fxjs/cjs_globalarrays.h b/fxjs/cjs_globalarrays.h
index 244db2e..726e3a7 100644
--- a/fxjs/cjs_globalarrays.h
+++ b/fxjs/cjs_globalarrays.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
diff --git a/fxjs/cjs_globalconsts.cpp b/fxjs/cjs_globalconsts.cpp
index cb6bd33..854ded8 100644
--- a/fxjs/cjs_globalconsts.cpp
+++ b/fxjs/cjs_globalconsts.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,14 +6,13 @@
#include "fxjs/cjs_globalconsts.h"
-#define GLOBAL_STRING(rt, name, value) \
- (rt)->DefineGlobalConst( \
- (name), [](const v8::FunctionCallbackInfo<v8::Value>& info) { \
- const char* pStr = (value); \
- info.GetReturnValue().Set( \
- v8::String::NewFromUtf8(info.GetIsolate(), pStr, \
- v8::NewStringType::kNormal, strlen(pStr)) \
- .ToLocalChecked()); \
+#include "fxjs/fxv8.h"
+
+#define GLOBAL_STRING(rt, name, value) \
+ (rt)->DefineGlobalConst( \
+ (name), [](const v8::FunctionCallbackInfo<v8::Value>& info) { \
+ info.GetReturnValue().Set( \
+ fxv8::NewStringHelper(info.GetIsolate(), (value))); \
})
// static
diff --git a/fxjs/cjs_globalconsts.h b/fxjs/cjs_globalconsts.h
index 71c689b..f553f3e 100644
--- a/fxjs/cjs_globalconsts.h
+++ b/fxjs/cjs_globalconsts.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
diff --git a/fxjs/cjs_highlight.cpp b/fxjs/cjs_highlight.cpp
index 4ada397..174685d 100644
--- a/fxjs/cjs_highlight.cpp
+++ b/fxjs/cjs_highlight.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,7 +12,7 @@
{"p", JSConstSpec::String, 0, "push"},
{"o", JSConstSpec::String, 0, "outline"}};
-int CJS_Highlight::ObjDefnID = -1;
+uint32_t CJS_Highlight::ObjDefnID = 0;
// static
void CJS_Highlight::DefineJSObjects(CFXJS_Engine* pEngine) {
diff --git a/fxjs/cjs_highlight.h b/fxjs/cjs_highlight.h
index efec127..ad68811 100644
--- a/fxjs/cjs_highlight.h
+++ b/fxjs/cjs_highlight.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
CJS_Highlight() = delete;
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const JSConstSpec ConstSpecs[];
};
diff --git a/fxjs/cjs_icon.cpp b/fxjs/cjs_icon.cpp
index 80be5c8..d3b9da4 100644
--- a/fxjs/cjs_icon.cpp
+++ b/fxjs/cjs_icon.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,11 +9,11 @@
const JSPropertySpec CJS_Icon::PropertySpecs[] = {
{"name", get_name_static, set_name_static}};
-int CJS_Icon::ObjDefnID = -1;
+uint32_t CJS_Icon::ObjDefnID = 0;
const char CJS_Icon::kName[] = "Icon";
// static
-int CJS_Icon::GetObjDefnID() {
+uint32_t CJS_Icon::GetObjDefnID() {
return ObjDefnID;
}
diff --git a/fxjs/cjs_icon.h b/fxjs/cjs_icon.h
index 321f508..54dc1cb 100644
--- a/fxjs/cjs_icon.h
+++ b/fxjs/cjs_icon.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,7 +12,7 @@
class CJS_Icon final : public CJS_Object {
public:
- static int GetObjDefnID();
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
CJS_Icon(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
@@ -24,7 +24,7 @@
JS_STATIC_PROP(name, name, CJS_Icon)
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const char kName[];
static const JSPropertySpec PropertySpecs[];
diff --git a/fxjs/cjs_object.cpp b/fxjs/cjs_object.cpp
index e13a509..f27d37d 100644
--- a/fxjs/cjs_object.cpp
+++ b/fxjs/cjs_object.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,11 +10,11 @@
// static
void CJS_Object::DefineConsts(CFXJS_Engine* pEngine,
- int objId,
+ uint32_t nObjDefnID,
pdfium::span<const JSConstSpec> consts) {
for (const auto& item : consts) {
pEngine->DefineObjConst(
- objId, item.pName,
+ nObjDefnID, item.pName,
item.eType == JSConstSpec::Number
? pEngine->NewNumber(item.number).As<v8::Value>()
: pEngine->NewString(item.pStr).As<v8::Value>());
@@ -23,23 +23,22 @@
// static
void CJS_Object::DefineProps(CFXJS_Engine* pEngine,
- int objId,
+ uint32_t nObjDefnID,
pdfium::span<const JSPropertySpec> props) {
for (const auto& item : props)
- pEngine->DefineObjProperty(objId, item.pName, item.pPropGet, item.pPropPut);
+ pEngine->DefineObjProperty(nObjDefnID, item.pName, item.pPropGet,
+ item.pPropPut);
}
// static
void CJS_Object::DefineMethods(CFXJS_Engine* pEngine,
- int objId,
+ uint32_t nObjDefnID,
pdfium::span<const JSMethodSpec> methods) {
for (const auto& item : methods)
- pEngine->DefineObjMethod(objId, item.pName, item.pMethodCall);
+ pEngine->DefineObjMethod(nObjDefnID, item.pName, item.pMethodCall);
}
CJS_Object::CJS_Object(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime)
- : m_pIsolate(pObject->GetIsolate()),
- m_pV8Object(GetIsolate(), pObject),
- m_pRuntime(pRuntime) {}
+ : m_pV8Object(pObject->GetIsolate(), pObject), m_pRuntime(pRuntime) {}
-CJS_Object::~CJS_Object() {}
+CJS_Object::~CJS_Object() = default;
diff --git a/fxjs/cjs_object.h b/fxjs/cjs_object.h
index 5da72ff..c53568e 100644
--- a/fxjs/cjs_object.h
+++ b/fxjs/cjs_object.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -36,24 +36,24 @@
class CJS_Object {
public:
static void DefineConsts(CFXJS_Engine* pEngine,
- int objId,
+ uint32_t nObjDefnID,
pdfium::span<const JSConstSpec> consts);
static void DefineProps(CFXJS_Engine* pEngine,
- int objId,
+ uint32_t nObjDefnID,
pdfium::span<const JSPropertySpec> consts);
static void DefineMethods(CFXJS_Engine* pEngine,
- int objId,
+ uint32_t nObjDefnID,
pdfium::span<const JSMethodSpec> consts);
CJS_Object(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
virtual ~CJS_Object();
- v8::Local<v8::Object> ToV8Object() { return m_pV8Object.Get(GetIsolate()); }
- v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); }
+ v8::Local<v8::Object> ToV8Object() {
+ return m_pV8Object.Get(GetRuntime()->GetIsolate());
+ }
CJS_Runtime* GetRuntime() const { return m_pRuntime.Get(); }
private:
- UnownedPtr<v8::Isolate> m_pIsolate;
v8::Global<v8::Object> m_pV8Object;
ObservedPtr<CJS_Runtime> m_pRuntime;
};
diff --git a/fxjs/cjs_position.cpp b/fxjs/cjs_position.cpp
index dc9594e..ccf4fe6 100644
--- a/fxjs/cjs_position.cpp
+++ b/fxjs/cjs_position.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,7 +15,7 @@
{"textIconH", JSConstSpec::Number, 5, 0},
{"overlay", JSConstSpec::Number, 6, 0}};
-int CJS_Position::ObjDefnID = -1;
+uint32_t CJS_Position::ObjDefnID = 0;
// static
void CJS_Position::DefineJSObjects(CFXJS_Engine* pEngine) {
diff --git a/fxjs/cjs_position.h b/fxjs/cjs_position.h
index ae951bf..14097a9 100644
--- a/fxjs/cjs_position.h
+++ b/fxjs/cjs_position.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
CJS_Position() = delete;
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const JSConstSpec ConstSpecs[];
};
diff --git a/fxjs/cjs_publicmethods.cpp b/fxjs/cjs_publicmethods.cpp
index 8eed97d..07fe8c5 100644
--- a/fxjs/cjs_publicmethods.cpp
+++ b/fxjs/cjs_publicmethods.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,9 +6,9 @@
#include "fxjs/cjs_publicmethods.h"
+#include <math.h>
+
#include <algorithm>
-#include <cmath>
-#include <cwctype>
#include <iomanip>
#include <iterator>
#include <limits>
@@ -18,15 +18,16 @@
#include <vector>
#include "build/build_config.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfdoc/cpdf_formcontrol.h"
#include "core/fpdfdoc/cpdf_interactiveform.h"
#include "core/fxcrt/fx_extension.h"
+#include "core/fxcrt/fx_string_wrappers.h"
#include "core/fxge/cfx_color.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_interactiveform.h"
#include "fxjs/cjs_color.h"
#include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
#include "fxjs/cjs_field.h"
#include "fxjs/cjs_object.h"
#include "fxjs/cjs_runtime.h"
@@ -34,7 +35,10 @@
#include "fxjs/fx_date_helpers.h"
#include "fxjs/js_define.h"
#include "fxjs/js_resources.h"
-#include "third_party/base/optional.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/base/check.h"
+#include "third_party/base/numerics/safe_conversions.h"
+#include "v8/include/v8-container.h"
// static
const JSMethodSpec CJS_PublicMethods::GlobalFunctionSpecs[] = {
@@ -64,7 +68,7 @@
namespace {
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
constexpr double kDoubleCorrect = 0.000000000000001;
#endif
@@ -93,14 +97,17 @@
return result;
}
-void AlertIfPossible(CJS_EventContext* pContext, const WideString& swMsg) {
+void AlertIfPossible(CJS_EventContext* pContext,
+ const WideString& wsCaller,
+ const WideString& wsMsg) {
CPDFSDK_FormFillEnvironment* pFormFillEnv = pContext->GetFormFillEnv();
- if (pFormFillEnv)
- pFormFillEnv->JS_appAlert(swMsg, WideString(), JSPLATFORM_ALERT_BUTTON_OK,
+ if (pFormFillEnv) {
+ pFormFillEnv->JS_appAlert(wsMsg, wsCaller, JSPLATFORM_ALERT_BUTTON_OK,
JSPLATFORM_ALERT_ICON_STATUS);
+ }
}
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
ByteString CalculateString(double dValue,
int iDec,
int* iDec2,
@@ -112,16 +119,17 @@
// Make sure the number of precision characters will fit.
iDec = std::min(iDec, std::numeric_limits<double>::digits10);
- std::stringstream ss;
+ fxcrt::ostringstream ss;
ss << std::fixed << std::setprecision(iDec) << dValue;
- std::string value = ss.str();
+ fxcrt::string value = ss.str();
size_t pos = value.find('.');
- *iDec2 = pos == std::string::npos ? value.size() : static_cast<int>(pos);
+ *iDec2 = pdfium::base::checked_cast<int>(
+ pos == fxcrt::string::npos ? value.size() : pos);
return ByteString(value.c_str());
}
#endif
-WideString CalcMergedString(const CJS_EventRecorder* event,
+WideString CalcMergedString(const CJS_EventContext* event,
const WideString& value,
const WideString& change) {
WideString prefix = value.First(event->SelStart());
@@ -136,7 +144,8 @@
const std::vector<v8::Local<v8::Value>>&)>
void JSGlobalFunc(const char* func_name_string,
const v8::FunctionCallbackInfo<v8::Value>& info) {
- CJS_Object* pObj = CFXJS_Engine::GetObjectPrivate(info.Holder());
+ CJS_Object* pObj =
+ CFXJS_Engine::GetObjectPrivate(info.GetIsolate(), info.Holder());
if (!pObj)
return;
@@ -171,13 +180,13 @@
return c == '.' || c == ',';
}
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
bool IsStyleWithDigitSeparator(int style) {
return style == 0 || style == 2;
}
char DigitSeparatorForStyle(int style) {
- ASSERT(IsStyleWithDigitSeparator(style));
+ DCHECK(IsStyleWithDigitSeparator(style));
return style == 0 ? ',' : '.';
}
@@ -194,7 +203,7 @@
return IsStyleWithCommaDecimalMark(style) ? ',' : '.';
}
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
void NormalizeDecimalMark(ByteString* str) {
str->Replace(",", ".");
}
@@ -204,20 +213,20 @@
str->Replace(L",", L".");
}
-Optional<double> ApplyNamedOperation(const wchar_t* sFunction,
- double dValue1,
- double dValue2) {
- if (FXSYS_wcsicmp(sFunction, L"AVG") == 0 ||
- FXSYS_wcsicmp(sFunction, L"SUM") == 0) {
+absl::optional<double> ApplyNamedOperation(const WideString& wsFunction,
+ double dValue1,
+ double dValue2) {
+ if (wsFunction.EqualsASCIINoCase("AVG") ||
+ wsFunction.EqualsASCIINoCase("SUM")) {
return dValue1 + dValue2;
}
- if (FXSYS_wcsicmp(sFunction, L"PRD") == 0)
+ if (wsFunction.EqualsASCIINoCase("PRD"))
return dValue1 * dValue2;
- if (FXSYS_wcsicmp(sFunction, L"MIN") == 0)
+ if (wsFunction.EqualsASCIINoCase("MIN"))
return std::min(dValue1, dValue2);
- if (FXSYS_wcsicmp(sFunction, L"MAX") == 0)
+ if (wsFunction.EqualsASCIINoCase("MAX"))
return std::max(dValue1, dValue2);
- return {};
+ return absl::nullopt;
}
} // namespace
@@ -313,14 +322,13 @@
v8::Local<v8::Array> CJS_PublicMethods::AF_MakeArrayFromList(
CJS_Runtime* pRuntime,
v8::Local<v8::Value> val) {
- ASSERT(!val.IsEmpty());
+ DCHECK(!val.IsEmpty());
if (val->IsArray())
return pRuntime->ToArray(val);
- ASSERT(val->IsString());
- WideString wsStr = pRuntime->ToWideString(val);
- ByteString t = wsStr.ToDefANSI();
- const char* p = t.c_str();
+ DCHECK(val->IsString());
+ ByteString bsVal = pRuntime->ToByteString(val);
+ const char* p = bsVal.c_str();
int nIndex = 0;
v8::Local<v8::Array> StrArray = pRuntime->NewArray();
@@ -343,7 +351,8 @@
return StrArray;
}
-double CJS_PublicMethods::ParseDate(const WideString& value,
+double CJS_PublicMethods::ParseDate(v8::Isolate* isolate,
+ const WideString& value,
bool* bWrongFormat) {
double dt = FX_GetDateTime();
int nYear = FX_GetYearFromTime(dt);
@@ -417,26 +426,28 @@
}
// TODO(thestig): Should we set |bWrongFormat| to false here too?
- return JS_DateParse(WideString::Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay,
- nYear, nHour, nMin, nSec));
+ return JS_DateParse(
+ isolate, WideString::Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear,
+ nHour, nMin, nSec));
}
-double CJS_PublicMethods::ParseDateUsingFormat(const WideString& value,
+double CJS_PublicMethods::ParseDateUsingFormat(v8::Isolate* isolate,
+ const WideString& value,
const WideString& format,
bool* bWrongFormat) {
- double dRet = std::nan("");
+ double dRet = nan("");
fxjs::ConversionStatus status = FX_ParseDateUsingFormat(value, format, &dRet);
if (status == fxjs::ConversionStatus::kSuccess)
return dRet;
if (status == fxjs::ConversionStatus::kBadDate) {
- dRet = JS_DateParse(value);
- if (!std::isnan(dRet))
+ dRet = JS_DateParse(isolate, value);
+ if (!isnan(dRet))
return dRet;
}
bool bBadFormat = false;
- dRet = ParseDate(value, &bBadFormat);
+ dRet = ParseDate(isolate, value, &bBadFormat);
if (bWrongFormat)
*bWrongFormat = bBadFormat;
@@ -475,23 +486,23 @@
sPart += c;
break;
case 'm':
- sPart = WideString::Format(L"%d", nMonth);
+ sPart = WideString::FormatInteger(nMonth);
break;
case 'd':
- sPart = WideString::Format(L"%d", nDay);
+ sPart = WideString::FormatInteger(nDay);
break;
case 'H':
- sPart = WideString::Format(L"%d", nHour);
+ sPart = WideString::FormatInteger(nHour);
break;
case 'h':
sPart =
- WideString::Format(L"%d", nHour > 12 ? nHour - 12 : nHour);
+ WideString::FormatInteger(nHour > 12 ? nHour - 12 : nHour);
break;
case 'M':
- sPart = WideString::Format(L"%d", nMin);
+ sPart = WideString::FormatInteger(nMin);
break;
case 's':
- sPart = WideString::Format(L"%d", nSec);
+ sPart = WideString::FormatInteger(nSec);
break;
case 't':
sPart += nHour > 12 ? 'p' : 'a';
@@ -582,17 +593,16 @@
CJS_Result CJS_PublicMethods::AFNumber_Format(
CJS_Runtime* pRuntime,
const std::vector<v8::Local<v8::Value>>& params) {
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
if (params.size() != 6)
return CJS_Result::Failure(JSMessage::kParamError);
CJS_EventContext* pEventContext = pRuntime->GetCurrentEventContext();
- CJS_EventRecorder* pEvent = pEventContext->GetEventRecorder();
- if (!pEvent->HasValue())
+ if (!pEventContext->HasValue())
return CJS_Result::Failure(WideString::FromASCII("No event handler"));
- WideString& Value = pEvent->Value();
- ByteString strValue = StrTrim(Value.ToDefANSI());
+ WideString& Value = pEventContext->Value();
+ ByteString strValue = StrTrim(Value.ToUTF8());
if (strValue.IsEmpty())
return CJS_Result::Success();
@@ -621,7 +631,7 @@
iDec2 = 1;
}
}
- ASSERT(iDec2 >= 0);
+ DCHECK(iDec2 >= 0);
// Processing separator style
if (static_cast<size_t>(iDec2) < strValue.GetLength()) {
@@ -638,7 +648,7 @@
}
// Processing currency string
- Value = WideString::FromDefANSI(strValue.AsStringView());
+ Value = WideString::FromUTF8(strValue.AsStringView());
if (bCurrencyPrepend)
Value = wstrCurrency + Value;
else
@@ -694,24 +704,23 @@
return CJS_Result::Failure(JSMessage::kParamError);
CJS_EventContext* pContext = pRuntime->GetCurrentEventContext();
- CJS_EventRecorder* pEvent = pContext->GetEventRecorder();
- if (!pEvent->HasValue())
+ if (!pContext->HasValue())
return CJS_Result::Failure(JSMessage::kBadObjectError);
- WideString& val = pEvent->Value();
- WideString& wstrChange = pEvent->Change();
+ WideString& val = pContext->Value();
+ WideString& wstrChange = pContext->Change();
WideString wstrValue = val;
- if (pEvent->WillCommit()) {
+ if (pContext->WillCommit()) {
WideString swTemp = StrTrim(wstrValue);
if (swTemp.IsEmpty())
return CJS_Result::Success();
NormalizeDecimalMarkW(&swTemp);
if (!IsNumber(swTemp)) {
- pEvent->Rc() = false;
+ pContext->Rc() = false;
WideString sError = JSGetStringFromID(JSMessage::kInvalidInputError);
- AlertIfPossible(pContext, sError);
+ AlertIfPossible(pContext, L"AFNumber_Keystroke", sError);
return CJS_Result::Failure(sError);
}
// It happens after the last keystroke and before validating,
@@ -719,16 +728,16 @@
}
WideString wstrSelected;
- if (pEvent->SelStart() != -1) {
- wstrSelected = wstrValue.Substr(pEvent->SelStart(),
- pEvent->SelEnd() - pEvent->SelStart());
+ if (pContext->SelStart() != -1) {
+ wstrSelected = wstrValue.Substr(pContext->SelStart(),
+ pContext->SelEnd() - pContext->SelStart());
}
bool bHasSign = wstrValue.Contains(L'-') && !wstrSelected.Contains(L'-');
if (bHasSign) {
// can't insert "change" in front of sign position.
- if (!wstrSelected.IsEmpty() && pEvent->SelStart() == 0) {
- pEvent->Rc() = false;
+ if (!wstrSelected.IsEmpty() && pContext->SelStart() == 0) {
+ pContext->Rc() = false;
return CJS_Result::Success();
}
}
@@ -740,7 +749,7 @@
for (size_t i = 0; i < wstrChange.GetLength(); ++i) {
if (wstrChange[i] == cSep) {
if (bHasSep) {
- pEvent->Rc() = false;
+ pContext->Rc() = false;
return CJS_Result::Success();
}
bHasSep = true;
@@ -748,16 +757,16 @@
}
if (wstrChange[i] == L'-') {
if (bHasSign) {
- pEvent->Rc() = false;
+ pContext->Rc() = false;
return CJS_Result::Success();
}
// sign's position is not correct
if (i != 0) {
- pEvent->Rc() = false;
+ pContext->Rc() = false;
return CJS_Result::Success();
}
- if (pEvent->SelStart() != 0) {
- pEvent->Rc() = false;
+ if (pContext->SelStart() != 0) {
+ pContext->Rc() = false;
return CJS_Result::Success();
}
bHasSign = true;
@@ -765,12 +774,12 @@
}
if (!FXSYS_IsDecimalDigit(wstrChange[i])) {
- pEvent->Rc() = false;
+ pContext->Rc() = false;
return CJS_Result::Success();
}
}
- val = CalcMergedString(pEvent, wstrValue, wstrChange);
+ val = CalcMergedString(pContext, wstrValue, wstrChange);
return CJS_Result::Success();
}
@@ -778,12 +787,11 @@
CJS_Result CJS_PublicMethods::AFPercent_Format(
CJS_Runtime* pRuntime,
const std::vector<v8::Local<v8::Value>>& params) {
-#if !defined(OS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID)
if (params.size() < 2)
return CJS_Result::Failure(JSMessage::kParamError);
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (!pEvent->HasValue())
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -799,8 +807,7 @@
// When the |iDec| value is too big, Acrobat will just return "%".
static constexpr int kDecLimit = 512;
- // TODO(thestig): Calculate this once C++14 can be used to declare variables
- // in constexpr functions.
+ // This count must be in sync with |kDecLimit|.
static constexpr size_t kDigitsInDecLimit = 3;
WideString& Value = pEvent->Value();
if (iDec > kDecLimit) {
@@ -808,7 +815,7 @@
return CJS_Result::Success();
}
- ByteString strValue = StrTrim(Value.ToDefANSI());
+ ByteString strValue = StrTrim(Value.ToUTF8());
if (strValue.IsEmpty())
strValue = "0";
@@ -839,7 +846,7 @@
strValue.ReleaseBuffer(szNewSize);
// for processing separator style
- Optional<size_t> mark_pos = strValue.Find('.');
+ absl::optional<size_t> mark_pos = strValue.Find('.');
if (mark_pos.has_value()) {
char mark = DecimalMarkForStyle(iSepStyle);
if (mark != '.')
@@ -859,7 +866,7 @@
strValue.InsertAtFront('%');
else
strValue.InsertAtBack('%');
- Value = WideString::FromDefANSI(strValue.AsStringView());
+ Value = WideString::FromUTF8(strValue.AsStringView());
#endif
return CJS_Result::Success();
}
@@ -878,8 +885,7 @@
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- CJS_EventContext* pContext = pRuntime->GetCurrentEventContext();
- CJS_EventRecorder* pEvent = pContext->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (!pEvent->HasValue())
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -892,15 +898,16 @@
double dDate;
if (strValue.Contains(L"GMT")) {
// e.g. "Tue Aug 11 14:24:16 GMT+08002009"
- dDate = ParseDateAsGMT(strValue);
+ dDate = ParseDateAsGMT(pRuntime->GetIsolate(), strValue);
} else {
- dDate = ParseDateUsingFormat(strValue, sFormat, nullptr);
+ dDate = ParseDateUsingFormat(pRuntime->GetIsolate(), strValue, sFormat,
+ nullptr);
}
- if (std::isnan(dDate)) {
+ if (isnan(dDate)) {
WideString swMsg = WideString::Format(
JSGetStringFromID(JSMessage::kParseDateError).c_str(), sFormat.c_str());
- AlertIfPossible(pContext, swMsg);
+ AlertIfPossible(pEvent, L"AFDate_FormatEx", swMsg);
return CJS_Result::Failure(JSMessage::kParseDateError);
}
@@ -908,7 +915,8 @@
return CJS_Result::Success();
}
-double CJS_PublicMethods::ParseDateAsGMT(const WideString& strValue) {
+double CJS_PublicMethods::ParseDateAsGMT(v8::Isolate* isolate,
+ const WideString& strValue) {
std::vector<WideString> wsArray;
WideString sTemp;
for (const auto& c : strValue) {
@@ -924,9 +932,9 @@
int nMonth = 1;
sTemp = wsArray[1];
- for (size_t i = 0; i < FX_ArraySize(fxjs::kMonths); ++i) {
- if (sTemp.Compare(fxjs::kMonths[i]) == 0) {
- nMonth = i + 1;
+ for (size_t i = 0; i < std::size(fxjs::kMonths); ++i) {
+ if (sTemp == fxjs::kMonths[i]) {
+ nMonth = static_cast<int>(i) + 1;
break;
}
}
@@ -938,8 +946,8 @@
int nYear = StringToFloat(wsArray[7].AsStringView());
double dRet = FX_MakeDate(FX_MakeDay(nYear, nMonth - 1, nDay),
FX_MakeTime(nHour, nMin, nSec, 0));
- if (std::isnan(dRet))
- dRet = JS_DateParse(strValue);
+ if (isnan(dRet))
+ dRet = JS_DateParse(isolate, strValue);
return dRet;
}
@@ -953,8 +961,7 @@
"AFDate_KeystrokeEx's parameter size not correct"));
}
- CJS_EventContext* pContext = pRuntime->GetCurrentEventContext();
- CJS_EventRecorder* pEvent = pContext->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (!pEvent->WillCommit())
return CJS_Result::Success();
@@ -967,11 +974,12 @@
bool bWrongFormat = false;
WideString sFormat = pRuntime->ToWideString(params[0]);
- double dRet = ParseDateUsingFormat(strValue, sFormat, &bWrongFormat);
- if (bWrongFormat || std::isnan(dRet)) {
+ double dRet = ParseDateUsingFormat(pRuntime->GetIsolate(), strValue, sFormat,
+ &bWrongFormat);
+ if (bWrongFormat || isnan(dRet)) {
WideString swMsg = WideString::Format(
JSGetStringFromID(JSMessage::kParseDateError).c_str(), sFormat.c_str());
- AlertIfPossible(pContext, swMsg);
+ AlertIfPossible(pEvent, L"AFDate_KeystrokeEx", swMsg);
pEvent->Rc() = false;
}
return CJS_Result::Success();
@@ -983,8 +991,8 @@
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- int iIndex = WithinBoundsOrZero(pRuntime->ToInt32(params[0]),
- FX_ArraySize(kDateFormats));
+ int iIndex =
+ WithinBoundsOrZero(pRuntime->ToInt32(params[0]), std::size(kDateFormats));
std::vector<v8::Local<v8::Value>> newParams;
newParams.push_back(pRuntime->NewString(kDateFormats[iIndex]));
return AFDate_FormatEx(pRuntime, newParams);
@@ -997,8 +1005,8 @@
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- int iIndex = WithinBoundsOrZero(pRuntime->ToInt32(params[0]),
- FX_ArraySize(kDateFormats));
+ int iIndex =
+ WithinBoundsOrZero(pRuntime->ToInt32(params[0]), std::size(kDateFormats));
std::vector<v8::Local<v8::Value>> newParams;
newParams.push_back(pRuntime->NewString(kDateFormats[iIndex]));
return AFDate_KeystrokeEx(pRuntime, newParams);
@@ -1011,8 +1019,8 @@
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- int iIndex = WithinBoundsOrZero(pRuntime->ToInt32(params[0]),
- FX_ArraySize(kTimeFormats));
+ int iIndex =
+ WithinBoundsOrZero(pRuntime->ToInt32(params[0]), std::size(kTimeFormats));
std::vector<v8::Local<v8::Value>> newParams;
newParams.push_back(pRuntime->NewString(kTimeFormats[iIndex]));
return AFDate_FormatEx(pRuntime, newParams);
@@ -1024,8 +1032,8 @@
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- int iIndex = WithinBoundsOrZero(pRuntime->ToInt32(params[0]),
- FX_ArraySize(kTimeFormats));
+ int iIndex =
+ WithinBoundsOrZero(pRuntime->ToInt32(params[0]), std::size(kTimeFormats));
std::vector<v8::Local<v8::Value>> newParams;
newParams.push_back(pRuntime->NewString(kTimeFormats[iIndex]));
return AFDate_KeystrokeEx(pRuntime, newParams);
@@ -1050,8 +1058,7 @@
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (!pEvent->HasValue())
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -1086,8 +1093,7 @@
if (params.size() < 1)
return CJS_Result::Failure(JSMessage::kParamError);
- CJS_EventContext* pContext = pRuntime->GetCurrentEventContext();
- CJS_EventRecorder* pEvent = pContext->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (!pEvent->HasValue())
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -1101,7 +1107,7 @@
return CJS_Result::Success();
if (valEvent.GetLength() > wstrMask.GetLength()) {
- AlertIfPossible(pContext,
+ AlertIfPossible(pEvent, L"AFSpecial_KeystrokeEx",
JSGetStringFromID(JSMessage::kParamTooLongError));
pEvent->Rc() = false;
return CJS_Result::Success();
@@ -1113,7 +1119,7 @@
break;
}
if (iIndex != wstrMask.GetLength()) {
- AlertIfPossible(pContext,
+ AlertIfPossible(pEvent, L"AFSpecial_KeystrokeEx",
JSGetStringFromID(JSMessage::kInvalidInputError));
pEvent->Rc() = false;
}
@@ -1129,20 +1135,22 @@
size_t combined_len = valEvent.GetLength() + wChange.GetLength() +
pEvent->SelStart() - pEvent->SelEnd();
if (combined_len > wstrMask.GetLength()) {
- AlertIfPossible(pContext, JSGetStringFromID(JSMessage::kParamTooLongError));
+ AlertIfPossible(pEvent, L"AFSpecial_KeystrokeEx",
+ JSGetStringFromID(JSMessage::kParamTooLongError));
pEvent->Rc() = false;
return CJS_Result::Success();
}
if (iIndexMask >= wstrMask.GetLength() && !wChange.IsEmpty()) {
- AlertIfPossible(pContext, JSGetStringFromID(JSMessage::kParamTooLongError));
+ AlertIfPossible(pEvent, L"AFSpecial_KeystrokeEx",
+ JSGetStringFromID(JSMessage::kParamTooLongError));
pEvent->Rc() = false;
return CJS_Result::Success();
}
for (size_t i = 0; i < wChange.GetLength(); ++i) {
if (iIndexMask >= wstrMask.GetLength()) {
- AlertIfPossible(pContext,
+ AlertIfPossible(pEvent, L"AFSpecial_KeystrokeEx",
JSGetStringFromID(JSMessage::kParamTooLongError));
pEvent->Rc() = false;
return CJS_Result::Success();
@@ -1168,8 +1176,7 @@
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- CJS_EventRecorder* pEvent =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (!pEvent->HasValue())
return CJS_Result::Failure(JSMessage::kBadObjectError);
@@ -1203,19 +1210,17 @@
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- CJS_EventRecorder* pEventRecorder =
- pRuntime->GetCurrentEventContext()->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
WideString swValue;
- if (pEventRecorder->HasValue())
- swValue = pEventRecorder->Value();
+ if (pEvent->HasValue())
+ swValue = pEvent->Value();
- if (pEventRecorder->WillCommit())
+ if (pEvent->WillCommit())
return CJS_Result::Success(pRuntime->NewString(swValue.AsStringView()));
return CJS_Result::Success(pRuntime->NewString(
- CalcMergedString(pEventRecorder, swValue, pEventRecorder->Change())
- .AsStringView()));
+ CalcMergedString(pEvent, swValue, pEvent->Change()).AsStringView()));
}
CJS_Result CJS_PublicMethods::AFParseDateEx(
@@ -1226,11 +1231,13 @@
WideString sValue = pRuntime->ToWideString(params[0]);
WideString sFormat = pRuntime->ToWideString(params[1]);
- double dDate = ParseDateUsingFormat(sValue, sFormat, nullptr);
- if (std::isnan(dDate)) {
+ double dDate =
+ ParseDateUsingFormat(pRuntime->GetIsolate(), sValue, sFormat, nullptr);
+ if (isnan(dDate)) {
WideString swMsg = WideString::Format(
JSGetStringFromID(JSMessage::kParseDateError).c_str(), sFormat.c_str());
- AlertIfPossible(pRuntime->GetCurrentEventContext(), swMsg);
+ AlertIfPossible(pRuntime->GetCurrentEventContext(), L"AFParseDateEx",
+ swMsg);
return CJS_Result::Failure(JSMessage::kParseDateError);
}
return CJS_Result::Success(pRuntime->NewNumber(dDate));
@@ -1245,10 +1252,10 @@
WideString sFunction = pRuntime->ToWideString(params[0]);
double arg1 = pRuntime->ToDouble(params[1]);
double arg2 = pRuntime->ToDouble(params[2]);
- if (std::isnan(arg1) || std::isnan(arg2))
+ if (isnan(arg1) || isnan(arg2))
return CJS_Result::Failure(JSMessage::kValueError);
- Optional<double> result = ApplyNamedOperation(sFunction.c_str(), arg1, arg2);
+ absl::optional<double> result = ApplyNamedOperation(sFunction, arg1, arg2);
if (!result.has_value())
return CJS_Result::Failure(JSMessage::kValueError);
@@ -1347,8 +1354,8 @@
wcscmp(sFunction.c_str(), L"MAX") == 0)) {
dValue = dTemp;
}
- Optional<double> dResult =
- ApplyNamedOperation(sFunction.c_str(), dValue, dTemp);
+ absl::optional<double> dResult =
+ ApplyNamedOperation(sFunction, dValue, dTemp);
if (!dResult.has_value())
return CJS_Result::Failure(JSMessage::kValueError);
@@ -1360,13 +1367,11 @@
if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
dValue /= nFieldsCount;
- dValue = floor(dValue * FXSYS_pow(10, 6) + 0.49) / FXSYS_pow(10, 6);
+ dValue = floor(dValue * powf(10, 6) + 0.49) / powf(10, 6);
CJS_EventContext* pContext = pRuntime->GetCurrentEventContext();
- if (pContext->GetEventRecorder()->HasValue()) {
- pContext->GetEventRecorder()->Value() =
- pRuntime->ToWideString(pRuntime->NewNumber(dValue));
- }
+ if (pContext->HasValue())
+ pContext->Value() = pRuntime->ToWideString(pRuntime->NewNumber(dValue));
return CJS_Result::Success();
}
@@ -1379,15 +1384,14 @@
if (params.size() != 4)
return CJS_Result::Failure(JSMessage::kParamError);
- CJS_EventContext* pContext = pRuntime->GetCurrentEventContext();
- CJS_EventRecorder* pEvent = pContext->GetEventRecorder();
+ CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
if (!pEvent->HasValue())
return CJS_Result::Failure(JSMessage::kBadObjectError);
if (pEvent->Value().IsEmpty())
return CJS_Result::Success();
- double dEentValue = atof(pEvent->Value().ToDefANSI().c_str());
+ double dEventValue = atof(pEvent->Value().ToUTF8().c_str());
bool bGreaterThan = pRuntime->ToBoolean(params[0]);
double dGreaterThan = pRuntime->ToDouble(params[1]);
bool bLessThan = pRuntime->ToBoolean(params[2]);
@@ -1395,25 +1399,25 @@
WideString swMsg;
if (bGreaterThan && bLessThan) {
- if (dEentValue < dGreaterThan || dEentValue > dLessThan)
+ if (dEventValue < dGreaterThan || dEventValue > dLessThan)
swMsg = WideString::Format(
JSGetStringFromID(JSMessage::kRangeBetweenError).c_str(),
pRuntime->ToWideString(params[1]).c_str(),
pRuntime->ToWideString(params[3]).c_str());
} else if (bGreaterThan) {
- if (dEentValue < dGreaterThan)
+ if (dEventValue < dGreaterThan)
swMsg = WideString::Format(
JSGetStringFromID(JSMessage::kRangeGreaterError).c_str(),
pRuntime->ToWideString(params[1]).c_str());
} else if (bLessThan) {
- if (dEentValue > dLessThan)
+ if (dEventValue > dLessThan)
swMsg = WideString::Format(
JSGetStringFromID(JSMessage::kRangeLessError).c_str(),
pRuntime->ToWideString(params[3]).c_str());
}
if (!swMsg.IsEmpty()) {
- AlertIfPossible(pContext, swMsg);
+ AlertIfPossible(pEvent, L"AFRange_Validate", swMsg);
pEvent->Rc() = false;
}
return CJS_Result::Success();
diff --git a/fxjs/cjs_publicmethods.h b/fxjs/cjs_publicmethods.h
index 53a4dcc..ddf13cd 100644
--- a/fxjs/cjs_publicmethods.h
+++ b/fxjs/cjs_publicmethods.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -18,9 +18,12 @@
static void DefineJSObjects(CFXJS_Engine* pEngine);
- static double ParseDate(const WideString& value, bool* bWrongFormat);
- static double ParseDateAsGMT(const WideString& value);
- static double ParseDateUsingFormat(const WideString& value,
+ static double ParseDate(v8::Isolate* isolate,
+ const WideString& value,
+ bool* bWrongFormat);
+ static double ParseDateAsGMT(v8::Isolate* isolate, const WideString& value);
+ static double ParseDateUsingFormat(v8::Isolate* isolate,
+ const WideString& value,
const WideString& format,
bool* bWrongFormat);
diff --git a/fxjs/cjs_publicmethods_embeddertest.cpp b/fxjs/cjs_publicmethods_embeddertest.cpp
index d35f0cc..5a1a6e7 100644
--- a/fxjs/cjs_publicmethods_embeddertest.cpp
+++ b/fxjs/cjs_publicmethods_embeddertest.cpp
@@ -1,16 +1,22 @@
-// Copyright 2015 PDFium Authors. All rights reserved.
+// Copyright 2015 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <cmath>
+#include <math.h>
+
#include <vector>
#include "core/fxcrt/fx_string.h"
#include "fpdfsdk/cpdfsdk_helpers.h"
#include "fxjs/cjs_event_context.h"
#include "fxjs/cjs_publicmethods.h"
+#include "testing/external_engine_embedder_test.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/js_embedder_test.h"
+#include "v8/include/v8-container.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-isolate.h"
+#include "v8/include/v8-local-handle.h"
+#include "v8/include/v8-value.h"
namespace {
@@ -20,7 +26,7 @@
} // namespace
-class CJS_PublicMethodsEmbedderTest : public JSEmbedderTest {};
+class CJS_PublicMethodsEmbedderTest : public ExternalEngineEmbedderTest {};
TEST_F(CJS_PublicMethodsEmbedderTest, ParseDateUsingFormat) {
v8::Isolate::Scope isolate_scope(isolate());
@@ -31,80 +37,80 @@
// 1968
bWrongFormat = false;
- date = CJS_PublicMethods::ParseDateUsingFormat(L"06/25/1968", L"mm/dd/yyyy",
- &bWrongFormat);
+ date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"06/25/1968",
+ L"mm/dd/yyyy", &bWrongFormat);
date = RoundDownDate(date);
EXPECT_DOUBLE_EQ(-47865600000, date);
EXPECT_FALSE(bWrongFormat);
// 1968
bWrongFormat = false;
- date = CJS_PublicMethods::ParseDateUsingFormat(L"25061968", L"ddmmyyyy",
- &bWrongFormat);
+ date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"25061968",
+ L"ddmmyyyy", &bWrongFormat);
date = RoundDownDate(date);
EXPECT_DOUBLE_EQ(-47865600000, date);
EXPECT_FALSE(bWrongFormat);
// 1968
bWrongFormat = false;
- date = CJS_PublicMethods::ParseDateUsingFormat(L"19680625", L"yyyymmdd",
- &bWrongFormat);
+ date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"19680625",
+ L"yyyymmdd", &bWrongFormat);
date = RoundDownDate(date);
EXPECT_DOUBLE_EQ(-47865600000, date);
EXPECT_FALSE(bWrongFormat);
// 1985
bWrongFormat = false;
- date = CJS_PublicMethods::ParseDateUsingFormat(L"31121985", L"ddmmyyyy",
- &bWrongFormat);
+ date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"31121985",
+ L"ddmmyyyy", &bWrongFormat);
date = RoundDownDate(date);
EXPECT_DOUBLE_EQ(504835200000.0, date);
EXPECT_FALSE(bWrongFormat);
// 2085, the other '85.
bWrongFormat = false;
- date = CJS_PublicMethods::ParseDateUsingFormat(L"311285", L"ddmmyy",
- &bWrongFormat);
+ date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"311285",
+ L"ddmmyy", &bWrongFormat);
date = RoundDownDate(date);
EXPECT_DOUBLE_EQ(3660595200000.0, date);
EXPECT_FALSE(bWrongFormat);
// 1995
bWrongFormat = false;
- date = CJS_PublicMethods::ParseDateUsingFormat(L"01021995", L"ddmmyyyy",
- &bWrongFormat);
+ date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"01021995",
+ L"ddmmyyyy", &bWrongFormat);
date = RoundDownDate(date);
EXPECT_DOUBLE_EQ(791596800000.0, date);
EXPECT_FALSE(bWrongFormat);
// 2095, the other '95.
bWrongFormat = false;
- date = CJS_PublicMethods::ParseDateUsingFormat(L"010295", L"ddmmyy",
- &bWrongFormat);
+ date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"010295",
+ L"ddmmyy", &bWrongFormat);
date = RoundDownDate(date);
EXPECT_DOUBLE_EQ(3947356800000.0, date);
EXPECT_FALSE(bWrongFormat);
// 2005
bWrongFormat = false;
- date = CJS_PublicMethods::ParseDateUsingFormat(L"01022005", L"ddmmyyyy",
- &bWrongFormat);
+ date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"01022005",
+ L"ddmmyyyy", &bWrongFormat);
date = RoundDownDate(date);
EXPECT_DOUBLE_EQ(1107216000000.0, date);
EXPECT_FALSE(bWrongFormat);
// 2005
bWrongFormat = false;
- date = CJS_PublicMethods::ParseDateUsingFormat(L"010205", L"ddmmyy",
- &bWrongFormat);
+ date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"010205",
+ L"ddmmyy", &bWrongFormat);
date = RoundDownDate(date);
EXPECT_DOUBLE_EQ(1107216000000.0, date);
EXPECT_FALSE(bWrongFormat);
// 2005 in a different format. https://crbug.com/436572
bWrongFormat = false;
- date = CJS_PublicMethods::ParseDateUsingFormat(L"050201", L"yymmdd",
- &bWrongFormat);
+ date = CJS_PublicMethods::ParseDateUsingFormat(isolate(), L"050201",
+ L"yymmdd", &bWrongFormat);
date = RoundDownDate(date);
EXPECT_DOUBLE_EQ(1107216000000.0, date);
EXPECT_FALSE(bWrongFormat);
@@ -182,7 +188,7 @@
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(GetV8Context());
- EXPECT_TRUE(OpenDocument("calculate.pdf"));
+ ASSERT_TRUE(OpenDocument("calculate.pdf"));
auto* page = LoadPage(0);
ASSERT_TRUE(page);
@@ -191,8 +197,7 @@
runtime.NewEventContext();
WideString result;
- runtime.GetCurrentEventContext()->GetEventRecorder()->SetValueForTest(
- &result);
+ runtime.GetCurrentEventContext()->SetValueForTest(&result);
auto ary = runtime.NewArray();
runtime.PutArrayElement(ary, 0, runtime.NewString("Calc1_A"));
@@ -205,8 +210,7 @@
CJS_Result ret = CJS_PublicMethods::AFSimple_Calculate(&runtime, params);
UnloadPage(page);
- runtime.GetCurrentEventContext()->GetEventRecorder()->SetValueForTest(
- nullptr);
+ runtime.GetCurrentEventContext()->SetValueForTest(nullptr);
ASSERT_TRUE(!ret.HasError());
ASSERT_TRUE(!ret.HasReturn());
@@ -218,7 +222,7 @@
v8::HandleScope handle_scope(isolate());
v8::Context::Scope context_scope(GetV8Context());
- EXPECT_TRUE(OpenDocument("calculate.pdf"));
+ ASSERT_TRUE(OpenDocument("calculate.pdf"));
auto* page = LoadPage(0);
ASSERT_TRUE(page);
@@ -226,7 +230,7 @@
CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle()));
runtime.NewEventContext();
- auto* handler = runtime.GetCurrentEventContext()->GetEventRecorder();
+ auto* handler = runtime.GetCurrentEventContext();
bool valid = true;
WideString result = L"-10";
diff --git a/fxjs/cjs_publicmethods_unittest.cpp b/fxjs/cjs_publicmethods_unittest.cpp
index 1d72418..a5b9314 100644
--- a/fxjs/cjs_publicmethods_unittest.cpp
+++ b/fxjs/cjs_publicmethods_unittest.cpp
@@ -1,9 +1,11 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fxjs/cjs_publicmethods.h"
+#include <iterator>
+
#include "testing/gtest/include/gtest/gtest.h"
TEST(CJS_PublicMethods, IsNumber) {
@@ -42,7 +44,7 @@
{L"0123", true},
{L"9876123", true},
};
- for (size_t i = 0; i < FX_ArraySize(test_data); ++i) {
+ for (size_t i = 0; i < std::size(test_data); ++i) {
EXPECT_EQ(test_data[i].expected,
CJS_PublicMethods::IsNumber(test_data[i].input))
<< "for case " << i;
diff --git a/fxjs/cjs_result.cpp b/fxjs/cjs_result.cpp
index 92f2b0b..8bed633 100644
--- a/fxjs/cjs_result.cpp
+++ b/fxjs/cjs_result.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,7 +6,7 @@
#include "fxjs/cjs_result.h"
-CJS_Result::CJS_Result() {}
+CJS_Result::CJS_Result() = default;
CJS_Result::CJS_Result(v8::Local<v8::Value> ret) : return_(ret) {}
diff --git a/fxjs/cjs_result.h b/fxjs/cjs_result.h
index 5e1ed7c..993a4dc 100644
--- a/fxjs/cjs_result.h
+++ b/fxjs/cjs_result.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,12 +8,12 @@
#define FXJS_CJS_RESULT_H_
#include "fxjs/js_resources.h"
-#include "third_party/base/optional.h"
-#include "v8/include/v8.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "v8/include/v8-forward.h"
class CJS_Result {
public:
- // Wrap constructors with static methods so we can apply WARN_UNUSED_RESULT,
+ // Wrap constructors with static methods so we can apply [[nodiscard]],
// otherwise we can't catch places where someone mistakenly writes:
//
// if (error)
@@ -24,14 +24,14 @@
// if (error)
// return CJS_Result(JS_ERROR_CODE);
//
- static CJS_Result Success() WARN_UNUSED_RESULT { return CJS_Result(); }
- static CJS_Result Success(v8::Local<v8::Value> value) WARN_UNUSED_RESULT {
+ [[nodiscard]] static CJS_Result Success() { return CJS_Result(); }
+ [[nodiscard]] static CJS_Result Success(v8::Local<v8::Value> value) {
return CJS_Result(value);
}
- static CJS_Result Failure(const WideString& str) WARN_UNUSED_RESULT {
+ [[nodiscard]] static CJS_Result Failure(const WideString& str) {
return CJS_Result(str);
}
- static CJS_Result Failure(JSMessage id) WARN_UNUSED_RESULT {
+ [[nodiscard]] static CJS_Result Failure(JSMessage id) {
return CJS_Result(id);
}
@@ -39,7 +39,7 @@
~CJS_Result();
bool HasError() const { return error_.has_value(); }
- WideString Error() const { return error_.value(); }
+ const WideString& Error() const { return error_.value(); }
bool HasReturn() const { return !return_.IsEmpty(); }
v8::Local<v8::Value> Return() const { return return_; }
@@ -50,7 +50,7 @@
explicit CJS_Result(const WideString&); // Error with custom message.
explicit CJS_Result(JSMessage id); // Error with stock message.
- Optional<WideString> error_;
+ absl::optional<WideString> error_;
v8::Local<v8::Value> return_;
};
diff --git a/fxjs/cjs_runtime.cpp b/fxjs/cjs_runtime.cpp
index 919d47a..f7d76da 100644
--- a/fxjs/cjs_runtime.cpp
+++ b/fxjs/cjs_runtime.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,8 @@
#include "fxjs/cjs_runtime.h"
+#include <math.h>
+
#include <algorithm>
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
@@ -19,7 +21,6 @@
#include "fxjs/cjs_document.h"
#include "fxjs/cjs_event.h"
#include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
#include "fxjs/cjs_field.h"
#include "fxjs/cjs_font.h"
#include "fxjs/cjs_global.h"
@@ -36,14 +37,20 @@
#include "fxjs/cjs_timerobj.h"
#include "fxjs/cjs_util.h"
#include "fxjs/cjs_zoomtype.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_define.h"
-#include "third_party/base/ptr_util.h"
+#include "third_party/base/check_op.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-exception.h"
+#include "v8/include/v8-isolate.h"
CJS_Runtime::CJS_Runtime(CPDFSDK_FormFillEnvironment* pFormFillEnv)
: m_pFormFillEnv(pFormFillEnv) {
v8::Isolate* pIsolate = nullptr;
IPDF_JSPLATFORM* pPlatform = m_pFormFillEnv->GetFormFillInfo()->m_pJsPlatform;
if (pPlatform->version <= 2) {
+ // Backwards compatibility - JS now initialized earlier in more modern
+ // JSPLATFORM versions.
unsigned int embedderDataSlot = 0;
v8::Isolate* pExternalIsolate = nullptr;
if (pPlatform->version == 2) {
@@ -120,12 +127,12 @@
}
IJS_EventContext* CJS_Runtime::NewEventContext() {
- m_EventContextArray.push_back(pdfium::MakeUnique<CJS_EventContext>(this));
+ m_EventContextArray.push_back(std::make_unique<CJS_EventContext>(this));
return m_EventContextArray.back().get();
}
void CJS_Runtime::ReleaseEventContext(IJS_EventContext* pContext) {
- ASSERT(pContext == m_EventContextArray.back().get());
+ DCHECK_EQ(pContext, m_EventContextArray.back().get());
m_EventContextArray.pop_back();
}
@@ -134,7 +141,7 @@
: m_EventContextArray.back().get();
}
-TimerHandlerIface* CJS_Runtime::GetTimerHandler() const {
+CFX_Timer::HandlerIface* CJS_Runtime::GetTimerHandler() const {
return m_pFormFillEnv ? m_pFormFillEnv->GetTimerHandler() : nullptr;
}
@@ -148,7 +155,7 @@
if (pThis.IsEmpty())
return;
- auto pJSDocument = JSGetObject<CJS_Document>(pThis);
+ auto pJSDocument = JSGetObject<CJS_Document>(GetIsolate(), pThis);
if (!pJSDocument)
return;
@@ -159,7 +166,7 @@
return m_pFormFillEnv.Get();
}
-Optional<IJS_Runtime::JS_Error> CJS_Runtime::ExecuteScript(
+absl::optional<IJS_Runtime::JS_Error> CJS_Runtime::ExecuteScript(
const WideString& script) {
return Execute(script);
}
@@ -176,22 +183,16 @@
return this;
}
-bool CJS_Runtime::GetValueByNameFromGlobalObject(ByteStringView utf8Name,
- v8::Local<v8::Value>* pValue) {
+v8::Local<v8::Value> CJS_Runtime::GetValueByNameFromGlobalObject(
+ ByteStringView utf8Name) {
v8::Isolate::Scope isolate_scope(GetIsolate());
v8::Local<v8::Context> context = GetV8Context();
v8::Context::Scope context_scope(context);
- v8::Local<v8::String> str =
- v8::String::NewFromUtf8(GetIsolate(), utf8Name.unterminated_c_str(),
- v8::NewStringType::kNormal, utf8Name.GetLength())
- .ToLocalChecked();
- v8::MaybeLocal<v8::Value> maybe_propvalue =
- context->Global()->Get(context, str);
- if (maybe_propvalue.IsEmpty())
- return false;
-
- *pValue = maybe_propvalue.ToLocalChecked();
- return true;
+ v8::Local<v8::String> str = fxv8::NewStringHelper(GetIsolate(), utf8Name);
+ v8::MaybeLocal<v8::Value> maybe_value = context->Global()->Get(context, str);
+ if (maybe_value.IsEmpty())
+ return v8::Local<v8::Value>();
+ return maybe_value.ToLocalChecked();
}
bool CJS_Runtime::SetValueByNameInGlobalObject(ByteStringView utf8Name,
@@ -203,10 +204,7 @@
v8::Isolate::Scope isolate_scope(pIsolate);
v8::Local<v8::Context> context = GetV8Context();
v8::Context::Scope context_scope(context);
- v8::Local<v8::String> str =
- v8::String::NewFromUtf8(pIsolate, utf8Name.unterminated_c_str(),
- v8::NewStringType::kNormal, utf8Name.GetLength())
- .ToLocalChecked();
+ v8::Local<v8::String> str = fxv8::NewStringHelper(pIsolate, utf8Name);
v8::Maybe<bool> result = context->Global()->Set(context, str, pValue);
return result.IsJust() && result.FromJust();
}
@@ -215,22 +213,21 @@
v8::Local<v8::Value> value) {
bool bAllowNaN = false;
if (value->IsString()) {
- ByteString bstr = ToWideString(value).ToDefANSI();
+ ByteString bstr = fxv8::ToByteString(GetIsolate(), value.As<v8::String>());
if (bstr.IsEmpty())
return value;
if (bstr == "NaN")
bAllowNaN = true;
}
- v8::Isolate* pIsolate = GetIsolate();
- v8::TryCatch try_catch(pIsolate);
+ v8::TryCatch try_catch(GetIsolate());
v8::MaybeLocal<v8::Number> maybeNum =
- value->ToNumber(pIsolate->GetCurrentContext());
+ value->ToNumber(GetIsolate()->GetCurrentContext());
if (maybeNum.IsEmpty())
return value;
v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
- if (std::isnan(num->Value()) && !bAllowNaN)
+ if (isnan(num->Value()) && !bAllowNaN)
return value;
return num;
diff --git a/fxjs/cjs_runtime.h b/fxjs/cjs_runtime.h
index b3f8ef6..a3569f6 100644
--- a/fxjs/cjs_runtime.h
+++ b/fxjs/cjs_runtime.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,20 +12,19 @@
#include <utility>
#include <vector>
+#include "core/fxcrt/cfx_timer.h"
#include "core/fxcrt/observed_ptr.h"
-#include "core/fxcrt/timerhandler_iface.h"
#include "fxjs/cfxjs_engine.h"
-#include "fxjs/cjs_eventrecorder.h"
+#include "fxjs/cjs_event_context.h"
#include "fxjs/ijs_runtime.h"
-class CJS_EventContext;
class CPDFSDK_FormFillEnvironment;
class CJS_Runtime final : public IJS_Runtime,
public CFXJS_Engine,
public Observable {
public:
- using FieldEvent = std::pair<WideString, JS_EVENT_T>;
+ using FieldEvent = std::pair<WideString, CJS_EventContext::Kind>;
explicit CJS_Runtime(CPDFSDK_FormFillEnvironment* pFormFillEnv);
~CJS_Runtime() override;
@@ -35,11 +34,11 @@
IJS_EventContext* NewEventContext() override;
void ReleaseEventContext(IJS_EventContext* pContext) override;
CPDFSDK_FormFillEnvironment* GetFormFillEnv() const override;
- Optional<IJS_Runtime::JS_Error> ExecuteScript(
+ absl::optional<IJS_Runtime::JS_Error> ExecuteScript(
const WideString& script) override;
CJS_EventContext* GetCurrentEventContext() const;
- TimerHandlerIface* GetTimerHandler() const;
+ CFX_Timer::HandlerIface* GetTimerHandler() const;
// Returns true if the event isn't already found in the set.
bool AddEventToSet(const FieldEvent& event);
@@ -53,8 +52,7 @@
// value will be returned, otherwise |value| is returned.
v8::Local<v8::Value> MaybeCoerceToNumber(v8::Local<v8::Value> value);
- bool GetValueByNameFromGlobalObject(ByteStringView utf8Name,
- v8::Local<v8::Value>* pValue);
+ v8::Local<v8::Value> GetValueByNameFromGlobalObject(ByteStringView utf8Name);
bool SetValueByNameInGlobalObject(ByteStringView utf8Name,
v8::Local<v8::Value> pValue);
diff --git a/fxjs/cjs_runtimestub.cpp b/fxjs/cjs_runtimestub.cpp
index 6e313de..0a68a17 100644
--- a/fxjs/cjs_runtimestub.cpp
+++ b/fxjs/cjs_runtimestub.cpp
@@ -1,4 +1,4 @@
-// Copyright 2015 PDFium Authors. All rights reserved.
+// Copyright 2015 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,7 +7,6 @@
#include "fxjs/cjs_runtimestub.h"
#include "fxjs/cjs_event_context_stub.h"
-#include "third_party/base/ptr_util.h"
CJS_RuntimeStub::CJS_RuntimeStub(CPDFSDK_FormFillEnvironment* pFormFillEnv)
: m_pFormFillEnv(pFormFillEnv) {}
@@ -16,21 +15,21 @@
IJS_EventContext* CJS_RuntimeStub::NewEventContext() {
if (!m_pContext)
- m_pContext = pdfium::MakeUnique<CJS_EventContextStub>();
+ m_pContext = std::make_unique<CJS_EventContextStub>();
return m_pContext.get();
}
void CJS_RuntimeStub::ReleaseEventContext(IJS_EventContext* pContext) {}
CPDFSDK_FormFillEnvironment* CJS_RuntimeStub::GetFormFillEnv() const {
- return m_pFormFillEnv.Get();
+ return m_pFormFillEnv;
}
CJS_Runtime* CJS_RuntimeStub::AsCJSRuntime() {
return nullptr;
}
-Optional<IJS_Runtime::JS_Error> CJS_RuntimeStub::ExecuteScript(
+absl::optional<IJS_Runtime::JS_Error> CJS_RuntimeStub::ExecuteScript(
const WideString& script) {
- return pdfium::nullopt;
+ return absl::nullopt;
}
diff --git a/fxjs/cjs_runtimestub.h b/fxjs/cjs_runtimestub.h
index 2b5e713..c58e2c4 100644
--- a/fxjs/cjs_runtimestub.h
+++ b/fxjs/cjs_runtimestub.h
@@ -1,4 +1,4 @@
-// Copyright 2018 PDFium Authors. All rights reserved.
+// Copyright 2018 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,8 +9,8 @@
#include <memory>
-#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/unowned_ptr.h"
+#include "core/fxcrt/widestring.h"
#include "fxjs/ijs_runtime.h"
class CPDFSDK_FormFillEnvironment;
@@ -27,7 +27,7 @@
void ReleaseEventContext(IJS_EventContext* pContext) override;
CPDFSDK_FormFillEnvironment* GetFormFillEnv() const override;
- Optional<IJS_Runtime::JS_Error> ExecuteScript(
+ absl::optional<IJS_Runtime::JS_Error> ExecuteScript(
const WideString& script) override;
private:
diff --git a/fxjs/cjs_scalehow.cpp b/fxjs/cjs_scalehow.cpp
index 999949c..b64da9f 100644
--- a/fxjs/cjs_scalehow.cpp
+++ b/fxjs/cjs_scalehow.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,7 +10,7 @@
{"proportional", JSConstSpec::Number, 0, 0},
{"anamorphic", JSConstSpec::Number, 1, 0}};
-int CJS_ScaleHow::ObjDefnID = -1;
+uint32_t CJS_ScaleHow::ObjDefnID = 0;
// static
void CJS_ScaleHow::DefineJSObjects(CFXJS_Engine* pEngine) {
diff --git a/fxjs/cjs_scalehow.h b/fxjs/cjs_scalehow.h
index f8c7eb5..b5ab3e5 100644
--- a/fxjs/cjs_scalehow.h
+++ b/fxjs/cjs_scalehow.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
CJS_ScaleHow() = delete;
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const JSConstSpec ConstSpecs[];
};
diff --git a/fxjs/cjs_scalewhen.cpp b/fxjs/cjs_scalewhen.cpp
index 5f39153..e8a3dd4 100644
--- a/fxjs/cjs_scalewhen.cpp
+++ b/fxjs/cjs_scalewhen.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,7 +12,7 @@
{"tooBig", JSConstSpec::Number, 2, 0},
{"tooSmall", JSConstSpec::Number, 3, 0}};
-int CJS_ScaleWhen::ObjDefnID = -1;
+uint32_t CJS_ScaleWhen::ObjDefnID = 0;
// static
void CJS_ScaleWhen::DefineJSObjects(CFXJS_Engine* pEngine) {
diff --git a/fxjs/cjs_scalewhen.h b/fxjs/cjs_scalewhen.h
index ef046f9..43ab541 100644
--- a/fxjs/cjs_scalewhen.h
+++ b/fxjs/cjs_scalewhen.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
CJS_ScaleWhen() = delete;
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const JSConstSpec ConstSpecs[];
};
diff --git a/fxjs/cjs_style.cpp b/fxjs/cjs_style.cpp
index c068702..a43fa7d 100644
--- a/fxjs/cjs_style.cpp
+++ b/fxjs/cjs_style.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
{"st", JSConstSpec::String, 0, "star"},
{"sq", JSConstSpec::String, 0, "square"}};
-int CJS_Style::ObjDefnID = -1;
+uint32_t CJS_Style::ObjDefnID = 0;
// static
void CJS_Style::DefineJSObjects(CFXJS_Engine* pEngine) {
diff --git a/fxjs/cjs_style.h b/fxjs/cjs_style.h
index 6e3ee2f..02449a6 100644
--- a/fxjs/cjs_style.h
+++ b/fxjs/cjs_style.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
CJS_Style() = delete;
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const JSConstSpec ConstSpecs[];
};
diff --git a/fxjs/cjs_timerobj.cpp b/fxjs/cjs_timerobj.cpp
index 5fa1ac3..9dc8cfa 100644
--- a/fxjs/cjs_timerobj.cpp
+++ b/fxjs/cjs_timerobj.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,10 +9,10 @@
#include "fxjs/global_timer.h"
#include "fxjs/js_define.h"
-int CJS_TimerObj::ObjDefnID = -1;
+uint32_t CJS_TimerObj::ObjDefnID = 0;
// static
-int CJS_TimerObj::GetObjDefnID() {
+uint32_t CJS_TimerObj::GetObjDefnID() {
return ObjDefnID;
}
diff --git a/fxjs/cjs_timerobj.h b/fxjs/cjs_timerobj.h
index 69effa6..a82ecd1 100644
--- a/fxjs/cjs_timerobj.h
+++ b/fxjs/cjs_timerobj.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -13,7 +13,7 @@
class CJS_TimerObj final : public CJS_Object {
public:
- static int GetObjDefnID();
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
CJS_TimerObj(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
@@ -23,7 +23,7 @@
int GetTimerID() const { return m_nTimerID; }
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
int m_nTimerID = 0; // Weak reference to GlobalTimer through global map.
};
diff --git a/fxjs/cjs_util.cpp b/fxjs/cjs_util.cpp
index 1f95c31..812e12b 100644
--- a/fxjs/cjs_util.cpp
+++ b/fxjs/cjs_util.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,25 +6,27 @@
#include "fxjs/cjs_util.h"
+#include <math.h>
#include <time.h>
#include <algorithm>
-#include <cmath>
-#include <cwctype>
+#include <string>
#include <vector>
#include "build/build_config.h"
#include "core/fxcrt/fx_extension.h"
#include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
#include "fxjs/cjs_object.h"
#include "fxjs/cjs_publicmethods.h"
#include "fxjs/cjs_runtime.h"
#include "fxjs/fx_date_helpers.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_define.h"
#include "fxjs/js_resources.h"
+#include "third_party/base/check_op.h"
+#include "v8/include/v8-date.h"
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
#include <ctype.h>
#endif
@@ -40,8 +42,8 @@
// Map PDF-style directives lacking direct wcsftime directives to
// the value with which they will be replaced.
struct TbConvertAdditional {
- const wchar_t* lpszJSMark;
- int iValue;
+ wchar_t js_mark;
+ int value;
};
const TbConvert TbConvertTable[] = {
@@ -49,7 +51,7 @@
{L"ddd", L"%a"}, {L"dd", L"%d"}, {L"yyyy", L"%Y"}, {L"yy", L"%y"},
{L"HH", L"%H"}, {L"hh", L"%I"}, {L"MM", L"%M"}, {L"ss", L"%S"},
{L"TT", L"%p"},
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
{L"tt", L"%p"}, {L"h", L"%#I"},
#else
{L"tt", L"%P"}, {L"h", L"%l"},
@@ -75,11 +77,11 @@
{"scand", scand_static},
{"byteToChar", byteToChar_static}};
-int CJS_Util::ObjDefnID = -1;
+uint32_t CJS_Util::ObjDefnID = 0;
const char CJS_Util::kName[] = "util";
// static
-int CJS_Util::GetObjDefnID() {
+uint32_t CJS_Util::GetObjDefnID() {
return ObjDefnID;
}
@@ -109,7 +111,8 @@
{
size_t offset = 0;
while (true) {
- Optional<size_t> offset_end = unsafe_fmt_string.Find(L"%", offset + 1);
+ absl::optional<size_t> offset_end =
+ unsafe_fmt_string.Find(L"%", offset + 1);
if (!offset_end.has_value()) {
unsafe_conversion_specifiers.push_back(
unsafe_fmt_string.Last(unsafe_fmt_string.GetLength() - offset));
@@ -132,14 +135,14 @@
WideString segment;
switch (ParseDataType(&fmt)) {
- case UTIL_INT:
+ case DataType::kInt:
segment = WideString::Format(fmt.c_str(), pRuntime->ToInt32(params[i]));
break;
- case UTIL_DOUBLE:
+ case DataType::kDouble:
segment =
WideString::Format(fmt.c_str(), pRuntime->ToDouble(params[i]));
break;
- case UTIL_STRING:
+ case DataType::kString:
segment = WideString::Format(fmt.c_str(),
pRuntime->ToWideString(params[i]).c_str());
break;
@@ -163,11 +166,11 @@
if (iSize < 2)
return CJS_Result::Failure(JSMessage::kParamError);
- if (params[1].IsEmpty() || !params[1]->IsDate())
+ if (!fxv8::IsDate(params[1]))
return CJS_Result::Failure(JSMessage::kSecondParamNotDateError);
v8::Local<v8::Date> v8_date = params[1].As<v8::Date>();
- if (v8_date.IsEmpty() || std::isnan(pRuntime->ToDouble(v8_date)))
+ if (v8_date.IsEmpty() || isnan(pRuntime->ToDouble(v8_date)))
return CJS_Result::Failure(JSMessage::kSecondParamInvalidDateError);
double date = FX_LocalTime(pRuntime->ToDouble(v8_date));
@@ -209,18 +212,19 @@
// Convert PDF-style format specifiers to wcsftime specifiers. Remove any
// pre-existing %-directives before inserting our own.
- std::basic_string<wchar_t> cFormat =
- pRuntime->ToWideString(params[0]).c_str();
+ std::wstring cFormat = pRuntime->ToWideString(params[0]).c_str();
cFormat.erase(std::remove(cFormat.begin(), cFormat.end(), '%'),
cFormat.end());
- for (size_t i = 0; i < FX_ArraySize(TbConvertTable); ++i) {
- int iStart = 0;
- int iEnd;
- while ((iEnd = cFormat.find(TbConvertTable[i].lpszJSMark, iStart)) != -1) {
- cFormat.replace(iEnd, wcslen(TbConvertTable[i].lpszJSMark),
+ for (size_t i = 0; i < std::size(TbConvertTable); ++i) {
+ size_t nFound = 0;
+ while (true) {
+ nFound = cFormat.find(TbConvertTable[i].lpszJSMark, nFound);
+ if (nFound == std::wstring::npos)
+ break;
+
+ cFormat.replace(nFound, wcslen(TbConvertTable[i].lpszJSMark),
TbConvertTable[i].lpszCppMark);
- iStart = iEnd;
}
}
@@ -228,24 +232,24 @@
return CJS_Result::Failure(JSMessage::kValueError);
const TbConvertAdditional cTableAd[] = {
- {L"m", month}, {L"d", day},
- {L"H", hour}, {L"h", hour > 12 ? hour - 12 : hour},
- {L"M", min}, {L"s", sec},
+ {L'm', month}, {L'd', day},
+ {L'H', hour}, {L'h', hour > 12 ? hour - 12 : hour},
+ {L'M', min}, {L's', sec},
};
- for (size_t i = 0; i < FX_ArraySize(cTableAd); ++i) {
- int iStart = 0;
- int iEnd;
- while ((iEnd = cFormat.find(cTableAd[i].lpszJSMark, iStart)) != -1) {
- if (iEnd > 0) {
- if (cFormat[iEnd - 1] == L'%') {
- iStart = iEnd + 1;
- continue;
- }
+ for (size_t i = 0; i < std::size(cTableAd); ++i) {
+ size_t nFound = 0;
+ while (true) {
+ nFound = cFormat.find(cTableAd[i].js_mark, nFound);
+ if (nFound == std::wstring::npos)
+ break;
+
+ if (nFound != 0 && cFormat[nFound - 1] == L'%') {
+ ++nFound;
+ continue;
}
- cFormat.replace(iEnd, wcslen(cTableAd[i].lpszJSMark),
- WideString::Format(L"%d", cTableAd[i].iValue).c_str());
- iStart = iEnd;
+ cFormat.replace(nFound, 1,
+ WideString::FormatInteger(cTableAd[i].value).c_str());
}
}
@@ -373,8 +377,9 @@
WideString sDate = pRuntime->ToWideString(params[1]);
double dDate = FX_GetDateTime();
if (sDate.GetLength() > 0)
- dDate = CJS_PublicMethods::ParseDateUsingFormat(sDate, sFormat, nullptr);
- if (std::isnan(dDate))
+ dDate = CJS_PublicMethods::ParseDateUsingFormat(pRuntime->GetIsolate(),
+ sDate, sFormat, nullptr);
+ if (isnan(dDate))
return CJS_Result::Success(pRuntime->NewUndefined());
return CJS_Result::Success(pRuntime->NewDate(dDate));
@@ -395,80 +400,80 @@
}
// static
-int CJS_Util::ParseDataType(WideString* sFormat) {
- enum State { BEFORE, FLAGS, WIDTH, PRECISION, SPECIFIER, AFTER };
+CJS_Util::DataType CJS_Util::ParseDataType(WideString* sFormat) {
+ enum State { kBefore, kFlags, kWidth, kPrecision, kSpecifier, kAfter };
- int result = -1;
- State state = BEFORE;
+ DataType result = DataType::kInvalid;
+ State state = kBefore;
size_t precision_digits = 0;
size_t i = 0;
while (i < sFormat->GetLength()) {
wchar_t c = (*sFormat)[i];
switch (state) {
- case BEFORE:
+ case kBefore:
if (c == L'%')
- state = FLAGS;
+ state = kFlags;
break;
- case FLAGS:
+ case kFlags:
if (c == L'+' || c == L'-' || c == L'#' || c == L' ') {
// Stay in same state.
} else {
- state = WIDTH;
+ state = kWidth;
continue; // Re-process same character.
}
break;
- case WIDTH:
+ case kWidth:
if (c == L'*')
- return -1;
+ return DataType::kInvalid;
if (FXSYS_IsDecimalDigit(c)) {
// Stay in same state.
} else if (c == L'.') {
- state = PRECISION;
+ state = kPrecision;
} else {
- state = SPECIFIER;
+ state = kSpecifier;
continue; // Re-process same character.
}
break;
- case PRECISION:
+ case kPrecision:
if (c == L'*')
- return -1;
+ return DataType::kInvalid;
if (FXSYS_IsDecimalDigit(c)) {
// Stay in same state.
++precision_digits;
} else {
- state = SPECIFIER;
+ state = kSpecifier;
continue; // Re-process same character.
}
break;
- case SPECIFIER:
+ case kSpecifier:
if (c == L'c' || c == L'C' || c == L'd' || c == L'i' || c == L'o' ||
c == L'u' || c == L'x' || c == L'X') {
- result = UTIL_INT;
+ result = DataType::kInt;
} else if (c == L'e' || c == L'E' || c == L'f' || c == L'g' ||
c == L'G') {
- result = UTIL_DOUBLE;
+ result = DataType::kDouble;
} else if (c == L's' || c == L'S') {
// Map s to S since we always deal internally with wchar_t strings.
// TODO(tsepez): Probably 100% borked. %S is not a standard
// conversion.
sFormat->SetAt(i, L'S');
- result = UTIL_STRING;
+ result = DataType::kString;
} else {
- return -1;
+ return DataType::kInvalid;
}
- state = AFTER;
+ state = kAfter;
break;
- case AFTER:
+ case kAfter:
if (c == L'%')
- return -1;
+ return DataType::kInvalid;
// Stay in same state until string exhausted.
break;
}
++i;
}
// See https://crbug.com/740166
- if (result == UTIL_INT && precision_digits > 2)
- return -1;
+ if (result == DataType::kInt && precision_digits > 2)
+ return DataType::kInvalid;
return result;
}
diff --git a/fxjs/cjs_util.h b/fxjs/cjs_util.h
index 6f55b3a..45e58e0 100644
--- a/fxjs/cjs_util.h
+++ b/fxjs/cjs_util.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,15 +12,18 @@
#include "core/fxcrt/widestring.h"
#include "fxjs/cjs_object.h"
#include "fxjs/js_define.h"
-
-// Return values for ParseDataType() below.
-#define UTIL_INT 0
-#define UTIL_DOUBLE 1
-#define UTIL_STRING 2
+#include "v8/include/v8-forward.h"
class CJS_Util final : public CJS_Object {
public:
- static int GetObjDefnID();
+ enum class DataType {
+ kInvalid = -1,
+ kInt = 0,
+ kDouble = 1,
+ kString = 2,
+ };
+
+ static uint32_t GetObjDefnID();
static void DefineJSObjects(CFXJS_Engine* pEngine);
CJS_Util(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
@@ -33,7 +36,7 @@
// byte-by-byte.
//
// Exposed for testing.
- static int ParseDataType(WideString* sFormat);
+ static DataType ParseDataType(WideString* sFormat);
// Exposed for testing.
static WideString StringPrintx(const WideString& cFormat,
@@ -46,7 +49,7 @@
JS_STATIC_METHOD(byteToChar, CJS_Util)
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const char kName[];
static const JSMethodSpec MethodSpecs[];
diff --git a/fxjs/cjs_util_unittest.cpp b/fxjs/cjs_util_unittest.cpp
index d405746..b925268 100644
--- a/fxjs/cjs_util_unittest.cpp
+++ b/fxjs/cjs_util_unittest.cpp
@@ -1,110 +1,112 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fxjs/cjs_util.h"
+#include <iterator>
+
#include "testing/gtest/include/gtest/gtest.h"
TEST(CJS_Util, ParseDataType) {
struct ParseDataTypeCase {
const wchar_t* const input_string;
- const int expected;
+ const CJS_Util::DataType expected;
};
// Commented out tests follow the spec but are not passing.
const ParseDataTypeCase cases[] = {
// Not conversions
- {L"", -1},
- {L"d", -1},
+ {L"", CJS_Util::DataType::kInvalid},
+ {L"d", CJS_Util::DataType::kInvalid},
// Simple cases
- {L"%d", UTIL_INT},
- {L"%x", UTIL_INT},
- {L"%f", UTIL_DOUBLE},
- {L"%s", UTIL_STRING},
+ {L"%d", CJS_Util::DataType::kInt},
+ {L"%x", CJS_Util::DataType::kInt},
+ {L"%f", CJS_Util::DataType::kDouble},
+ {L"%s", CJS_Util::DataType::kString},
// nDecSep Not implemented
- // {L"%,0d", UTIL_INT},
- // {L"%,1d", UTIL_INT},
- // {L"%,2d", UTIL_INT},
- // {L"%,3d", UTIL_INT},
+ // {L"%,0d", CJS_Util::DataType::kInt},
+ // {L"%,1d", CJS_Util::DataType::kInt},
+ // {L"%,2d", CJS_Util::DataType::kInt},
+ // {L"%,3d", CJS_Util::DataType::kInt},
// {L"%,4d", -1},
// {L"%,d", -1},
// cFlags("+ 0#"") are only valid for numeric conversions.
- {L"%+d", UTIL_INT},
- {L"%+x", UTIL_INT},
- {L"%+f", UTIL_DOUBLE},
+ {L"%+d", CJS_Util::DataType::kInt},
+ {L"%+x", CJS_Util::DataType::kInt},
+ {L"%+f", CJS_Util::DataType::kDouble},
// {L"%+s", -1},
- {L"% d", UTIL_INT},
- {L"% x", UTIL_INT},
- {L"% f", UTIL_DOUBLE},
+ {L"% d", CJS_Util::DataType::kInt},
+ {L"% x", CJS_Util::DataType::kInt},
+ {L"% f", CJS_Util::DataType::kDouble},
// {L"% s", -1},
- {L"%0d", UTIL_INT},
- {L"%0x", UTIL_INT},
- {L"%0f", UTIL_DOUBLE},
+ {L"%0d", CJS_Util::DataType::kInt},
+ {L"%0x", CJS_Util::DataType::kInt},
+ {L"%0f", CJS_Util::DataType::kDouble},
// {L"%0s", -1},
- {L"%#d", UTIL_INT},
- {L"%#x", UTIL_INT},
- {L"%#f", UTIL_DOUBLE},
+ {L"%#d", CJS_Util::DataType::kInt},
+ {L"%#x", CJS_Util::DataType::kInt},
+ {L"%#f", CJS_Util::DataType::kDouble},
// {L"%#s", -1},
// nWidth should work. for all conversions, can be combined with cFlags=0
// for numbers.
- {L"%5d", UTIL_INT},
- {L"%05d", UTIL_INT},
- {L"%5x", UTIL_INT},
- {L"%05x", UTIL_INT},
- {L"%5f", UTIL_DOUBLE},
- {L"%05f", UTIL_DOUBLE},
- {L"%5s", UTIL_STRING},
+ {L"%5d", CJS_Util::DataType::kInt},
+ {L"%05d", CJS_Util::DataType::kInt},
+ {L"%5x", CJS_Util::DataType::kInt},
+ {L"%05x", CJS_Util::DataType::kInt},
+ {L"%5f", CJS_Util::DataType::kDouble},
+ {L"%05f", CJS_Util::DataType::kDouble},
+ {L"%5s", CJS_Util::DataType::kString},
// {L"%05s", -1},
// nPrecision should only work for float
// {L"%.5d", -1},
// {L"%.5x", -1},
- {L"%.5f", UTIL_DOUBLE},
+ {L"%.5f", CJS_Util::DataType::kDouble},
// {L"%.5s", -1},
// {L"%.14d", -1},
// {L"%.14x", -1},
- {L"%.14f", UTIL_DOUBLE},
+ {L"%.14f", CJS_Util::DataType::kDouble},
// {L"%.14s", -1},
// {L"%.f", -1},
// See https://crbug.com/740166
// nPrecision too large (> 260) causes crashes in Windows.
// Avoid this by limiting to two digits
- {L"%.1d", UTIL_INT},
- {L"%.10d", UTIL_INT},
- {L"%.100d", -1},
+ {L"%.1d", CJS_Util::DataType::kInt},
+ {L"%.10d", CJS_Util::DataType::kInt},
+ {L"%.100d", CJS_Util::DataType::kInvalid},
// Unexpected characters
- {L"%ad", -1},
- {L"%bx", -1},
- // {L"%cf", -1},
- // {L"%es", -1},
- // {L"%gd", -1},
- {L"%hx", -1},
- // {L"%if", -1},
- {L"%js", -1},
- {L"%@d", -1},
- {L"%~x", -1},
- {L"%[f", -1},
- {L"%\0s", -1},
- {L"%\nd", -1},
- {L"%\rx", -1},
- // {L"%%f", -1},
- // {L"% s", -1},
+ {L"%ad", CJS_Util::DataType::kInvalid},
+ {L"%bx", CJS_Util::DataType::kInvalid},
+ // {L"%cf", CJS_Util::DataType::kInvalid},
+ // {L"%es", CJS_Util::DataType::kInvalid},
+ // {L"%gd", CJS_Util::DataType::kInvalid},
+ {L"%hx", CJS_Util::DataType::kInvalid},
+ // {L"%if", CJS_Util::DataType::kInvalid},
+ {L"%js", CJS_Util::DataType::kInvalid},
+ {L"%@d", CJS_Util::DataType::kInvalid},
+ {L"%~x", CJS_Util::DataType::kInvalid},
+ {L"%[f", CJS_Util::DataType::kInvalid},
+ {L"%\0s", CJS_Util::DataType::kInvalid},
+ {L"%\nd", CJS_Util::DataType::kInvalid},
+ {L"%\rx", CJS_Util::DataType::kInvalid},
+ // {L"%%f", CJS_Util::DataType::kInvalid},
+ // {L"% s", CJS_Util::DataType::kInvalid},
// Combine multiple valid components
- {L"%+6d", UTIL_INT},
- {L"% 7x", UTIL_INT},
- {L"%#9.3f", UTIL_DOUBLE},
- {L"%10s", UTIL_STRING},
+ {L"%+6d", CJS_Util::DataType::kInt},
+ {L"% 7x", CJS_Util::DataType::kInt},
+ {L"%#9.3f", CJS_Util::DataType::kDouble},
+ {L"%10s", CJS_Util::DataType::kString},
};
- for (size_t i = 0; i < FX_ArraySize(cases); i++) {
+ for (size_t i = 0; i < std::size(cases); i++) {
WideString input(cases[i].input_string);
EXPECT_EQ(cases[i].expected, CJS_Util::ParseDataType(&input))
<< cases[i].input_string;
diff --git a/fxjs/cjs_zoomtype.cpp b/fxjs/cjs_zoomtype.cpp
index cdaa2d5..b978468 100644
--- a/fxjs/cjs_zoomtype.cpp
+++ b/fxjs/cjs_zoomtype.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,7 +15,7 @@
{"pref", JSConstSpec::String, 0, "Preferred"},
{"refW", JSConstSpec::String, 0, "ReflowWidth"}};
-int CJS_Zoomtype::ObjDefnID = -1;
+uint32_t CJS_Zoomtype::ObjDefnID = 0;
// static
void CJS_Zoomtype::DefineJSObjects(CFXJS_Engine* pEngine) {
diff --git a/fxjs/cjs_zoomtype.h b/fxjs/cjs_zoomtype.h
index de268cd..2efd49a 100644
--- a/fxjs/cjs_zoomtype.h
+++ b/fxjs/cjs_zoomtype.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
CJS_Zoomtype() = delete;
private:
- static int ObjDefnID;
+ static uint32_t ObjDefnID;
static const JSConstSpec ConstSpecs[];
};
diff --git a/fxjs/fx_date_helpers.cpp b/fxjs/fx_date_helpers.cpp
index 5256fb1..3d7d1f3 100644
--- a/fxjs/fx_date_helpers.cpp
+++ b/fxjs/fx_date_helpers.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,9 +6,11 @@
#include "fxjs/fx_date_helpers.h"
+#include <math.h>
#include <time.h>
+#include <wctype.h>
-#include <cmath>
+#include <iterator>
#include "build/build_config.h"
#include "core/fxcrt/fx_extension.h"
@@ -36,7 +38,7 @@
time_t t = 0;
FXSYS_time(&t);
FXSYS_localtime(&t);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
// In gcc 'timezone' is a global variable declared in time.h. In VC++, that
// variable was removed in VC++ 2015, with _get_timezone replacing it.
long timezone = 0;
@@ -113,9 +115,9 @@
// Check for February onwards.
static constexpr int kCumulativeDaysInMonths[] = {
59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
- for (size_t i = 0; i < FX_ArraySize(kCumulativeDaysInMonths); ++i) {
+ for (size_t i = 0; i < std::size(kCumulativeDaysInMonths); ++i) {
if (day < kCumulativeDaysInMonths[i])
- return i + 1;
+ return static_cast<int>(i) + 1;
}
return -1;
@@ -159,7 +161,7 @@
size_t FindSubWordLength(const WideString& str, size_t nStart) {
pdfium::span<const wchar_t> data = str.span();
size_t i = nStart;
- while (i < data.size() && std::iswalnum(data[i]))
+ while (i < data.size() && iswalnum(data[i]))
++i;
return i - nStart;
}
@@ -247,7 +249,7 @@
double mn = Mod(m, 12);
double t = TimeFromYearMonth(static_cast<int>(ym), static_cast<int>(mn));
if (YearFromTime(t) != ym || MonthFromTime(t) != mn || DateFromTime(t) != 1)
- return std::nan("");
+ return nan("");
return Day(t) + dt - 1;
}
@@ -261,8 +263,8 @@
}
double FX_MakeDate(double day, double time) {
- if (!std::isfinite(day) || !std::isfinite(time))
- return std::nan("");
+ if (!isfinite(day) || !isfinite(time))
+ return nan("");
return day * 86400000 + time;
}
@@ -433,9 +435,9 @@
nSkip = FindSubWordLength(value, j);
if (nSkip == KMonthAbbreviationLength) {
WideString sMonth = value.Substr(j, KMonthAbbreviationLength);
- for (size_t m = 0; m < FX_ArraySize(kMonths); ++m) {
+ for (size_t m = 0; m < std::size(kMonths); ++m) {
if (sMonth.CompareNoCase(kMonths[m]) == 0) {
- nMonth = m + 1;
+ nMonth = static_cast<int>(m) + 1;
i += 3;
j += nSkip;
bFind = true;
@@ -470,11 +472,11 @@
if (nSkip <= kLongestFullMonthLength) {
WideString sMonth = value.Substr(j, nSkip);
sMonth.MakeLower();
- for (size_t m = 0; m < FX_ArraySize(kFullMonths); ++m) {
+ for (size_t m = 0; m < std::size(kFullMonths); ++m) {
WideString sFullMonths = WideString(kFullMonths[m]);
sFullMonths.MakeLower();
- if (sFullMonths.Contains(sMonth.c_str())) {
- nMonth = m + 1;
+ if (sFullMonths.Contains(sMonth.AsStringView())) {
+ nMonth = static_cast<int>(m) + 1;
i += 4;
j += nSkip;
bFind = true;
@@ -482,7 +484,6 @@
}
}
}
-
if (!bFind) {
nMonth = FX_ParseStringInteger(value, j, &nSkip, 4);
i += 4;
@@ -541,7 +542,7 @@
dt = FX_MakeDate(FX_MakeDay(nYear, nMonth - 1, nDay),
FX_MakeTime(nHour, nMin, nSec, 0));
- if (std::isnan(dt))
+ if (isnan(dt))
return ConversionStatus::kBadDate;
*result = dt;
diff --git a/fxjs/fx_date_helpers.h b/fxjs/fx_date_helpers.h
index 3657694..6f6f403 100644
--- a/fxjs/fx_date_helpers.h
+++ b/fxjs/fx_date_helpers.h
@@ -1,4 +1,4 @@
-// Copyright 2018 PDFium Authors. All rights reserved.
+// Copyright 2018 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,7 +9,7 @@
#include <stddef.h>
-#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/widestring.h"
namespace fxjs {
diff --git a/fxjs/fx_date_helpers_unittest.cpp b/fxjs/fx_date_helpers_unittest.cpp
index fb756b9..cc95719 100644
--- a/fxjs/fx_date_helpers_unittest.cpp
+++ b/fxjs/fx_date_helpers_unittest.cpp
@@ -1,9 +1,10 @@
-// Copyright 2019 PDFium Authors. All rights reserved.
+// Copyright 2019 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fxjs/fx_date_helpers.h"
+#include "core/fxcrt/fake_time_test.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -12,6 +13,8 @@
} // namespace
+using fxjs::ConversionStatus;
+
TEST(FX_DateHelper, GetYearFromTime) {
static constexpr struct {
double time_ms;
@@ -106,3 +109,47 @@
<< test.time_ms;
}
}
+
+using FXDateHelperFakeTimeTest = FakeTimeTest;
+
+TEST_F(FXDateHelperFakeTimeTest, ParseDateUsingFormatWithEmptyParams) {
+ double result = 0.0;
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"", L"", &result));
+ EXPECT_DOUBLE_EQ(1'587'654'321'000, result);
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"value", L"", &result));
+ EXPECT_DOUBLE_EQ(1'587'654'321'000, result);
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"", L"format", &result));
+ EXPECT_DOUBLE_EQ(1'587'654'321'000, result);
+}
+
+TEST_F(FXDateHelperFakeTimeTest, ParseDateUsingFormatForValidMonthDay) {
+ double result = 0.0;
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"01/02/2000", L"mm/dd/yyyy", &result));
+ EXPECT_DOUBLE_EQ(946'825'521'000, result);
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"1/2/2000", L"m/d/yyyy", &result));
+ EXPECT_DOUBLE_EQ(946'825'521'000, result);
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"1-2-2000", L"m-d-yyyy", &result));
+ EXPECT_DOUBLE_EQ(946'825'521'000, result);
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"2-1-2000", L"d-m-yyyy", &result));
+ EXPECT_DOUBLE_EQ(946'825'521'000, result);
+
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"11/12/2000", L"mm/dd/yyyy", &result));
+ EXPECT_DOUBLE_EQ(973'955'121'000, result);
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"11/12/2000", L"m/d/yyyy", &result));
+ EXPECT_DOUBLE_EQ(973'955'121'000, result);
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"11-12-2000", L"m-d-yyyy", &result));
+ EXPECT_DOUBLE_EQ(973'955'121'000, result);
+ EXPECT_EQ(ConversionStatus::kSuccess,
+ FX_ParseDateUsingFormat(L"12-11-2000", L"d-m-yyyy", &result));
+ EXPECT_DOUBLE_EQ(973'955'121'000, result);
+}
diff --git a/fxjs/fxv8.cpp b/fxjs/fxv8.cpp
new file mode 100644
index 0000000..bbf1ec6
--- /dev/null
+++ b/fxjs/fxv8.cpp
@@ -0,0 +1,337 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fxjs/fxv8.h"
+
+#include "third_party/base/numerics/safe_conversions.h"
+#include "v8/include/v8-container.h"
+#include "v8/include/v8-date.h"
+#include "v8/include/v8-exception.h"
+#include "v8/include/v8-isolate.h"
+#include "v8/include/v8-primitive.h"
+#include "v8/include/v8-value.h"
+
+namespace fxv8 {
+
+bool IsUndefined(v8::Local<v8::Value> value) {
+ return !value.IsEmpty() && value->IsUndefined();
+}
+
+bool IsNull(v8::Local<v8::Value> value) {
+ return !value.IsEmpty() && value->IsNull();
+}
+
+bool IsBoolean(v8::Local<v8::Value> value) {
+ return !value.IsEmpty() && value->IsBoolean();
+}
+
+bool IsString(v8::Local<v8::Value> value) {
+ return !value.IsEmpty() && value->IsString();
+}
+
+bool IsNumber(v8::Local<v8::Value> value) {
+ return !value.IsEmpty() && value->IsNumber();
+}
+
+bool IsInteger(v8::Local<v8::Value> value) {
+ return !value.IsEmpty() && value->IsInt32();
+}
+
+bool IsObject(v8::Local<v8::Value> value) {
+ return !value.IsEmpty() && value->IsObject();
+}
+
+bool IsArray(v8::Local<v8::Value> value) {
+ return !value.IsEmpty() && value->IsArray();
+}
+
+bool IsDate(v8::Local<v8::Value> value) {
+ return !value.IsEmpty() && value->IsDate();
+}
+
+bool IsFunction(v8::Local<v8::Value> value) {
+ return !value.IsEmpty() && value->IsFunction();
+}
+
+v8::Local<v8::Value> NewNullHelper(v8::Isolate* pIsolate) {
+ return v8::Null(pIsolate);
+}
+
+v8::Local<v8::Value> NewUndefinedHelper(v8::Isolate* pIsolate) {
+ return v8::Undefined(pIsolate);
+}
+
+v8::Local<v8::Number> NewNumberHelper(v8::Isolate* pIsolate, int number) {
+ return v8::Int32::New(pIsolate, number);
+}
+
+v8::Local<v8::Number> NewNumberHelper(v8::Isolate* pIsolate, double number) {
+ return v8::Number::New(pIsolate, number);
+}
+
+v8::Local<v8::Number> NewNumberHelper(v8::Isolate* pIsolate, float number) {
+ return v8::Number::New(pIsolate, number);
+}
+
+v8::Local<v8::Boolean> NewBooleanHelper(v8::Isolate* pIsolate, bool b) {
+ return v8::Boolean::New(pIsolate, b);
+}
+
+v8::Local<v8::String> NewStringHelper(v8::Isolate* pIsolate,
+ ByteStringView str) {
+ return v8::String::NewFromUtf8(
+ pIsolate, str.unterminated_c_str(), v8::NewStringType::kNormal,
+ pdfium::base::checked_cast<int>(str.GetLength()))
+ .ToLocalChecked();
+}
+
+v8::Local<v8::String> NewStringHelper(v8::Isolate* pIsolate,
+ WideStringView str) {
+ return NewStringHelper(pIsolate, FX_UTF8Encode(str).AsStringView());
+}
+
+v8::Local<v8::Array> NewArrayHelper(v8::Isolate* pIsolate) {
+ return v8::Array::New(pIsolate);
+}
+
+v8::Local<v8::Array> NewArrayHelper(v8::Isolate* pIsolate,
+ pdfium::span<v8::Local<v8::Value>> values) {
+ v8::Local<v8::Array> result = NewArrayHelper(pIsolate);
+ for (size_t i = 0; i < values.size(); ++i) {
+ fxv8::ReentrantPutArrayElementHelper(
+ pIsolate, result, i,
+ values[i].IsEmpty() ? fxv8::NewUndefinedHelper(pIsolate) : values[i]);
+ }
+ return result;
+}
+
+v8::Local<v8::Object> NewObjectHelper(v8::Isolate* pIsolate) {
+ return v8::Object::New(pIsolate);
+}
+
+v8::Local<v8::Date> NewDateHelper(v8::Isolate* pIsolate, double d) {
+ return v8::Date::New(pIsolate->GetCurrentContext(), d)
+ .ToLocalChecked()
+ .As<v8::Date>();
+}
+
+WideString ToWideString(v8::Isolate* pIsolate, v8::Local<v8::String> pValue) {
+ v8::String::Utf8Value s(pIsolate, pValue);
+ return WideString::FromUTF8(ByteStringView(*s, s.length()));
+}
+
+ByteString ToByteString(v8::Isolate* pIsolate, v8::Local<v8::String> pValue) {
+ v8::String::Utf8Value s(pIsolate, pValue);
+ return ByteString(*s, s.length());
+}
+
+int ReentrantToInt32Helper(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty())
+ return 0;
+ v8::TryCatch squash_exceptions(pIsolate);
+ return pValue->Int32Value(pIsolate->GetCurrentContext()).FromMaybe(0);
+}
+
+bool ReentrantToBooleanHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty())
+ return false;
+ v8::TryCatch squash_exceptions(pIsolate);
+ return pValue->BooleanValue(pIsolate);
+}
+
+float ReentrantToFloatHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ return static_cast<float>(ReentrantToDoubleHelper(pIsolate, pValue));
+}
+
+double ReentrantToDoubleHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty())
+ return 0.0;
+ v8::TryCatch squash_exceptions(pIsolate);
+ return pValue->NumberValue(pIsolate->GetCurrentContext()).FromMaybe(0.0);
+}
+
+WideString ReentrantToWideStringHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty())
+ return WideString();
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::MaybeLocal<v8::String> maybe_string =
+ pValue->ToString(pIsolate->GetCurrentContext());
+ if (maybe_string.IsEmpty())
+ return WideString();
+
+ return ToWideString(pIsolate, maybe_string.ToLocalChecked());
+}
+
+ByteString ReentrantToByteStringHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty())
+ return ByteString();
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::MaybeLocal<v8::String> maybe_string =
+ pValue->ToString(pIsolate->GetCurrentContext());
+ if (maybe_string.IsEmpty())
+ return ByteString();
+
+ return ToByteString(pIsolate, maybe_string.ToLocalChecked());
+}
+
+v8::Local<v8::Object> ReentrantToObjectHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ if (!fxv8::IsObject(pValue))
+ return v8::Local<v8::Object>();
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
+ return pValue->ToObject(context).ToLocalChecked();
+}
+
+v8::Local<v8::Array> ReentrantToArrayHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ if (!fxv8::IsArray(pValue))
+ return v8::Local<v8::Array>();
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
+ return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
+}
+
+v8::Local<v8::Value> ReentrantGetObjectPropertyHelper(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName) {
+ if (pObj.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Local<v8::Value> val;
+ if (!pObj->Get(pIsolate->GetCurrentContext(),
+ NewStringHelper(pIsolate, bsUTF8PropertyName))
+ .ToLocal(&val)) {
+ return v8::Local<v8::Value>();
+ }
+ return val;
+}
+
+std::vector<WideString> ReentrantGetObjectPropertyNamesHelper(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj) {
+ if (pObj.IsEmpty())
+ return std::vector<WideString>();
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Local<v8::Array> val;
+ v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
+ if (!pObj->GetPropertyNames(context).ToLocal(&val))
+ return std::vector<WideString>();
+
+ std::vector<WideString> result;
+ for (uint32_t i = 0; i < val->Length(); ++i) {
+ result.push_back(ReentrantToWideStringHelper(
+ pIsolate, val->Get(context, i).ToLocalChecked()));
+ }
+ return result;
+}
+
+bool ReentrantHasObjectOwnPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName) {
+ if (pObj.IsEmpty())
+ return false;
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Local<v8::Context> pContext = pIsolate->GetCurrentContext();
+ v8::Local<v8::String> hKey =
+ fxv8::NewStringHelper(pIsolate, bsUTF8PropertyName);
+ return pObj->HasRealNamedProperty(pContext, hKey).FromJust();
+}
+
+bool ReentrantSetObjectOwnPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName,
+ v8::Local<v8::Value> pValue) {
+ if (pObj.IsEmpty() || pValue.IsEmpty())
+ return false;
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Local<v8::String> name = NewStringHelper(pIsolate, bsUTF8PropertyName);
+ return pObj->DefineOwnProperty(pIsolate->GetCurrentContext(), name, pValue)
+ .FromMaybe(false);
+}
+
+bool ReentrantPutObjectPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName,
+ v8::Local<v8::Value> pPut) {
+ if (pObj.IsEmpty() || pPut.IsEmpty())
+ return false;
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Local<v8::String> name = NewStringHelper(pIsolate, bsUTF8PropertyName);
+ v8::Maybe<bool> result = pObj->Set(pIsolate->GetCurrentContext(), name, pPut);
+ return result.IsJust() && result.FromJust();
+}
+
+void ReentrantDeleteObjectPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName) {
+ v8::TryCatch squash_exceptions(pIsolate);
+ pObj->Delete(pIsolate->GetCurrentContext(),
+ fxv8::NewStringHelper(pIsolate, bsUTF8PropertyName))
+ .FromJust();
+}
+
+bool ReentrantPutArrayElementHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Array> pArray,
+ size_t index,
+ v8::Local<v8::Value> pValue) {
+ if (pArray.IsEmpty())
+ return false;
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Maybe<bool> result =
+ pArray->Set(pIsolate->GetCurrentContext(),
+ pdfium::base::checked_cast<uint32_t>(index), pValue);
+ return result.IsJust() && result.FromJust();
+}
+
+v8::Local<v8::Value> ReentrantGetArrayElementHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Array> pArray,
+ size_t index) {
+ if (pArray.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Local<v8::Value> val;
+ if (!pArray
+ ->Get(pIsolate->GetCurrentContext(),
+ pdfium::base::checked_cast<uint32_t>(index))
+ .ToLocal(&val)) {
+ return v8::Local<v8::Value>();
+ }
+ return val;
+}
+
+size_t GetArrayLengthHelper(v8::Local<v8::Array> pArray) {
+ if (pArray.IsEmpty())
+ return 0;
+ return pArray->Length();
+}
+
+void ThrowExceptionHelper(v8::Isolate* pIsolate, ByteStringView str) {
+ pIsolate->ThrowException(NewStringHelper(pIsolate, str));
+}
+
+void ThrowExceptionHelper(v8::Isolate* pIsolate, WideStringView str) {
+ pIsolate->ThrowException(NewStringHelper(pIsolate, str));
+}
+
+} // namespace fxv8
diff --git a/fxjs/fxv8.h b/fxjs/fxv8.h
new file mode 100644
index 0000000..5ebd7f5
--- /dev/null
+++ b/fxjs/fxv8.h
@@ -0,0 +1,110 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJS_FXV8_H_
+#define FXJS_FXV8_H_
+
+#include <stddef.h>
+
+#include <vector>
+
+#include "core/fxcrt/fx_string.h"
+#include "third_party/base/span.h"
+#include "v8/include/v8-forward.h"
+
+// The fxv8 functions soften up the interface to the V8 API. In particular,
+// PDFium uses size_t for sizes and indices, but V8 mostly uses ints, so
+// these routines perform checked conversions.
+
+namespace fxv8 {
+
+// These first check for empty locals.
+bool IsUndefined(v8::Local<v8::Value> value);
+bool IsNull(v8::Local<v8::Value> value);
+bool IsBoolean(v8::Local<v8::Value> value);
+bool IsString(v8::Local<v8::Value> value);
+bool IsNumber(v8::Local<v8::Value> value);
+bool IsInteger(v8::Local<v8::Value> value);
+bool IsObject(v8::Local<v8::Value> value);
+bool IsArray(v8::Local<v8::Value> value);
+bool IsDate(v8::Local<v8::Value> value);
+bool IsFunction(v8::Local<v8::Value> value);
+
+v8::Local<v8::Value> NewNullHelper(v8::Isolate* pIsolate);
+v8::Local<v8::Value> NewUndefinedHelper(v8::Isolate* pIsolate);
+v8::Local<v8::Number> NewNumberHelper(v8::Isolate* pIsolate, int number);
+v8::Local<v8::Number> NewNumberHelper(v8::Isolate* pIsolate, double number);
+v8::Local<v8::Number> NewNumberHelper(v8::Isolate* pIsolate, float number);
+v8::Local<v8::Boolean> NewBooleanHelper(v8::Isolate* pIsolate, bool b);
+v8::Local<v8::String> NewStringHelper(v8::Isolate* pIsolate,
+ ByteStringView str);
+v8::Local<v8::String> NewStringHelper(v8::Isolate* pIsolate,
+ WideStringView str);
+v8::Local<v8::Array> NewArrayHelper(v8::Isolate* pIsolate);
+v8::Local<v8::Array> NewArrayHelper(v8::Isolate* pIsolate,
+ pdfium::span<v8::Local<v8::Value>> values);
+v8::Local<v8::Object> NewObjectHelper(v8::Isolate* pIsolate);
+v8::Local<v8::Date> NewDateHelper(v8::Isolate* pIsolate, double d);
+
+// Conversion to PDFium type without re-entry from known v8 type.
+WideString ToWideString(v8::Isolate* pIsolate, v8::Local<v8::String> pValue);
+ByteString ToByteString(v8::Isolate* pIsolate, v8::Local<v8::String> pValue);
+
+// Conversion to PDFium type with possible re-entry for coercion.
+int32_t ReentrantToInt32Helper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue);
+bool ReentrantToBooleanHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue);
+float ReentrantToFloatHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue);
+double ReentrantToDoubleHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue);
+WideString ReentrantToWideStringHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue);
+ByteString ReentrantToByteStringHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue);
+v8::Local<v8::Object> ReentrantToObjectHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue);
+v8::Local<v8::Array> ReentrantToArrayHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue);
+
+v8::Local<v8::Value> ReentrantGetObjectPropertyHelper(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName);
+std::vector<WideString> ReentrantGetObjectPropertyNamesHelper(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj);
+bool ReentrantHasObjectOwnPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName);
+bool ReentrantSetObjectOwnPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName,
+ v8::Local<v8::Value> pValue);
+bool ReentrantPutObjectPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName,
+ v8::Local<v8::Value> pPut);
+void ReentrantDeleteObjectPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName);
+
+bool ReentrantPutArrayElementHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Array> pArray,
+ size_t index,
+ v8::Local<v8::Value> pValue);
+v8::Local<v8::Value> ReentrantGetArrayElementHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Array> pArray,
+ size_t index);
+size_t GetArrayLengthHelper(v8::Local<v8::Array> pArray);
+
+void ThrowExceptionHelper(v8::Isolate* pIsolate, ByteStringView str);
+void ThrowExceptionHelper(v8::Isolate* pIsolate, WideStringView str);
+
+} // namespace fxv8
+
+#endif // FXJS_FXV8_H_
diff --git a/fxjs/gc/container_trace.h b/fxjs/gc/container_trace.h
new file mode 100644
index 0000000..dfe4a74
--- /dev/null
+++ b/fxjs/gc/container_trace.h
@@ -0,0 +1,66 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FXJS_GC_CONTAINER_TRACE_H_
+#define FXJS_GC_CONTAINER_TRACE_H_
+
+#include <list>
+#include <map>
+#include <set>
+#include <vector>
+
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
+
+namespace fxgc {
+
+template <typename T, typename V = cppgc::Visitor>
+void ContainerTrace(V* visitor, const std::list<cppgc::Member<T>>& container) {
+ for (const auto& item : container)
+ visitor->Trace(item);
+}
+
+template <typename T, typename U, typename V = cppgc::Visitor>
+void ContainerTrace(V* visitor,
+ const std::map<cppgc::Member<T>, U>& container) {
+ for (const auto& item : container) {
+ visitor->Trace(item.first);
+ }
+}
+
+template <typename T, typename U, typename V = cppgc::Visitor>
+void ContainerTrace(V* visitor,
+ const std::map<U, cppgc::Member<T>>& container) {
+ for (const auto& item : container)
+ visitor->Trace(item.second);
+}
+
+template <typename T, typename U, typename V = cppgc::Visitor>
+void ContainerTrace(
+ V* visitor,
+ const std::map<cppgc::Member<U>, cppgc::Member<T>>& container) {
+ for (const auto& item : container) {
+ visitor->Trace(item.first);
+ visitor->Trace(item.second);
+ }
+}
+
+template <typename T, typename V = cppgc::Visitor>
+void ContainerTrace(V* visitor, const std::set<cppgc::Member<T>>& container) {
+ for (const auto& item : container)
+ visitor->Trace(item);
+}
+
+template <typename T, typename V = cppgc::Visitor>
+void ContainerTrace(V* visitor,
+ const std::vector<cppgc::Member<T>>& container) {
+ for (const auto& item : container)
+ visitor->Trace(item);
+}
+
+} // namespace fxgc
+
+using fxgc::ContainerTrace;
+
+#endif // FXJS_GC_CONTAINER_TRACE_H_
diff --git a/fxjs/gc/container_trace_unittest.cpp b/fxjs/gc/container_trace_unittest.cpp
new file mode 100644
index 0000000..9273afe
--- /dev/null
+++ b/fxjs/gc/container_trace_unittest.cpp
@@ -0,0 +1,89 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fxjs/gc/container_trace.h"
+
+#include <stdint.h>
+
+#include <list>
+#include <map>
+#include <set>
+#include <vector>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "v8/include/cppgc/member.h"
+
+namespace {
+
+class Thing : public cppgc::GarbageCollected<Thing> {
+ public:
+ void Trace(cppgc::Visitor* visitor) const {}
+};
+
+class CountingVisitor {
+ public:
+ CountingVisitor() = default;
+
+ void Trace(const void* that) { ++call_count_; }
+ int call_count() const { return call_count_; }
+
+ private:
+ int call_count_ = 0;
+};
+
+} // namespace
+
+TEST(ContainerTrace, ActualListTrace) {
+ std::list<cppgc::Member<Thing>> thing;
+ thing.emplace_back(nullptr);
+
+ CountingVisitor cv;
+ ContainerTrace(&cv, thing);
+ EXPECT_EQ(1, cv.call_count());
+}
+
+TEST(ContainerTrace, ActualMapTraceFirst) {
+ std::map<cppgc::Member<Thing>, int> thing;
+ thing[nullptr] = 42;
+
+ CountingVisitor cv;
+ ContainerTrace(&cv, thing);
+ EXPECT_EQ(1, cv.call_count());
+}
+
+TEST(ContainerTrace, ActualMapTraceSecond) {
+ std::map<int, cppgc::Member<Thing>> thing;
+ thing[42] = nullptr;
+
+ CountingVisitor cv;
+ ContainerTrace(&cv, thing);
+ EXPECT_EQ(1, cv.call_count());
+}
+
+TEST(ContainerTrace, ActualMapTraceBoth) {
+ std::map<cppgc::Member<Thing>, cppgc::Member<Thing>> thing;
+ thing[nullptr] = nullptr;
+
+ CountingVisitor cv;
+ ContainerTrace(&cv, thing);
+ EXPECT_EQ(2, cv.call_count());
+}
+
+TEST(ContainerTrace, ActualSetTrace) {
+ std::set<cppgc::Member<Thing>> thing;
+ thing.insert(nullptr);
+
+ CountingVisitor cv;
+ ContainerTrace(&cv, thing);
+ EXPECT_EQ(1, cv.call_count());
+}
+
+TEST(ContainerTrace, ActualVectorTrace) {
+ std::vector<cppgc::Member<Thing>> thing;
+ thing.emplace_back(nullptr);
+
+ CountingVisitor cv;
+ ContainerTrace(&cv, thing);
+ EXPECT_EQ(1, cv.call_count());
+}
diff --git a/fxjs/gc/gced_tree_node.h b/fxjs/gc/gced_tree_node.h
new file mode 100644
index 0000000..fed5e73
--- /dev/null
+++ b/fxjs/gc/gced_tree_node.h
@@ -0,0 +1,47 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FXJS_GC_GCED_TREE_NODE_H_
+#define FXJS_GC_GCED_TREE_NODE_H_
+
+#include "core/fxcrt/tree_node.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
+
+namespace fxjs {
+
+// For DOM/XML-ish trees, where references outside the tree are Persistent<>.
+template <typename T>
+class GCedTreeNode : public cppgc::GarbageCollected<GCedTreeNode<T>>,
+ public fxcrt::TreeNodeBase<T> {
+ public:
+ virtual void Trace(cppgc::Visitor* visitor) const {
+ visitor->Trace(m_pParent);
+ visitor->Trace(m_pFirstChild);
+ visitor->Trace(m_pLastChild);
+ visitor->Trace(m_pNextSibling);
+ visitor->Trace(m_pPrevSibling);
+ }
+
+ protected:
+ GCedTreeNode() = default;
+ GCedTreeNode(const GCedTreeNode& that) = delete;
+ GCedTreeNode& operator=(const GCedTreeNode& that) = delete;
+
+ private:
+ friend class fxcrt::TreeNodeBase<T>;
+
+ cppgc::Member<T> m_pParent;
+ cppgc::Member<T> m_pFirstChild;
+ cppgc::Member<T> m_pLastChild;
+ cppgc::Member<T> m_pNextSibling;
+ cppgc::Member<T> m_pPrevSibling;
+};
+
+} // namespace fxjs
+
+using fxjs::GCedTreeNode;
+
+#endif // FXJS_GC_GCED_TREE_NODE_H_
diff --git a/fxjs/gc/gced_tree_node_mixin.h b/fxjs/gc/gced_tree_node_mixin.h
new file mode 100644
index 0000000..2f160e0
--- /dev/null
+++ b/fxjs/gc/gced_tree_node_mixin.h
@@ -0,0 +1,48 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FXJS_GC_GCED_TREE_NODE_MIXIN_H_
+#define FXJS_GC_GCED_TREE_NODE_MIXIN_H_
+
+#include "core/fxcrt/tree_node.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/visitor.h"
+
+namespace fxjs {
+
+// For DOM/XML-ish trees, where references outside the tree are Persistent<>,
+// usable by classes that are already garbage collected themselves.
+template <typename T>
+class GCedTreeNodeMixin : public cppgc::GarbageCollectedMixin,
+ public fxcrt::TreeNodeBase<T> {
+ public:
+ virtual void Trace(cppgc::Visitor* visitor) const {
+ visitor->Trace(m_pParent);
+ visitor->Trace(m_pFirstChild);
+ visitor->Trace(m_pLastChild);
+ visitor->Trace(m_pNextSibling);
+ visitor->Trace(m_pPrevSibling);
+ }
+
+ protected:
+ GCedTreeNodeMixin() = default;
+ GCedTreeNodeMixin(const GCedTreeNodeMixin& that) = delete;
+ GCedTreeNodeMixin& operator=(const GCedTreeNodeMixin& that) = delete;
+
+ private:
+ friend class fxcrt::TreeNodeBase<T>;
+
+ cppgc::Member<T> m_pParent;
+ cppgc::Member<T> m_pFirstChild;
+ cppgc::Member<T> m_pLastChild;
+ cppgc::Member<T> m_pNextSibling;
+ cppgc::Member<T> m_pPrevSibling;
+};
+
+} // namespace fxjs
+
+using fxjs::GCedTreeNodeMixin;
+
+#endif // FXJS_GC_GCED_TREE_NODE_MIXIN_H_
diff --git a/fxjs/gc/gced_tree_node_mixin_unittest.cpp b/fxjs/gc/gced_tree_node_mixin_unittest.cpp
new file mode 100644
index 0000000..2cd098e
--- /dev/null
+++ b/fxjs/gc/gced_tree_node_mixin_unittest.cpp
@@ -0,0 +1,149 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fxjs/gc/gced_tree_node_mixin.h"
+
+#include <map>
+
+#include "core/fxcrt/observed_ptr.h"
+#include "fxjs/gc/heap.h"
+#include "testing/fxgc_unittest.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/v8_test_environment.h"
+#include "v8/include/cppgc/allocation.h"
+#include "v8/include/cppgc/persistent.h"
+
+namespace {
+
+class ObservableGCedTreeNodeMixinForTest
+ : public cppgc::GarbageCollected<ObservableGCedTreeNodeMixinForTest>,
+ public GCedTreeNodeMixin<ObservableGCedTreeNodeMixinForTest>,
+ public Observable {
+ public:
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
+
+ // GCedTreeNodeMixin:
+ void Trace(cppgc::Visitor* visitor) const override {
+ GCedTreeNodeMixin<ObservableGCedTreeNodeMixinForTest>::Trace(visitor);
+ }
+
+ private:
+ ObservableGCedTreeNodeMixinForTest() = default;
+};
+
+} // namespace
+
+class GCedTreeNodeMixinUnitTest : public FXGCUnitTest {
+ public:
+ GCedTreeNodeMixinUnitTest() = default;
+ ~GCedTreeNodeMixinUnitTest() override = default;
+
+ // FXGCUnitTest:
+ void TearDown() override {
+ root_ = nullptr; // Can't (yet) outlive |FXGCUnitTest::heap_|.
+ FXGCUnitTest::TearDown();
+ }
+
+ ObservableGCedTreeNodeMixinForTest* root() const { return root_; }
+ void CreateRoot() { root_ = CreateNode(); }
+
+ ObservableGCedTreeNodeMixinForTest* CreateNode() {
+ return cppgc::MakeGarbageCollected<ObservableGCedTreeNodeMixinForTest>(
+ heap()->GetAllocationHandle());
+ }
+
+ void AddClutterToFront(ObservableGCedTreeNodeMixinForTest* parent) {
+ for (int i = 0; i < 4; ++i) {
+ parent->AppendFirstChild(
+ cppgc::MakeGarbageCollected<ObservableGCedTreeNodeMixinForTest>(
+ heap()->GetAllocationHandle()));
+ }
+ }
+
+ void AddClutterToBack(ObservableGCedTreeNodeMixinForTest* parent) {
+ for (int i = 0; i < 4; ++i) {
+ parent->AppendLastChild(
+ cppgc::MakeGarbageCollected<ObservableGCedTreeNodeMixinForTest>(
+ heap()->GetAllocationHandle()));
+ }
+ }
+
+ private:
+ cppgc::Persistent<ObservableGCedTreeNodeMixinForTest> root_;
+};
+
+TEST_F(GCedTreeNodeMixinUnitTest, OneRefence) {
+ CreateRoot();
+ ObservedPtr<ObservableGCedTreeNodeMixinForTest> watcher(root());
+ ForceGCAndPump();
+ EXPECT_TRUE(watcher);
+}
+
+TEST_F(GCedTreeNodeMixinUnitTest, NoReferences) {
+ ObservedPtr<ObservableGCedTreeNodeMixinForTest> watcher(CreateNode());
+ ForceGCAndPump();
+ EXPECT_FALSE(watcher);
+}
+
+TEST_F(GCedTreeNodeMixinUnitTest, FirstHasParent) {
+ CreateRoot();
+ ObservedPtr<ObservableGCedTreeNodeMixinForTest> watcher(CreateNode());
+ root()->AppendFirstChild(watcher.Get());
+ ForceGCAndPump();
+ ASSERT_TRUE(root());
+ EXPECT_TRUE(watcher);
+ root()->RemoveChild(watcher.Get());
+ ForceGCAndPump();
+ ASSERT_TRUE(root());
+ EXPECT_FALSE(watcher);
+
+ // Now add some clutter.
+ watcher.Reset(CreateNode());
+ root()->AppendFirstChild(watcher.Get());
+ AddClutterToFront(root());
+ AddClutterToBack(root());
+ ForceGCAndPump();
+ ASSERT_TRUE(root());
+ EXPECT_TRUE(watcher);
+ root()->RemoveChild(watcher.Get());
+ ForceGCAndPump();
+ EXPECT_TRUE(root());
+ EXPECT_FALSE(watcher);
+}
+
+TEST_F(GCedTreeNodeMixinUnitTest, RemoveSelf) {
+ CreateRoot();
+ ObservedPtr<ObservableGCedTreeNodeMixinForTest> watcher(CreateNode());
+ root()->AppendFirstChild(watcher.Get());
+ ForceGCAndPump();
+ EXPECT_TRUE(root());
+ ASSERT_TRUE(watcher);
+ watcher->RemoveSelfIfParented();
+ ForceGCAndPump();
+ EXPECT_TRUE(root());
+ EXPECT_FALSE(watcher);
+}
+
+TEST_F(GCedTreeNodeMixinUnitTest, InsertBeforeAfter) {
+ CreateRoot();
+ AddClutterToFront(root());
+ ObservedPtr<ObservableGCedTreeNodeMixinForTest> watcher(CreateNode());
+ root()->AppendFirstChild(watcher.Get());
+ root()->InsertBefore(root()->GetFirstChild(), root()->GetLastChild());
+ root()->InsertAfter(root()->GetLastChild(), root()->GetFirstChild());
+ ForceGCAndPump();
+ ASSERT_TRUE(root());
+ EXPECT_TRUE(watcher);
+ root()->RemoveChild(watcher.Get());
+ ForceGCAndPump();
+ EXPECT_TRUE(root());
+ EXPECT_FALSE(watcher);
+}
+
+TEST_F(GCedTreeNodeMixinUnitTest, AsMapKey) {
+ std::map<cppgc::Persistent<ObservableGCedTreeNodeMixinForTest>, int> score;
+ ObservableGCedTreeNodeMixinForTest* node = CreateNode();
+ score[node] = 100;
+ EXPECT_EQ(100, score[node]);
+}
diff --git a/fxjs/gc/gced_tree_node_unittest.cpp b/fxjs/gc/gced_tree_node_unittest.cpp
new file mode 100644
index 0000000..a456a31
--- /dev/null
+++ b/fxjs/gc/gced_tree_node_unittest.cpp
@@ -0,0 +1,143 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fxjs/gc/gced_tree_node.h"
+
+#include <map>
+
+#include "core/fxcrt/observed_ptr.h"
+#include "fxjs/gc/heap.h"
+#include "testing/fxgc_unittest.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/v8_test_environment.h"
+#include "v8/include/cppgc/allocation.h"
+#include "v8/include/cppgc/persistent.h"
+
+namespace {
+
+class ObservableGCedTreeNodeForTest
+ : public GCedTreeNode<ObservableGCedTreeNodeForTest>,
+ public Observable {
+ public:
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
+
+ private:
+ ObservableGCedTreeNodeForTest() = default;
+};
+
+} // namespace
+
+class GCedTreeNodeUnitTest : public FXGCUnitTest {
+ public:
+ GCedTreeNodeUnitTest() = default;
+ ~GCedTreeNodeUnitTest() override = default;
+
+ // FXGCUnitTest:
+ void TearDown() override {
+ root_ = nullptr; // Can't (yet) outlive |FXGCUnitTest::heap_|.
+ FXGCUnitTest::TearDown();
+ }
+
+ ObservableGCedTreeNodeForTest* root() const { return root_; }
+ void CreateRoot() { root_ = CreateNode(); }
+
+ ObservableGCedTreeNodeForTest* CreateNode() {
+ return cppgc::MakeGarbageCollected<ObservableGCedTreeNodeForTest>(
+ heap()->GetAllocationHandle());
+ }
+
+ void AddClutterToFront(ObservableGCedTreeNodeForTest* parent) {
+ for (int i = 0; i < 4; ++i) {
+ parent->AppendFirstChild(
+ cppgc::MakeGarbageCollected<ObservableGCedTreeNodeForTest>(
+ heap()->GetAllocationHandle()));
+ }
+ }
+
+ void AddClutterToBack(ObservableGCedTreeNodeForTest* parent) {
+ for (int i = 0; i < 4; ++i) {
+ parent->AppendLastChild(
+ cppgc::MakeGarbageCollected<ObservableGCedTreeNodeForTest>(
+ heap()->GetAllocationHandle()));
+ }
+ }
+
+ private:
+ cppgc::Persistent<ObservableGCedTreeNodeForTest> root_;
+};
+
+TEST_F(GCedTreeNodeUnitTest, OneRefence) {
+ CreateRoot();
+ ObservedPtr<ObservableGCedTreeNodeForTest> watcher(root());
+ ForceGCAndPump();
+ EXPECT_TRUE(watcher);
+}
+
+TEST_F(GCedTreeNodeUnitTest, NoReferences) {
+ ObservedPtr<ObservableGCedTreeNodeForTest> watcher(CreateNode());
+ ForceGCAndPump();
+ EXPECT_FALSE(watcher);
+}
+
+TEST_F(GCedTreeNodeUnitTest, FirstHasParent) {
+ CreateRoot();
+ ObservedPtr<ObservableGCedTreeNodeForTest> watcher(CreateNode());
+ root()->AppendFirstChild(watcher.Get());
+ ForceGCAndPump();
+ ASSERT_TRUE(root());
+ EXPECT_TRUE(watcher);
+ root()->RemoveChild(watcher.Get());
+ ForceGCAndPump();
+ ASSERT_TRUE(root());
+ EXPECT_FALSE(watcher);
+
+ // Now add some clutter.
+ watcher.Reset(CreateNode());
+ root()->AppendFirstChild(watcher.Get());
+ AddClutterToFront(root());
+ AddClutterToBack(root());
+ ForceGCAndPump();
+ ASSERT_TRUE(root());
+ EXPECT_TRUE(watcher);
+ root()->RemoveChild(watcher.Get());
+ ForceGCAndPump();
+ EXPECT_TRUE(root());
+ EXPECT_FALSE(watcher);
+}
+
+TEST_F(GCedTreeNodeUnitTest, RemoveSelf) {
+ CreateRoot();
+ ObservedPtr<ObservableGCedTreeNodeForTest> watcher(CreateNode());
+ root()->AppendFirstChild(watcher.Get());
+ ForceGCAndPump();
+ EXPECT_TRUE(root());
+ ASSERT_TRUE(watcher);
+ watcher->RemoveSelfIfParented();
+ ForceGCAndPump();
+ EXPECT_TRUE(root());
+ EXPECT_FALSE(watcher);
+}
+
+TEST_F(GCedTreeNodeUnitTest, InsertBeforeAfter) {
+ CreateRoot();
+ AddClutterToFront(root());
+ ObservedPtr<ObservableGCedTreeNodeForTest> watcher(CreateNode());
+ root()->AppendFirstChild(watcher.Get());
+ root()->InsertBefore(root()->GetFirstChild(), root()->GetLastChild());
+ root()->InsertAfter(root()->GetLastChild(), root()->GetFirstChild());
+ ForceGCAndPump();
+ ASSERT_TRUE(root());
+ EXPECT_TRUE(watcher);
+ root()->RemoveChild(watcher.Get());
+ ForceGCAndPump();
+ EXPECT_TRUE(root());
+ EXPECT_FALSE(watcher);
+}
+
+TEST_F(GCedTreeNodeUnitTest, AsMapKey) {
+ std::map<cppgc::Persistent<ObservableGCedTreeNodeForTest>, int> score;
+ ObservableGCedTreeNodeForTest* node = CreateNode();
+ score[node] = 100;
+ EXPECT_EQ(100, score[node]);
+}
diff --git a/fxjs/gc/heap.cpp b/fxjs/gc/heap.cpp
new file mode 100644
index 0000000..301018f
--- /dev/null
+++ b/fxjs/gc/heap.cpp
@@ -0,0 +1,98 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fxjs/gc/heap.h"
+
+#include <utility>
+
+#include "core/fxcrt/fx_system.h"
+#include "third_party/base/check.h"
+#include "v8/include/cppgc/heap.h"
+
+namespace {
+
+size_t g_platform_ref_count = 0;
+v8::Platform* g_platform = nullptr;
+v8::Isolate* g_isolate = nullptr;
+
+} // namespace
+
+// Taken from v8/samples/cppgc/cppgc-for-v8-embedders.cc.
+// Adaptper that makes the global v8::Platform compatible with a
+// cppgc::Platform.
+class CFXGC_Platform final : public cppgc::Platform {
+ public:
+ CFXGC_Platform() = default;
+ ~CFXGC_Platform() override = default;
+
+ cppgc::PageAllocator* GetPageAllocator() override {
+ return g_platform->GetPageAllocator();
+ }
+
+ double MonotonicallyIncreasingTime() override {
+ return g_platform->MonotonicallyIncreasingTime();
+ }
+
+ std::shared_ptr<cppgc::TaskRunner> GetForegroundTaskRunner() override {
+ // V8's default platform creates a new task runner when passed the
+ // v8::Isolate pointer the first time. For non-default platforms this will
+ // require getting the appropriate task runner.
+ return g_platform->GetForegroundTaskRunner(g_isolate);
+ }
+
+ std::unique_ptr<cppgc::JobHandle> PostJob(
+ cppgc::TaskPriority priority,
+ std::unique_ptr<cppgc::JobTask> job_task) override {
+ return g_platform->PostJob(priority, std::move(job_task));
+ }
+};
+
+void FXGC_Initialize(v8::Platform* platform, v8::Isolate* isolate) {
+ if (platform) {
+ DCHECK(!g_platform);
+ g_platform = platform;
+ g_isolate = isolate;
+ }
+}
+
+void FXGC_Release() {
+ if (g_platform && g_platform_ref_count == 0) {
+ g_platform = nullptr;
+ g_isolate = nullptr;
+ }
+}
+
+FXGCScopedHeap FXGC_CreateHeap() {
+ // If XFA is included at compile-time, but JS is disabled at run-time,
+ // we may still attempt to build a CPDFXFA_Context which will want a
+ // heap. But we can't make one because JS is disabled.
+ // TODO(tsepez): Stop the context from even being created.
+ if (!g_platform)
+ return nullptr;
+
+ ++g_platform_ref_count;
+ auto heap = cppgc::Heap::Create(
+ std::make_shared<CFXGC_Platform>(),
+ cppgc::Heap::HeapOptions{
+ {},
+ cppgc::Heap::StackSupport::kNoConservativeStackScan,
+ cppgc::Heap::MarkingType::kAtomic,
+ cppgc::Heap::SweepingType::kIncrementalAndConcurrent,
+ {}});
+ return FXGCScopedHeap(heap.release());
+}
+
+void FXGC_ForceGarbageCollection(cppgc::Heap* heap) {
+ heap->ForceGarbageCollectionSlow("FXGC", "ForceGarbageCollection",
+ cppgc::Heap::StackState::kNoHeapPointers);
+}
+
+void FXGCHeapDeleter::operator()(cppgc::Heap* heap) {
+ DCHECK(heap);
+ DCHECK(g_platform_ref_count > 0);
+ --g_platform_ref_count;
+
+ FXGC_ForceGarbageCollection(heap);
+ delete heap;
+}
diff --git a/fxjs/gc/heap.h b/fxjs/gc/heap.h
new file mode 100644
index 0000000..1e2bf61
--- /dev/null
+++ b/fxjs/gc/heap.h
@@ -0,0 +1,36 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FXJS_GC_HEAP_H_
+#define FXJS_GC_HEAP_H_
+
+#include <memory>
+
+#include "v8/include/cppgc/allocation.h"
+
+namespace cppgc {
+class Heap;
+} // namespace cppgc
+
+namespace v8 {
+class Isolate;
+class Platform;
+} // namespace v8
+
+struct FXGCHeapDeleter {
+ void operator()(cppgc::Heap* heap);
+};
+
+using FXGCScopedHeap = std::unique_ptr<cppgc::Heap, FXGCHeapDeleter>;
+
+void FXGC_Initialize(v8::Platform* platform, v8::Isolate* isolate);
+void FXGC_Release();
+FXGCScopedHeap FXGC_CreateHeap();
+void FXGC_ForceGarbageCollection(cppgc::Heap* heap);
+
+#define CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED \
+ template <typename T> \
+ friend class cppgc::MakeGarbageCollectedTrait
+
+#endif // FXJS_GC_HEAP_H_
diff --git a/fxjs/gc/heap_unittest.cpp b/fxjs/gc/heap_unittest.cpp
new file mode 100644
index 0000000..aa90d00
--- /dev/null
+++ b/fxjs/gc/heap_unittest.cpp
@@ -0,0 +1,175 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fxjs/gc/heap.h"
+
+#include <memory>
+#include <set>
+
+#include "testing/fxgc_unittest.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/v8_test_environment.h"
+#include "third_party/base/containers/contains.h"
+#include "v8/include/cppgc/allocation.h"
+#include "v8/include/cppgc/persistent.h"
+
+namespace {
+
+class PseudoCollectible : public cppgc::GarbageCollected<PseudoCollectible> {
+ public:
+ static void ClearCounts() {
+ s_live_.clear();
+ s_dead_.clear();
+ }
+ static size_t LiveCount() { return s_live_.size(); }
+ static size_t DeadCount() { return s_dead_.size(); }
+
+ PseudoCollectible() { s_live_.insert(this); }
+ virtual ~PseudoCollectible() {
+ s_live_.erase(this);
+ s_dead_.insert(this);
+ }
+
+ bool IsLive() const { return pdfium::Contains(s_live_, this); }
+
+ virtual void Trace(cppgc::Visitor* visitor) const {}
+
+ private:
+ static std::set<const PseudoCollectible*> s_live_;
+ static std::set<const PseudoCollectible*> s_dead_;
+};
+
+std::set<const PseudoCollectible*> PseudoCollectible::s_live_;
+std::set<const PseudoCollectible*> PseudoCollectible::s_dead_;
+
+class CollectibleHolder {
+ public:
+ explicit CollectibleHolder(PseudoCollectible* holdee) : holdee_(holdee) {}
+ ~CollectibleHolder() = default;
+
+ PseudoCollectible* holdee() const { return holdee_; }
+
+ private:
+ cppgc::Persistent<PseudoCollectible> holdee_;
+};
+
+class Bloater : public cppgc::GarbageCollected<Bloater> {
+ public:
+ void Trace(cppgc::Visitor* visitor) const {}
+ uint8_t bloat_[65536];
+};
+
+} // namespace
+
+class HeapUnitTest : public FXGCUnitTest {
+ public:
+ HeapUnitTest() = default;
+ ~HeapUnitTest() override = default;
+
+ // FXGCUnitTest:
+ void TearDown() override {
+ PseudoCollectible::ClearCounts();
+ FXGCUnitTest::TearDown();
+ }
+};
+
+TEST_F(HeapUnitTest, SeveralHeaps) {
+ FXGCScopedHeap heap1 = FXGC_CreateHeap();
+ EXPECT_TRUE(heap1);
+
+ FXGCScopedHeap heap2 = FXGC_CreateHeap();
+ EXPECT_TRUE(heap2);
+
+ FXGCScopedHeap heap3 = FXGC_CreateHeap();
+ EXPECT_TRUE(heap3);
+
+ // Test manually destroying the heap.
+ heap3.reset();
+ EXPECT_FALSE(heap3);
+ heap3.reset();
+ EXPECT_FALSE(heap3);
+}
+
+TEST_F(HeapUnitTest, NoReferences) {
+ FXGCScopedHeap heap1 = FXGC_CreateHeap();
+ ASSERT_TRUE(heap1);
+ {
+ auto holder = std::make_unique<CollectibleHolder>(
+ cppgc::MakeGarbageCollected<PseudoCollectible>(
+ heap1->GetAllocationHandle()));
+
+ EXPECT_TRUE(holder->holdee()->IsLive());
+ EXPECT_EQ(1u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(0u, PseudoCollectible::DeadCount());
+ }
+ FXGC_ForceGarbageCollection(heap1.get());
+ EXPECT_EQ(0u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(1u, PseudoCollectible::DeadCount());
+}
+
+TEST_F(HeapUnitTest, HasReferences) {
+ FXGCScopedHeap heap1 = FXGC_CreateHeap();
+ ASSERT_TRUE(heap1);
+ {
+ auto holder = std::make_unique<CollectibleHolder>(
+ cppgc::MakeGarbageCollected<PseudoCollectible>(
+ heap1->GetAllocationHandle()));
+
+ EXPECT_TRUE(holder->holdee()->IsLive());
+ EXPECT_EQ(1u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(0u, PseudoCollectible::DeadCount());
+
+ FXGC_ForceGarbageCollection(heap1.get());
+ EXPECT_TRUE(holder->holdee()->IsLive());
+ EXPECT_EQ(1u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(0u, PseudoCollectible::DeadCount());
+ }
+}
+
+// TODO(tsepez): enable when CPPGC fixes this segv.
+TEST_F(HeapUnitTest, DISABLED_DeleteHeapHasReferences) {
+ FXGCScopedHeap heap1 = FXGC_CreateHeap();
+ ASSERT_TRUE(heap1);
+ {
+ auto holder = std::make_unique<CollectibleHolder>(
+ cppgc::MakeGarbageCollected<PseudoCollectible>(
+ heap1->GetAllocationHandle()));
+
+ EXPECT_TRUE(holder->holdee()->IsLive());
+ EXPECT_EQ(1u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(0u, PseudoCollectible::DeadCount());
+
+ heap1.reset();
+
+ // Maybe someday magically nulled by heap destruction.
+ EXPECT_FALSE(holder->holdee());
+ EXPECT_EQ(1u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(0u, PseudoCollectible::DeadCount());
+ }
+}
+
+TEST_F(HeapUnitTest, DeleteHeapNoReferences) {
+ FXGCScopedHeap heap1 = FXGC_CreateHeap();
+ ASSERT_TRUE(heap1);
+ {
+ auto holder = std::make_unique<CollectibleHolder>(
+ cppgc::MakeGarbageCollected<PseudoCollectible>(
+ heap1->GetAllocationHandle()));
+
+ EXPECT_TRUE(holder->holdee()->IsLive());
+ EXPECT_EQ(1u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(0u, PseudoCollectible::DeadCount());
+ }
+ heap1.reset();
+ EXPECT_EQ(0u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(1u, PseudoCollectible::DeadCount());
+}
+
+TEST_F(HeapUnitTest, Bloat) {
+ ASSERT_TRUE(heap());
+ for (int i = 0; i < 100000; ++i) {
+ cppgc::MakeGarbageCollected<Bloater>(heap()->GetAllocationHandle());
+ Pump(); // Do not force GC, must happen implicitly when space required.
+ }
+}
diff --git a/fxjs/gc/move_unittest.cpp b/fxjs/gc/move_unittest.cpp
new file mode 100644
index 0000000..3d5a809
--- /dev/null
+++ b/fxjs/gc/move_unittest.cpp
@@ -0,0 +1,62 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <utility>
+
+#include "fxjs/gc/heap.h"
+#include "testing/fxgc_unittest.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/persistent.h"
+
+namespace {
+
+class HeapObject : public cppgc::GarbageCollected<HeapObject> {
+ public:
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
+
+ void Trace(cppgc::Visitor* visitor) const {
+ visitor->Trace(frick_);
+ visitor->Trace(frack_);
+ }
+
+ cppgc::Member<HeapObject> frick_;
+ cppgc::Member<HeapObject> frack_;
+
+ private:
+ HeapObject() = default;
+};
+
+class CppObject {
+ public:
+ CppObject() = default;
+
+ cppgc::Persistent<HeapObject> click_;
+ cppgc::Persistent<HeapObject> clack_;
+};
+
+} // namespace
+
+class MoveUnitTest : public FXGCUnitTest {};
+
+TEST_F(MoveUnitTest, Member) {
+ // Moving a Member<> leaves the moved-from object as null.
+ auto* obj =
+ cppgc::MakeGarbageCollected<HeapObject>(heap()->GetAllocationHandle());
+ obj->frick_ = obj;
+ obj->frack_ = std::move(obj->frick_);
+ EXPECT_FALSE(obj->frick_);
+ EXPECT_EQ(obj, obj->frack_);
+}
+
+TEST_F(MoveUnitTest, Persistent) {
+ // Moving a Persistent<> leaves the moved-from object as null.
+ auto* obj =
+ cppgc::MakeGarbageCollected<HeapObject>(heap()->GetAllocationHandle());
+ CppObject outsider;
+ outsider.click_ = obj;
+ outsider.clack_ = std::move(outsider.click_);
+ EXPECT_FALSE(outsider.click_);
+ EXPECT_EQ(obj, outsider.clack_);
+}
diff --git a/fxjs/global_timer.cpp b/fxjs/global_timer.cpp
index b837508..035aff8 100644
--- a/fxjs/global_timer.cpp
+++ b/fxjs/global_timer.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,8 +8,10 @@
#include <map>
-#include "core/fxcrt/timerhandler_iface.h"
+#include "core/fxcrt/cfx_timer.h"
#include "fxjs/cjs_app.h"
+#include "third_party/base/check.h"
+#include "third_party/base/containers/contains.h"
#include "third_party/base/no_destructor.h"
namespace {
@@ -34,8 +36,10 @@
m_swJScript(script),
m_pRuntime(pRuntime),
m_pEmbedApp(pObj) {
- if (HasValidID())
+ if (HasValidID()) {
+ DCHECK(!pdfium::Contains(GetGlobalTimerMap(), m_nTimerID));
GetGlobalTimerMap()[m_nTimerID] = this;
+ }
}
GlobalTimer::~GlobalTimer() {
@@ -45,6 +49,7 @@
if (m_pRuntime && m_pRuntime->GetTimerHandler())
m_pRuntime->GetTimerHandler()->KillTimer(m_nTimerID);
+ DCHECK(pdfium::Contains(GetGlobalTimerMap(), m_nTimerID));
GetGlobalTimerMap().erase(m_nTimerID);
}
@@ -84,5 +89,5 @@
}
bool GlobalTimer::HasValidID() const {
- return m_nTimerID != TimerHandlerIface::kInvalidTimerID;
+ return m_nTimerID != CFX_Timer::HandlerIface::kInvalidTimerID;
}
diff --git a/fxjs/global_timer.h b/fxjs/global_timer.h
index ef6bbb6..106c9e6 100644
--- a/fxjs/global_timer.h
+++ b/fxjs/global_timer.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,6 +7,7 @@
#ifndef FXJS_GLOBAL_TIMER_H_
#define FXJS_GLOBAL_TIMER_H_
+#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/cjs_runtime.h"
class CJS_App;
@@ -44,7 +45,7 @@
const uint32_t m_dwTimeOut;
const WideString m_swJScript;
ObservedPtr<CJS_Runtime> m_pRuntime;
- CJS_App* const m_pEmbedApp;
+ UnownedPtr<CJS_App> const m_pEmbedApp;
};
#endif // FXJS_GLOBAL_TIMER_H_
diff --git a/fxjs/ijs_event_context.h b/fxjs/ijs_event_context.h
index e2c6407..8e9d23c 100644
--- a/fxjs/ijs_event_context.h
+++ b/fxjs/ijs_event_context.h
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,15 +7,11 @@
#ifndef FXJS_IJS_EVENT_CONTEXT_H_
#define FXJS_IJS_EVENT_CONTEXT_H_
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/widestring.h"
#include "fxjs/ijs_runtime.h"
-#include "third_party/base/optional.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
-class CPDF_Bookmark;
class CPDF_FormField;
-class CPDFSDK_Annot;
-class CPDFSDK_FormFillEnvironment;
// Records the details of an event and triggers JS execution for it. There
// can be more than one of these at any given time, as JS callbacks to C++
@@ -24,23 +20,20 @@
public:
virtual ~IJS_EventContext() = default;
- virtual Optional<IJS_Runtime::JS_Error> RunScript(
+ virtual absl::optional<IJS_Runtime::JS_Error> RunScript(
const WideString& script) = 0;
- virtual void OnApp_Init() = 0;
+ virtual void OnDoc_Open(const WideString& strTargetName) = 0;
+ virtual void OnDoc_WillPrint() = 0;
+ virtual void OnDoc_DidPrint() = 0;
+ virtual void OnDoc_WillSave() = 0;
+ virtual void OnDoc_DidSave() = 0;
+ virtual void OnDoc_WillClose() = 0;
- virtual void OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString& strTargetName) = 0;
- virtual void OnDoc_WillPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
- virtual void OnDoc_DidPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
- virtual void OnDoc_WillSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
- virtual void OnDoc_DidSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
- virtual void OnDoc_WillClose(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
-
- virtual void OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
- virtual void OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
- virtual void OnPage_InView(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
- virtual void OnPage_OutView(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
+ virtual void OnPage_Open() = 0;
+ virtual void OnPage_Close() = 0;
+ virtual void OnPage_InView() = 0;
+ virtual void OnPage_OutView() = 0;
virtual void OnField_MouseDown(bool bModifier,
bool bShift,
@@ -88,44 +81,6 @@
WideString* Value,
bool* bRc) = 0;
- virtual void OnScreen_Focus(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) = 0;
- virtual void OnScreen_Blur(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) = 0;
- virtual void OnScreen_Open(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) = 0;
- virtual void OnScreen_Close(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) = 0;
- virtual void OnScreen_MouseDown(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) = 0;
- virtual void OnScreen_MouseUp(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) = 0;
- virtual void OnScreen_MouseEnter(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) = 0;
- virtual void OnScreen_MouseExit(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) = 0;
- virtual void OnScreen_InView(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) = 0;
- virtual void OnScreen_OutView(bool bModifier,
- bool bShift,
- CPDFSDK_Annot* pScreen) = 0;
-
- virtual void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) = 0;
- virtual void OnLink_MouseUp(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
-
- virtual void OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv,
- const WideString&) = 0;
- virtual void OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv) = 0;
- virtual void OnConsole_Exec() = 0;
virtual void OnExternal_Exec() = 0;
};
diff --git a/fxjs/ijs_runtime.cpp b/fxjs/ijs_runtime.cpp
index 34a846e..0308524 100644
--- a/fxjs/ijs_runtime.cpp
+++ b/fxjs/ijs_runtime.cpp
@@ -1,36 +1,46 @@
-// Copyright 2018 PDFium Authors. All rights reserved.
+// Copyright 2018 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fxjs/ijs_runtime.h"
#include "fxjs/cjs_runtimestub.h"
-#include "third_party/base/ptr_util.h"
#ifdef PDF_ENABLE_V8
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fxjs/cfxjs_engine.h"
#include "fxjs/cjs_runtime.h"
-#endif
+#ifdef PDF_ENABLE_XFA
+#include "fxjs/gc/heap.h"
+#endif // PDF_ENABLE_XFA
+#endif // PDF_ENABLE_V8
IJS_Runtime::ScopedEventContext::ScopedEventContext(IJS_Runtime* pRuntime)
: m_pRuntime(pRuntime), m_pContext(pRuntime->NewEventContext()) {}
IJS_Runtime::ScopedEventContext::~ScopedEventContext() {
- m_pRuntime->ReleaseEventContext(m_pContext.Release());
+ m_pRuntime->ReleaseEventContext(m_pContext.ExtractAsDangling());
}
// static
-void IJS_Runtime::Initialize(unsigned int slot, void* isolate) {
+void IJS_Runtime::Initialize(unsigned int slot, void* isolate, void* platform) {
#ifdef PDF_ENABLE_V8
FXJS_Initialize(slot, static_cast<v8::Isolate*>(isolate));
-#endif
+#ifdef PDF_ENABLE_XFA
+ FXGC_Initialize(static_cast<v8::Platform*>(platform),
+ static_cast<v8::Isolate*>(isolate));
+#endif // PDF_ENABLE_XFA
+#endif // PDF_ENABLE_V8
}
// static
void IJS_Runtime::Destroy() {
#ifdef PDF_ENABLE_V8
+#ifdef PDF_ENABLE_XFA
+ FXGC_Release();
+#endif // PDF_ENABLE_XFA
FXJS_Release();
-#endif
+#endif // PDF_ENABLE_V8
}
// static
@@ -38,9 +48,9 @@
CPDFSDK_FormFillEnvironment* pFormFillEnv) {
#ifdef PDF_ENABLE_V8
if (pFormFillEnv->IsJSPlatformPresent())
- return pdfium::MakeUnique<CJS_Runtime>(pFormFillEnv);
+ return std::make_unique<CJS_Runtime>(pFormFillEnv);
#endif
- return pdfium::MakeUnique<CJS_RuntimeStub>(pFormFillEnv);
+ return std::make_unique<CJS_RuntimeStub>(pFormFillEnv);
}
IJS_Runtime::~IJS_Runtime() = default;
diff --git a/fxjs/ijs_runtime.h b/fxjs/ijs_runtime.h
index ca103aa..d2ce19f 100644
--- a/fxjs/ijs_runtime.h
+++ b/fxjs/ijs_runtime.h
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,12 +9,11 @@
#include <memory>
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/unowned_ptr.h"
-#include "third_party/base/optional.h"
+#include "core/fxcrt/widestring.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
-class CFXJSE_Value;
class CJS_Runtime;
class CPDFSDK_FormFillEnvironment;
class IJS_EventContext;
@@ -34,18 +33,20 @@
class ScopedEventContext {
public:
+ FX_STACK_ALLOCATED();
+
explicit ScopedEventContext(IJS_Runtime* pRuntime);
~ScopedEventContext();
- IJS_EventContext* Get() const { return m_pContext.Get(); }
- IJS_EventContext* operator->() const { return m_pContext.Get(); }
+ IJS_EventContext* Get() const { return m_pContext; }
+ IJS_EventContext* operator->() const { return m_pContext; }
private:
UnownedPtr<IJS_Runtime> const m_pRuntime;
UnownedPtr<IJS_EventContext> m_pContext;
};
- static void Initialize(unsigned int slot, void* isolate);
+ static void Initialize(unsigned int slot, void* isolate, void* platform);
static void Destroy();
static std::unique_ptr<IJS_Runtime> Create(
CPDFSDK_FormFillEnvironment* pFormFillEnv);
@@ -56,7 +57,7 @@
virtual IJS_EventContext* NewEventContext() = 0;
virtual void ReleaseEventContext(IJS_EventContext* pContext) = 0;
virtual CPDFSDK_FormFillEnvironment* GetFormFillEnv() const = 0;
- virtual Optional<JS_Error> ExecuteScript(const WideString& script) = 0;
+ virtual absl::optional<JS_Error> ExecuteScript(const WideString& script) = 0;
protected:
IJS_Runtime() = default;
diff --git a/fxjs/js_define.cpp b/fxjs/js_define.cpp
index 0c0c02c..b19c2e2 100644
--- a/fxjs/js_define.cpp
+++ b/fxjs/js_define.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,8 +6,10 @@
#include "fxjs/js_define.h"
+#include <math.h>
+#include <stdarg.h>
+
#include <algorithm>
-#include <cmath>
#include <limits>
#include <vector>
@@ -15,50 +17,46 @@
#include "fxjs/cjs_document.h"
#include "fxjs/cjs_object.h"
#include "fxjs/fx_date_helpers.h"
+#include "fxjs/fxv8.h"
+#include "third_party/base/check.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-function.h"
+#include "v8/include/v8-isolate.h"
void JSDestructor(v8::Local<v8::Object> obj) {
CFXJS_Engine::SetObjectPrivate(obj, nullptr);
}
-double JS_DateParse(const WideString& str) {
- v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
+double JS_DateParse(v8::Isolate* pIsolate, const WideString& str) {
v8::Isolate::Scope isolate_scope(pIsolate);
v8::HandleScope scope(pIsolate);
v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
// Use the built-in object method.
- v8::Local<v8::Value> v =
- context->Global()
- ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
- v8::NewStringType::kNormal)
- .ToLocalChecked())
- .ToLocalChecked();
- if (v->IsObject()) {
- v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
- v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
- v8::NewStringType::kNormal)
- .ToLocalChecked())
- .ToLocalChecked();
- if (v->IsFunction()) {
- v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
- const int argc = 1;
- v8::Local<v8::Value> timeStr =
- v8::String::NewFromUtf8(pIsolate,
- FX_UTF8Encode(str.AsStringView()).c_str(),
- v8::NewStringType::kNormal)
- .ToLocalChecked();
- v8::Local<v8::Value> argv[argc] = {timeStr};
- v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
- if (v->IsNumber()) {
- double date = v->ToNumber(context).ToLocalChecked()->Value();
- if (!std::isfinite(date))
- return date;
- return FX_LocalTime(date);
- }
- }
- }
- return 0;
+ v8::MaybeLocal<v8::Value> maybe_value =
+ context->Global()->Get(context, fxv8::NewStringHelper(pIsolate, "Date"));
+
+ v8::Local<v8::Value> value;
+ if (!maybe_value.ToLocal(&value) || !value->IsObject())
+ return 0;
+
+ v8::Local<v8::Object> obj = value.As<v8::Object>();
+ maybe_value = obj->Get(context, fxv8::NewStringHelper(pIsolate, "parse"));
+ if (!maybe_value.ToLocal(&value) || !value->IsFunction())
+ return 0;
+
+ v8::Local<v8::Function> func = value.As<v8::Function>();
+ static constexpr int argc = 1;
+ v8::Local<v8::Value> argv[argc] = {
+ fxv8::NewStringHelper(pIsolate, str.AsStringView()),
+ };
+ maybe_value = func->Call(context, context->Global(), argc, argv);
+ if (!maybe_value.ToLocal(&value) || !value->IsNumber())
+ return 0;
+
+ double date = value.As<v8::Number>()->Value();
+ return isfinite(date) ? FX_LocalTime(date) : date;
}
std::vector<v8::Local<v8::Value>> ExpandKeywordParams(
@@ -66,7 +64,7 @@
const std::vector<v8::Local<v8::Value>>& originals,
size_t nKeywords,
...) {
- ASSERT(nKeywords);
+ DCHECK(nKeywords);
std::vector<v8::Local<v8::Value>> result(nKeywords, v8::Local<v8::Value>());
size_t size = std::min(originals.size(), nKeywords);
diff --git a/fxjs/js_define.h b/fxjs/js_define.h
index 2c15c9f..5b6573a 100644
--- a/fxjs/js_define.h
+++ b/fxjs/js_define.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,6 +7,7 @@
#ifndef FXJS_JS_DEFINE_H_
#define FXJS_JS_DEFINE_H_
+#include <memory>
#include <vector>
#include "core/fxcrt/unowned_ptr.h"
@@ -14,11 +15,10 @@
#include "fxjs/cjs_result.h"
#include "fxjs/cjs_runtime.h"
#include "fxjs/js_resources.h"
-#include "third_party/base/ptr_util.h"
class CJS_Object;
-double JS_DateParse(const WideString& str);
+double JS_DateParse(v8::Isolate* pIsolate, const WideString& str);
// Some JS methods have the bizarre convention that they may also be called
// with a single argument which is an object containing the actual arguments
@@ -42,20 +42,22 @@
// to construct native object state.
template <class T>
-static void JSConstructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) {
+static void JSConstructor(CFXJS_Engine* pEngine,
+ v8::Local<v8::Object> obj,
+ v8::Local<v8::Object> proxy) {
pEngine->SetObjectPrivate(
- obj, pdfium::MakeUnique<T>(obj, static_cast<CJS_Runtime*>(pEngine)));
+ obj, std::make_unique<T>(proxy, static_cast<CJS_Runtime*>(pEngine)));
}
// CJS_Object has virtual dtor, template not required.
void JSDestructor(v8::Local<v8::Object> obj);
template <class C>
-UnownedPtr<C> JSGetObject(v8::Local<v8::Object> obj) {
+UnownedPtr<C> JSGetObject(v8::Isolate* isolate, v8::Local<v8::Object> obj) {
if (CFXJS_Engine::GetObjDefnID(obj) != C::GetObjDefnID())
return nullptr;
- CJS_Object* pJSObj = CFXJS_Engine::GetObjectPrivate(obj);
+ CJS_Object* pJSObj = CFXJS_Engine::GetObjectPrivate(isolate, obj);
if (!pJSObj)
return nullptr;
@@ -67,7 +69,7 @@
const char* class_name_string,
v8::Local<v8::String> property,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- auto pObj = JSGetObject<C>(info.Holder());
+ auto pObj = JSGetObject<C>(info.GetIsolate(), info.Holder());
if (!pObj)
return;
@@ -75,7 +77,7 @@
if (!pRuntime)
return;
- CJS_Result result = (pObj.Get()->*M)(pRuntime);
+ CJS_Result result = (pObj.get()->*M)(pRuntime);
if (result.HasError()) {
pRuntime->Error(JSFormatErrorString(class_name_string, prop_name_string,
result.Error()));
@@ -92,7 +94,7 @@
v8::Local<v8::String> property,
v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<void>& info) {
- auto pObj = JSGetObject<C>(info.Holder());
+ auto pObj = JSGetObject<C>(info.GetIsolate(), info.Holder());
if (!pObj)
return;
@@ -100,7 +102,7 @@
if (!pRuntime)
return;
- CJS_Result result = (pObj.Get()->*M)(pRuntime, value);
+ CJS_Result result = (pObj.get()->*M)(pRuntime, value);
if (result.HasError()) {
pRuntime->Error(JSFormatErrorString(class_name_string, prop_name_string,
result.Error()));
@@ -113,7 +115,7 @@
void JSMethod(const char* method_name_string,
const char* class_name_string,
const v8::FunctionCallbackInfo<v8::Value>& info) {
- auto pObj = JSGetObject<C>(info.Holder());
+ auto pObj = JSGetObject<C>(info.GetIsolate(), info.Holder());
if (!pObj)
return;
@@ -125,7 +127,7 @@
for (unsigned int i = 0; i < (unsigned int)info.Length(); i++)
parameters.push_back(info[i]);
- CJS_Result result = (pObj.Get()->*M)(pRuntime, parameters);
+ CJS_Result result = (pObj.get()->*M)(pRuntime, parameters);
if (result.HasError()) {
pRuntime->Error(JSFormatErrorString(class_name_string, method_name_string,
result.Error()));
diff --git a/fxjs/js_resources.cpp b/fxjs/js_resources.cpp
index 3bc8df3..c133610 100644
--- a/fxjs/js_resources.cpp
+++ b/fxjs/js_resources.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,8 @@
#include "fxjs/js_resources.h"
+#include "third_party/base/notreached.h"
+
WideString JSGetStringFromID(JSMessage msg) {
const char* msg_string = "";
switch (msg) {
@@ -81,12 +83,15 @@
case JSMessage::kUserGestureRequiredError:
msg_string = "User gesture required.";
break;
- case JSMessage::kTooManyOccurances:
- msg_string = "Too many occurances.";
+ case JSMessage::kTooManyOccurrences:
+ msg_string = "Too many occurrences.";
break;
case JSMessage::kUnknownMethod:
msg_string = "Unknown method.";
break;
+ case JSMessage::kWouldBeCyclic:
+ msg_string = "Operation would create a cycle.";
+ break;
default:
NOTREACHED();
break;
@@ -97,10 +102,10 @@
WideString JSFormatErrorString(const char* class_name,
const char* property_name,
const WideString& details) {
- WideString result = WideString::FromDefANSI(class_name);
+ WideString result = WideString::FromUTF8(class_name);
if (property_name) {
result += L".";
- result += WideString::FromDefANSI(property_name);
+ result += WideString::FromUTF8(property_name);
}
result += L": ";
result += details;
diff --git a/fxjs/js_resources.h b/fxjs/js_resources.h
index 8a30862..0bc6be0 100644
--- a/fxjs/js_resources.h
+++ b/fxjs/js_resources.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -33,8 +33,9 @@
kUnknownProperty,
kInvalidSetError,
kUserGestureRequiredError,
- kTooManyOccurances,
+ kTooManyOccurrences,
kUnknownMethod,
+ kWouldBeCyclic,
};
WideString JSGetStringFromID(JSMessage msg);
diff --git a/fxjs/xfa/cfxjse_app_embeddertest.cpp b/fxjs/xfa/cfxjse_app_embeddertest.cpp
index 628f56e..0e6fa45 100644
--- a/fxjs/xfa/cfxjse_app_embeddertest.cpp
+++ b/fxjs/xfa/cfxjse_app_embeddertest.cpp
@@ -1,4 +1,4 @@
-// Copyright 2019 PDFium Authors. All rights reserved.
+// Copyright 2019 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
diff --git a/fxjs/xfa/cfxjse_arguments.cpp b/fxjs/xfa/cfxjse_arguments.cpp
deleted file mode 100644
index 8bfc8e3..0000000
--- a/fxjs/xfa/cfxjse_arguments.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "fxjs/xfa/cfxjse_arguments.h"
-
-#include "fxjs/xfa/cfxjse_context.h"
-#include "fxjs/xfa/cfxjse_value.h"
-#include "third_party/base/ptr_util.h"
-
-CFXJSE_Arguments::CFXJSE_Arguments(
- const v8::FunctionCallbackInfo<v8::Value>* pInfo,
- CFXJSE_Value* pRetValue)
- : m_pInfo(pInfo), m_pRetValue(pRetValue) {}
-
-CFXJSE_Arguments::~CFXJSE_Arguments() {}
-
-int32_t CFXJSE_Arguments::GetLength() const {
- return m_pInfo->Length();
-}
-
-std::unique_ptr<CFXJSE_Value> CFXJSE_Arguments::GetValue(int32_t index) const {
- auto pArgValue = pdfium::MakeUnique<CFXJSE_Value>(v8::Isolate::GetCurrent());
- pArgValue->ForceSetValue((*m_pInfo)[index]);
- return pArgValue;
-}
-
-bool CFXJSE_Arguments::GetBoolean(int32_t index) const {
- return (*m_pInfo)[index]->BooleanValue(m_pInfo->GetIsolate());
-}
-
-int32_t CFXJSE_Arguments::GetInt32(int32_t index) const {
- return static_cast<int32_t>(
- (*m_pInfo)[index]
- ->NumberValue(m_pInfo->GetIsolate()->GetCurrentContext())
- .FromMaybe(0.0));
-}
-
-float CFXJSE_Arguments::GetFloat(int32_t index) const {
- return static_cast<float>(
- (*m_pInfo)[index]
- ->NumberValue(m_pInfo->GetIsolate()->GetCurrentContext())
- .FromMaybe(0.0));
-}
-
-ByteString CFXJSE_Arguments::GetUTF8String(int32_t index) const {
- v8::Isolate* isolate = m_pInfo->GetIsolate();
- v8::Local<v8::Value> info = (*m_pInfo)[index];
- v8::Local<v8::String> hString =
- info->ToString(isolate->GetCurrentContext()).ToLocalChecked();
- v8::String::Utf8Value szStringVal(isolate, hString);
- return ByteString(*szStringVal);
-}
-
-CFXJSE_Value* CFXJSE_Arguments::GetReturnValue() const {
- return m_pRetValue.Get();
-}
diff --git a/fxjs/xfa/cfxjse_arguments.h b/fxjs/xfa/cfxjse_arguments.h
deleted file mode 100644
index e048bc2..0000000
--- a/fxjs/xfa/cfxjse_arguments.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef FXJS_XFA_CFXJSE_ARGUMENTS_H_
-#define FXJS_XFA_CFXJSE_ARGUMENTS_H_
-
-#include <memory>
-
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/unowned_ptr.h"
-#include "v8/include/v8.h"
-
-class CFXJSE_Value;
-
-class CFXJSE_Arguments {
- public:
- CFXJSE_Arguments(const v8::FunctionCallbackInfo<v8::Value>* pInfo,
- CFXJSE_Value* pRetValue);
- ~CFXJSE_Arguments();
-
- int32_t GetLength() const;
- std::unique_ptr<CFXJSE_Value> GetValue(int32_t index) const;
- bool GetBoolean(int32_t index) const;
- int32_t GetInt32(int32_t index) const;
- float GetFloat(int32_t index) const;
- ByteString GetUTF8String(int32_t index) const;
- CFXJSE_Value* GetReturnValue() const;
-
- private:
- UnownedPtr<const v8::FunctionCallbackInfo<v8::Value>> const m_pInfo;
- UnownedPtr<CFXJSE_Value> const m_pRetValue;
-};
-
-#endif // FXJS_XFA_CFXJSE_ARGUMENTS_H_
diff --git a/fxjs/xfa/cfxjse_class.cpp b/fxjs/xfa/cfxjse_class.cpp
index f6caf07..26b4666 100644
--- a/fxjs/xfa/cfxjse_class.cpp
+++ b/fxjs/xfa/cfxjse_class.cpp
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,12 +10,21 @@
#include <utility>
#include "fxjs/cjs_result.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
-#include "fxjs/xfa/cfxjse_arguments.h"
#include "fxjs/xfa/cfxjse_context.h"
#include "fxjs/xfa/cfxjse_isolatetracker.h"
#include "fxjs/xfa/cfxjse_value.h"
-#include "third_party/base/ptr_util.h"
+#include "third_party/base/check.h"
+#include "third_party/base/check_op.h"
+#include "v8/include/v8-container.h"
+#include "v8/include/v8-external.h"
+#include "v8/include/v8-function-callback.h"
+#include "v8/include/v8-function.h"
+#include "v8/include/v8-isolate.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-primitive.h"
+#include "v8/include/v8-template.h"
using pdfium::fxjse::kClassTag;
using pdfium::fxjse::kFuncTag;
@@ -34,19 +43,12 @@
void V8FunctionCallback_Wrapper(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- const FXJSE_FUNCTION_DESCRIPTOR* lpFunctionInfo =
+ const FXJSE_FUNCTION_DESCRIPTOR* pFunctionInfo =
AsFunctionDescriptor(info.Data().As<v8::External>()->Value());
- if (!lpFunctionInfo)
+ if (!pFunctionInfo)
return;
- ByteStringView szFunctionName(lpFunctionInfo->name);
- auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
- lpThisValue->ForceSetValue(info.Holder());
- auto lpRetValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
- CFXJSE_Arguments impl(&info, lpRetValue.get());
- lpFunctionInfo->callbackProc(lpThisValue.get(), szFunctionName, impl);
- if (!lpRetValue->DirectGetValue().IsEmpty())
- info.GetReturnValue().Set(lpRetValue->DirectGetValue());
+ pFunctionInfo->callbackProc(CFXJSE_HostObject::FromV8(info.Holder()), info);
}
void V8ConstructorCallback_Wrapper(
@@ -54,30 +56,28 @@
if (!info.IsConstructCall())
return;
- const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition =
+ const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor =
AsClassDescriptor(info.Data().As<v8::External>()->Value());
- if (!lpClassDefinition)
+ if (!pClassDescriptor)
return;
- ASSERT(info.Holder()->InternalFieldCount() == 2);
+ DCHECK_EQ(info.Holder()->InternalFieldCount(), 2);
info.Holder()->SetAlignedPointerInInternalField(0, nullptr);
info.Holder()->SetAlignedPointerInInternalField(1, nullptr);
}
void Context_GlobalObjToString(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- const FXJSE_CLASS_DESCRIPTOR* lpClass =
+ const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor =
AsClassDescriptor(info.Data().As<v8::External>()->Value());
- if (!lpClass)
+ if (!pClassDescriptor)
return;
- if (info.This() == info.Holder() && lpClass->name) {
- ByteString szStringVal = ByteString::Format("[object %s]", lpClass->name);
+ if (info.This() == info.Holder() && pClassDescriptor->name) {
+ ByteString szStringVal =
+ ByteString::Format("[object %s]", pClassDescriptor->name);
info.GetReturnValue().Set(
- v8::String::NewFromUtf8(info.GetIsolate(), szStringVal.c_str(),
- v8::NewStringType::kNormal,
- szStringVal.GetLength())
- .ToLocalChecked());
+ fxv8::NewStringHelper(info.GetIsolate(), szStringVal.AsStringView()));
return;
}
v8::Local<v8::String> local_str =
@@ -95,10 +95,10 @@
auto* pClassDescriptor = static_cast<const FXJSE_CLASS_DESCRIPTOR*>(
hCallBackInfo->GetAlignedPointerFromInternalField(0));
- if (pClassDescriptor != &GlobalClassDescriptor &&
- pClassDescriptor != &NormalClassDescriptor &&
- pClassDescriptor != &VariablesClassDescriptor &&
- pClassDescriptor != &kFormCalcFM2JSDescriptor) {
+ if (pClassDescriptor != &kGlobalClassDescriptor &&
+ pClassDescriptor != &kNormalClassDescriptor &&
+ pClassDescriptor != &kVariablesClassDescriptor &&
+ pClassDescriptor != &kFormCalcDescriptor) {
return;
}
@@ -114,9 +114,7 @@
if (result.HasError()) {
WideString err = JSFormatErrorString(pClassDescriptor->name, *szPropName,
result.Error());
- v8::MaybeLocal<v8::String> str = v8::String::NewFromUtf8(
- info.GetIsolate(), err.ToDefANSI().c_str(), v8::NewStringType::kNormal);
- info.GetIsolate()->ThrowException(str.ToLocalChecked());
+ fxv8::ThrowExceptionHelper(info.GetIsolate(), err.AsStringView());
return;
}
@@ -124,39 +122,39 @@
info.GetReturnValue().Set(result.Return());
}
-void DynPropGetterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
- CFXJSE_Value* pObject,
+void DynPropGetterAdapter(v8::Isolate* pIsolate,
+ const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor,
+ v8::Local<v8::Object> pObject,
ByteStringView szPropName,
CFXJSE_Value* pValue) {
- ASSERT(lpClass);
+ DCHECK(pClassDescriptor);
- int32_t nPropType =
- lpClass->dynPropTypeGetter == nullptr
- ? FXJSE_ClassPropType_Property
- : lpClass->dynPropTypeGetter(pObject, szPropName, false);
- if (nPropType == FXJSE_ClassPropType_Property) {
- if (lpClass->dynPropGetter)
- lpClass->dynPropGetter(pObject, szPropName, pValue);
- } else if (nPropType == FXJSE_ClassPropType_Method) {
- if (lpClass->dynMethodCall && pValue) {
- v8::Isolate* pIsolate = pValue->GetIsolate();
+ FXJSE_ClassPropType nPropType =
+ pClassDescriptor->dynPropTypeGetter
+ ? pClassDescriptor->dynPropTypeGetter(pIsolate, pObject, szPropName,
+ false)
+ : FXJSE_ClassPropType::kProperty;
+ if (nPropType == FXJSE_ClassPropType::kProperty) {
+ if (pClassDescriptor->dynPropGetter) {
+ pValue->ForceSetValue(pIsolate, pClassDescriptor->dynPropGetter(
+ pIsolate, pObject, szPropName));
+ }
+ } else if (nPropType == FXJSE_ClassPropType::kMethod) {
+ if (pClassDescriptor->dynMethodCall && pValue) {
v8::HandleScope hscope(pIsolate);
v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate =
v8::ObjectTemplate::New(pIsolate);
hCallBackInfoTemplate->SetInternalFieldCount(2);
v8::Local<v8::Object> hCallBackInfo =
- hCallBackInfoTemplate
- ->NewInstance(pValue->GetIsolate()->GetCurrentContext())
+ hCallBackInfoTemplate->NewInstance(pIsolate->GetCurrentContext())
.ToLocalChecked();
hCallBackInfo->SetAlignedPointerInInternalField(
- 0, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClass));
+ 0, const_cast<FXJSE_CLASS_DESCRIPTOR*>(pClassDescriptor));
hCallBackInfo->SetInternalField(
- 1, v8::String::NewFromUtf8(
- pIsolate, reinterpret_cast<const char*>(szPropName.raw_str()),
- v8::NewStringType::kNormal, szPropName.GetLength())
- .ToLocalChecked());
+ 1, fxv8::NewStringHelper(pIsolate, szPropName));
pValue->ForceSetValue(
- v8::Function::New(pValue->GetIsolate()->GetCurrentContext(),
+ pIsolate,
+ v8::Function::New(pIsolate->GetCurrentContext(),
DynPropGetterAdapter_MethodCallback, hCallBackInfo,
0, v8::ConstructorBehavior::kThrow)
.ToLocalChecked());
@@ -164,47 +162,49 @@
}
}
-void DynPropSetterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
- CFXJSE_Value* pObject,
+void DynPropSetterAdapter(v8::Isolate* pIsolate,
+ const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor,
+ v8::Local<v8::Object> pObject,
ByteStringView szPropName,
CFXJSE_Value* pValue) {
- ASSERT(lpClass);
- int32_t nPropType =
- lpClass->dynPropTypeGetter == nullptr
- ? FXJSE_ClassPropType_Property
- : lpClass->dynPropTypeGetter(pObject, szPropName, false);
- if (nPropType != FXJSE_ClassPropType_Method) {
- if (lpClass->dynPropSetter)
- lpClass->dynPropSetter(pObject, szPropName, pValue);
+ DCHECK(pClassDescriptor);
+ FXJSE_ClassPropType nPropType =
+ pClassDescriptor->dynPropTypeGetter
+ ? pClassDescriptor->dynPropTypeGetter(pIsolate, pObject, szPropName,
+ false)
+ : FXJSE_ClassPropType::kProperty;
+ if (nPropType != FXJSE_ClassPropType::kMethod) {
+ if (pClassDescriptor->dynPropSetter) {
+ pClassDescriptor->dynPropSetter(pIsolate, pObject, szPropName,
+ pValue->GetValue(pIsolate));
+ }
}
}
-bool DynPropQueryAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
- CFXJSE_Value* pObject,
+bool DynPropQueryAdapter(v8::Isolate* pIsolate,
+ const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor,
+ v8::Local<v8::Object> pObject,
ByteStringView szPropName) {
- ASSERT(lpClass);
- int32_t nPropType =
- lpClass->dynPropTypeGetter == nullptr
- ? FXJSE_ClassPropType_Property
- : lpClass->dynPropTypeGetter(pObject, szPropName, true);
- return nPropType != FXJSE_ClassPropType_None;
+ FXJSE_ClassPropType nPropType = pClassDescriptor->dynPropTypeGetter
+ ? pClassDescriptor->dynPropTypeGetter(
+ pIsolate, pObject, szPropName, true)
+ : FXJSE_ClassPropType::kProperty;
+ return nPropType != FXJSE_ClassPropType::kNone;
}
void NamedPropertyQueryCallback(
v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Integer>& info) {
- v8::Local<v8::Object> thisObject = info.Holder();
- const FXJSE_CLASS_DESCRIPTOR* lpClass =
+ const FXJSE_CLASS_DESCRIPTOR* pClass =
AsClassDescriptor(info.Data().As<v8::External>()->Value());
- if (!lpClass)
+ if (!pClass)
return;
v8::HandleScope scope(info.GetIsolate());
v8::String::Utf8Value szPropName(info.GetIsolate(), property);
ByteStringView szFxPropName(*szPropName, szPropName.length());
- auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
- lpThisValue->ForceSetValue(thisObject);
- if (DynPropQueryAdapter(lpClass, lpThisValue.get(), szFxPropName)) {
+ if (DynPropQueryAdapter(info.GetIsolate(), pClass, info.Holder(),
+ szFxPropName)) {
info.GetReturnValue().Set(v8::DontDelete);
return;
}
@@ -215,40 +215,33 @@
void NamedPropertyGetterCallback(
v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- v8::Local<v8::Object> thisObject = info.Holder();
- const FXJSE_CLASS_DESCRIPTOR* lpClass =
+ const FXJSE_CLASS_DESCRIPTOR* pClass =
AsClassDescriptor(info.Data().As<v8::External>()->Value());
- if (!lpClass)
+ if (!pClass)
return;
v8::String::Utf8Value szPropName(info.GetIsolate(), property);
ByteStringView szFxPropName(*szPropName, szPropName.length());
- auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
- lpThisValue->ForceSetValue(thisObject);
- auto lpNewValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
- DynPropGetterAdapter(lpClass, lpThisValue.get(), szFxPropName,
- lpNewValue.get());
- info.GetReturnValue().Set(lpNewValue->DirectGetValue());
+ auto pNewValue = std::make_unique<CFXJSE_Value>();
+ DynPropGetterAdapter(info.GetIsolate(), pClass, info.Holder(), szFxPropName,
+ pNewValue.get());
+ info.GetReturnValue().Set(pNewValue->DirectGetValue());
}
void NamedPropertySetterCallback(
v8::Local<v8::Name> property,
v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- v8::Local<v8::Object> thisObject = info.Holder();
- const FXJSE_CLASS_DESCRIPTOR* lpClass =
+ const FXJSE_CLASS_DESCRIPTOR* pClass =
AsClassDescriptor(info.Data().As<v8::External>()->Value());
- if (!lpClass)
+ if (!pClass)
return;
v8::String::Utf8Value szPropName(info.GetIsolate(), property);
ByteStringView szFxPropName(*szPropName, szPropName.length());
- auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
- lpThisValue->ForceSetValue(thisObject);
- auto lpNewValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
- lpNewValue->ForceSetValue(value);
- DynPropSetterAdapter(lpClass, lpThisValue.get(), szFxPropName,
- lpNewValue.get());
+ auto pNewValue = std::make_unique<CFXJSE_Value>(info.GetIsolate(), value);
+ DynPropSetterAdapter(info.GetIsolate(), pClass, info.Holder(), szFxPropName,
+ pNewValue.get());
info.GetReturnValue().Set(value);
}
@@ -258,86 +251,89 @@
}
void SetUpNamedPropHandler(v8::Isolate* pIsolate,
- v8::Local<v8::ObjectTemplate>* pObjectTemplate,
- const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition) {
+ v8::Local<v8::ObjectTemplate> pObjectTemplate,
+ const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor) {
v8::NamedPropertyHandlerConfiguration configuration(
- lpClassDefinition->dynPropGetter ? NamedPropertyGetterCallback : nullptr,
- lpClassDefinition->dynPropSetter ? NamedPropertySetterCallback : nullptr,
- lpClassDefinition->dynPropTypeGetter ? NamedPropertyQueryCallback
- : nullptr,
+ pClassDescriptor->dynPropGetter ? NamedPropertyGetterCallback : nullptr,
+ pClassDescriptor->dynPropSetter ? NamedPropertySetterCallback : nullptr,
+ pClassDescriptor->dynPropTypeGetter ? NamedPropertyQueryCallback
+ : nullptr,
nullptr, NamedPropertyEnumeratorCallback,
v8::External::New(pIsolate,
- const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)),
+ const_cast<FXJSE_CLASS_DESCRIPTOR*>(pClassDescriptor)),
v8::PropertyHandlerFlags::kNonMasking);
- (*pObjectTemplate)->SetHandler(configuration);
+ pObjectTemplate->SetHandler(configuration);
}
} // namespace
// static
CFXJSE_Class* CFXJSE_Class::Create(
- CFXJSE_Context* lpContext,
- const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition,
+ CFXJSE_Context* pContext,
+ const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor,
bool bIsJSGlobal) {
- if (!lpContext || !lpClassDefinition)
+ if (!pContext || !pClassDescriptor)
return nullptr;
CFXJSE_Class* pExistingClass =
- lpContext->GetClassByName(lpClassDefinition->name);
+ pContext->GetClassByName(pClassDescriptor->name);
if (pExistingClass)
return pExistingClass;
- v8::Isolate* pIsolate = lpContext->GetIsolate();
- auto pClass = pdfium::MakeUnique<CFXJSE_Class>(lpContext);
- pClass->m_szClassName = lpClassDefinition->name;
- pClass->m_lpClassDefinition = lpClassDefinition;
+ v8::Isolate* pIsolate = pContext->GetIsolate();
+ auto pClass = std::make_unique<CFXJSE_Class>(pContext);
+ pClass->m_szClassName = pClassDescriptor->name;
+ pClass->m_pClassDescriptor = pClassDescriptor;
CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
v8::Local<v8::FunctionTemplate> hFunctionTemplate = v8::FunctionTemplate::New(
pIsolate, bIsJSGlobal ? 0 : V8ConstructorCallback_Wrapper,
- v8::External::New(
- pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)));
- hFunctionTemplate->SetClassName(
- v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name,
- v8::NewStringType::kNormal)
- .ToLocalChecked());
+ v8::External::New(pIsolate,
+ const_cast<FXJSE_CLASS_DESCRIPTOR*>(pClassDescriptor)));
+ v8::Local<v8::String> classname =
+ fxv8::NewStringHelper(pIsolate, pClassDescriptor->name);
+ hFunctionTemplate->SetClassName(classname);
+ hFunctionTemplate->PrototypeTemplate()->Set(
+ v8::Symbol::GetToStringTag(pIsolate), classname,
+ static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontEnum));
hFunctionTemplate->InstanceTemplate()->SetInternalFieldCount(2);
v8::Local<v8::ObjectTemplate> hObjectTemplate =
hFunctionTemplate->InstanceTemplate();
- SetUpNamedPropHandler(pIsolate, &hObjectTemplate, lpClassDefinition);
+ SetUpNamedPropHandler(pIsolate, hObjectTemplate, pClassDescriptor);
- if (lpClassDefinition->methNum) {
- for (int32_t i = 0; i < lpClassDefinition->methNum; i++) {
+ if (pClassDescriptor->methNum) {
+ for (int32_t i = 0; i < pClassDescriptor->methNum; i++) {
v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(
pIsolate, V8FunctionCallback_Wrapper,
v8::External::New(pIsolate, const_cast<FXJSE_FUNCTION_DESCRIPTOR*>(
- lpClassDefinition->methods + i)));
+ pClassDescriptor->methods + i)));
fun->RemovePrototype();
hObjectTemplate->Set(
- v8::String::NewFromUtf8(pIsolate, lpClassDefinition->methods[i].name,
- v8::NewStringType::kNormal)
- .ToLocalChecked(),
+ fxv8::NewStringHelper(pIsolate, pClassDescriptor->methods[i].name),
fun,
static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
}
}
if (bIsJSGlobal) {
- v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(
+ v8::Local<v8::FunctionTemplate> fn = v8::FunctionTemplate::New(
pIsolate, Context_GlobalObjToString,
v8::External::New(
- pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)));
- fun->RemovePrototype();
- hObjectTemplate->Set(v8::String::NewFromUtf8(pIsolate, "toString",
- v8::NewStringType::kNormal)
- .ToLocalChecked(),
- fun);
+ pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(pClassDescriptor)));
+ fn->RemovePrototype();
+ hObjectTemplate->Set(fxv8::NewStringHelper(pIsolate, "toString"), fn);
}
- pClass->m_hTemplate.Reset(lpContext->GetIsolate(), hFunctionTemplate);
+ pClass->m_hTemplate.Reset(pContext->GetIsolate(), hFunctionTemplate);
CFXJSE_Class* pResult = pClass.get();
- lpContext->AddClass(std::move(pClass));
+ pContext->AddClass(std::move(pClass));
return pResult;
}
-CFXJSE_Class::CFXJSE_Class(CFXJSE_Context* lpContext) : m_pContext(lpContext) {}
+CFXJSE_Class::CFXJSE_Class(const CFXJSE_Context* pContext)
+ : m_pContext(pContext) {}
-CFXJSE_Class::~CFXJSE_Class() {}
+CFXJSE_Class::~CFXJSE_Class() = default;
+
+v8::Local<v8::FunctionTemplate> CFXJSE_Class::GetTemplate(
+ v8::Isolate* pIsolate) {
+ return v8::Local<v8::FunctionTemplate>::New(pIsolate, m_hTemplate);
+}
diff --git a/fxjs/xfa/cfxjse_class.h b/fxjs/xfa/cfxjse_class.h
index f5bc232..5f4d752 100644
--- a/fxjs/xfa/cfxjse_class.h
+++ b/fxjs/xfa/cfxjse_class.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,31 +9,29 @@
#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/xfa/fxjse.h"
-#include "v8/include/v8.h"
+#include "v8/include/v8-forward.h"
+#include "v8/include/v8-persistent-handle.h"
class CFXJSE_Context;
-class CFXJSE_Value;
struct FXJSE_CLASS_DESCRIPTOR;
class CFXJSE_Class {
public:
static CFXJSE_Class* Create(CFXJSE_Context* pContext,
- const FXJSE_CLASS_DESCRIPTOR* lpClassDefintion,
+ const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor,
bool bIsJSGlobal);
- explicit CFXJSE_Class(CFXJSE_Context* lpContext);
+ explicit CFXJSE_Class(const CFXJSE_Context* pContext);
~CFXJSE_Class();
- CFXJSE_Context* GetContext() const { return m_pContext.Get(); }
- v8::Global<v8::FunctionTemplate>& GetTemplate() { return m_hTemplate; }
+ bool IsName(ByteStringView name) const { return name == m_szClassName; }
+ const CFXJSE_Context* GetContext() const { return m_pContext; }
+ v8::Local<v8::FunctionTemplate> GetTemplate(v8::Isolate* pIsolate);
protected:
- friend class CFXJSE_Context;
- friend class CFXJSE_Value;
-
ByteString m_szClassName;
- UnownedPtr<const FXJSE_CLASS_DESCRIPTOR> m_lpClassDefinition;
- UnownedPtr<CFXJSE_Context> const m_pContext;
+ UnownedPtr<const FXJSE_CLASS_DESCRIPTOR> m_pClassDescriptor;
+ UnownedPtr<const CFXJSE_Context> const m_pContext;
v8::Global<v8::FunctionTemplate> m_hTemplate;
};
diff --git a/fxjs/xfa/cfxjse_context.cpp b/fxjs/xfa/cfxjse_context.cpp
index 1ff1417..970cb3d 100644
--- a/fxjs/xfa/cfxjse_context.cpp
+++ b/fxjs/xfa/cfxjse_context.cpp
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,11 +9,20 @@
#include <utility>
#include "fxjs/cfxjs_engine.h"
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_class.h"
#include "fxjs/xfa/cfxjse_isolatetracker.h"
#include "fxjs/xfa/cfxjse_runtimedata.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "fxjs/xfa/cjx_object.h"
+#include "third_party/base/check.h"
+#include "third_party/base/check_op.h"
#include "third_party/base/ptr_util.h"
+#include "v8/include/v8-exception.h"
+#include "v8/include/v8-function.h"
+#include "v8/include/v8-message.h"
+#include "v8/include/v8-script.h"
+#include "xfa/fxfa/parser/cxfa_thisproxy.h"
namespace {
@@ -51,9 +60,12 @@
" this.log(...args);\n"
"};";
-// Only address matters, values are for humans debuging here.
-char g_FXJSEHostObjectTag[] = "FXJSE Host Object";
-char g_FXJSEProxyObjectTag[] = "FXJSE Proxy Object";
+// Only address matters, values are for humans debuging here. Keep these
+// wchar_t to prevent the compiler from doing something clever, like
+// aligning them on a byte boundary to save space, which would make them
+// incompatible for use as V8 aligned pointers.
+const wchar_t kFXJSEHostObjectTag[] = L"FXJSE Host Object";
+const wchar_t kFXJSEProxyObjectTag[] = L"FXJSE Proxy Object";
v8::Local<v8::Object> CreateReturnValue(v8::Isolate* pIsolate,
v8::TryCatch* trycatch) {
@@ -68,23 +80,18 @@
v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
v8::Local<v8::Value> hException = trycatch->Exception();
if (hException->IsObject()) {
- v8::Local<v8::String> hNameStr =
- v8::String::NewFromUtf8(pIsolate, "name", v8::NewStringType::kNormal)
- .ToLocalChecked();
+ v8::Local<v8::String> hNameStr = fxv8::NewStringHelper(pIsolate, "name");
v8::Local<v8::Value> hValue =
hException.As<v8::Object>()->Get(context, hNameStr).ToLocalChecked();
if (hValue->IsString() || hValue->IsStringObject()) {
hReturnValue->Set(context, 0, hValue).FromJust();
} else {
v8::Local<v8::String> hErrorStr =
- v8::String::NewFromUtf8(pIsolate, "Error", v8::NewStringType::kNormal)
- .ToLocalChecked();
+ fxv8::NewStringHelper(pIsolate, "Error");
hReturnValue->Set(context, 0, hErrorStr).FromJust();
}
-
v8::Local<v8::String> hMessageStr =
- v8::String::NewFromUtf8(pIsolate, "message", v8::NewStringType::kNormal)
- .ToLocalChecked();
+ fxv8::NewStringHelper(pIsolate, "message");
hValue =
hException.As<v8::Object>()->Get(context, hMessageStr).ToLocalChecked();
if (hValue->IsString() || hValue->IsStringObject())
@@ -92,9 +99,7 @@
else
hReturnValue->Set(context, 1, hMessage->Get()).FromJust();
} else {
- v8::Local<v8::String> hErrorStr =
- v8::String::NewFromUtf8(pIsolate, "Error", v8::NewStringType::kNormal)
- .ToLocalChecked();
+ v8::Local<v8::String> hErrorStr = fxv8::NewStringHelper(pIsolate, "Error");
hReturnValue->Set(context, 0, hErrorStr).FromJust();
hReturnValue->Set(context, 1, hMessage->Get()).FromJust();
}
@@ -111,65 +116,48 @@
return hReturnValue;
}
-class CFXJSE_ScopeUtil_IsolateHandleContext {
- public:
- explicit CFXJSE_ScopeUtil_IsolateHandleContext(CFXJSE_Context* pContext)
- : m_parent(pContext->GetIsolate()), m_cscope(pContext->GetContext()) {}
- CFXJSE_ScopeUtil_IsolateHandleContext(
- const CFXJSE_ScopeUtil_IsolateHandleContext&) = delete;
- CFXJSE_ScopeUtil_IsolateHandleContext& operator=(
- const CFXJSE_ScopeUtil_IsolateHandleContext&) = delete;
-
- private:
- void* operator new(size_t size) = delete;
- void operator delete(void*, size_t) = delete;
-
- CFXJSE_ScopeUtil_IsolateHandle m_parent;
- v8::Context::Scope m_cscope;
-};
-
void FXJSE_UpdateProxyBinding(v8::Local<v8::Object> hObject) {
- ASSERT(!hObject.IsEmpty());
- ASSERT(hObject->InternalFieldCount() == 2);
- hObject->SetAlignedPointerInInternalField(0, g_FXJSEProxyObjectTag);
+ DCHECK(!hObject.IsEmpty());
+ DCHECK_EQ(hObject->InternalFieldCount(), 2);
+ hObject->SetAlignedPointerInInternalField(
+ 0, const_cast<wchar_t*>(kFXJSEProxyObjectTag));
hObject->SetAlignedPointerInInternalField(1, nullptr);
}
} // namespace
void FXJSE_UpdateObjectBinding(v8::Local<v8::Object> hObject,
- CFXJSE_HostObject* lpNewBinding) {
- ASSERT(!hObject.IsEmpty());
- ASSERT(hObject->InternalFieldCount() == 2);
- hObject->SetAlignedPointerInInternalField(0, g_FXJSEHostObjectTag);
- hObject->SetAlignedPointerInInternalField(1, lpNewBinding);
+ CFXJSE_HostObject* pNewBinding) {
+ DCHECK(!hObject.IsEmpty());
+ DCHECK_EQ(hObject->InternalFieldCount(), 2);
+ hObject->SetAlignedPointerInInternalField(
+ 0, const_cast<wchar_t*>(kFXJSEHostObjectTag));
+ hObject->SetAlignedPointerInInternalField(1, pNewBinding);
}
void FXJSE_ClearObjectBinding(v8::Local<v8::Object> hObject) {
- ASSERT(!hObject.IsEmpty());
- ASSERT(hObject->InternalFieldCount() == 2);
+ DCHECK(!hObject.IsEmpty());
+ DCHECK_EQ(hObject->InternalFieldCount(), 2);
hObject->SetAlignedPointerInInternalField(0, nullptr);
hObject->SetAlignedPointerInInternalField(1, nullptr);
}
-CFXJSE_HostObject* FXJSE_RetrieveObjectBinding(
- v8::Local<v8::Object> hJSObject) {
- ASSERT(!hJSObject.IsEmpty());
- if (!hJSObject->IsObject())
+CFXJSE_HostObject* FXJSE_RetrieveObjectBinding(v8::Local<v8::Value> hValue) {
+ if (!fxv8::IsObject(hValue))
return nullptr;
- v8::Local<v8::Object> hObject = hJSObject;
+ v8::Local<v8::Object> hObject = hValue.As<v8::Object>();
if (hObject->InternalFieldCount() != 2 ||
- hObject->GetAlignedPointerFromInternalField(0) == g_FXJSEProxyObjectTag) {
+ hObject->GetAlignedPointerFromInternalField(0) == kFXJSEProxyObjectTag) {
v8::Local<v8::Value> hProtoObject = hObject->GetPrototype();
- if (hProtoObject.IsEmpty() || !hProtoObject->IsObject())
+ if (!fxv8::IsObject(hProtoObject))
return nullptr;
hObject = hProtoObject.As<v8::Object>();
if (hObject->InternalFieldCount() != 2)
return nullptr;
}
- if (hObject->GetAlignedPointerFromInternalField(0) != g_FXJSEHostObjectTag)
+ if (hObject->GetAlignedPointerFromInternalField(0) != kFXJSEHostObjectTag)
return nullptr;
return static_cast<CFXJSE_HostObject*>(
@@ -180,31 +168,27 @@
std::unique_ptr<CFXJSE_Context> CFXJSE_Context::Create(
v8::Isolate* pIsolate,
const FXJSE_CLASS_DESCRIPTOR* pGlobalClass,
- CFXJSE_HostObject* pGlobalObject) {
+ CFXJSE_HostObject* pGlobalObject,
+ CXFA_ThisProxy* pProxy) {
CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
- auto pContext = pdfium::MakeUnique<CFXJSE_Context>(pIsolate);
+ // Private constructor.
+ auto pContext = pdfium::WrapUnique(new CFXJSE_Context(pIsolate, pProxy));
v8::Local<v8::ObjectTemplate> hObjectTemplate;
if (pGlobalClass) {
CFXJSE_Class* pGlobalClassObj =
CFXJSE_Class::Create(pContext.get(), pGlobalClass, true);
- ASSERT(pGlobalClassObj);
- v8::Local<v8::FunctionTemplate> hFunctionTemplate =
- v8::Local<v8::FunctionTemplate>::New(pIsolate,
- pGlobalClassObj->m_hTemplate);
- hObjectTemplate = hFunctionTemplate->InstanceTemplate();
+ hObjectTemplate =
+ pGlobalClassObj->GetTemplate(pIsolate)->InstanceTemplate();
} else {
hObjectTemplate = v8::ObjectTemplate::New(pIsolate);
hObjectTemplate->SetInternalFieldCount(2);
}
- hObjectTemplate->Set(
- v8::Symbol::GetToStringTag(pIsolate),
- v8::String::NewFromUtf8(pIsolate, "global", v8::NewStringType::kNormal)
- .ToLocalChecked());
+ hObjectTemplate->Set(v8::Symbol::GetToStringTag(pIsolate),
+ fxv8::NewStringHelper(pIsolate, "global"));
v8::Local<v8::Context> hNewContext =
v8::Context::New(pIsolate, nullptr, hObjectTemplate);
-
v8::Local<v8::Object> pThisProxy = hNewContext->Global();
FXJSE_UpdateProxyBinding(pThisProxy);
@@ -212,25 +196,25 @@
FXJSE_UpdateObjectBinding(pThis, pGlobalObject);
v8::Local<v8::Context> hRootContext = v8::Local<v8::Context>::New(
- pIsolate, CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext);
+ pIsolate, CFXJSE_RuntimeData::Get(pIsolate)->GetRootContext());
hNewContext->SetSecurityToken(hRootContext->GetSecurityToken());
pContext->m_hContext.Reset(pIsolate, hNewContext);
return pContext;
}
-CFXJSE_Context::CFXJSE_Context(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {}
+CFXJSE_Context::CFXJSE_Context(v8::Isolate* pIsolate, CXFA_ThisProxy* pProxy)
+ : m_pIsolate(pIsolate), m_pProxy(pProxy) {}
-CFXJSE_Context::~CFXJSE_Context() {}
+CFXJSE_Context::~CFXJSE_Context() = default;
-std::unique_ptr<CFXJSE_Value> CFXJSE_Context::GetGlobalObject() {
- auto pValue = pdfium::MakeUnique<CFXJSE_Value>(GetIsolate());
- CFXJSE_ScopeUtil_IsolateHandleContext scope(this);
+v8::Local<v8::Object> CFXJSE_Context::GetGlobalObject() {
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::EscapableHandleScope handle_scope(GetIsolate());
v8::Local<v8::Context> hContext =
v8::Local<v8::Context>::New(GetIsolate(), m_hContext);
- v8::Local<v8::Object> hGlobalObject =
+ v8::Local<v8::Object> result =
hContext->Global()->GetPrototype().As<v8::Object>();
- pValue->ForceSetValue(hGlobalObject);
- return pValue;
+ return handle_scope.Escape(result);
}
v8::Local<v8::Context> CFXJSE_Context::GetContext() {
@@ -245,64 +229,58 @@
auto pClass =
std::find_if(m_rgClasses.begin(), m_rgClasses.end(),
[szName](const std::unique_ptr<CFXJSE_Class>& item) {
- return szName == item->m_szClassName;
+ return item->IsName(szName);
});
return pClass != m_rgClasses.end() ? pClass->get() : nullptr;
}
void CFXJSE_Context::EnableCompatibleMode() {
- ExecuteScript(szCompatibleModeScript, nullptr, nullptr);
- ExecuteScript(szConsoleScript, nullptr, nullptr);
+ ExecuteScript(szCompatibleModeScript, nullptr, v8::Local<v8::Object>());
+ ExecuteScript(szConsoleScript, nullptr, v8::Local<v8::Object>());
}
-bool CFXJSE_Context::ExecuteScript(const char* szScript,
- CFXJSE_Value* lpRetValue,
- CFXJSE_Value* lpNewThisObject) {
+bool CFXJSE_Context::ExecuteScript(ByteStringView bsScript,
+ CFXJSE_Value* pRetValue,
+ v8::Local<v8::Object> hNewThis) {
CFXJSE_ScopeUtil_IsolateHandleContext scope(this);
v8::Local<v8::Context> hContext = GetIsolate()->GetCurrentContext();
v8::TryCatch trycatch(GetIsolate());
v8::Local<v8::String> hScriptString =
- v8::String::NewFromUtf8(GetIsolate(), szScript,
- v8::NewStringType::kNormal)
- .ToLocalChecked();
- if (!lpNewThisObject) {
+ fxv8::NewStringHelper(GetIsolate(), bsScript);
+ if (hNewThis.IsEmpty()) {
v8::Local<v8::Script> hScript;
if (v8::Script::Compile(hContext, hScriptString).ToLocal(&hScript)) {
- ASSERT(!trycatch.HasCaught());
+ CHECK(!trycatch.HasCaught());
v8::Local<v8::Value> hValue;
if (hScript->Run(hContext).ToLocal(&hValue)) {
- ASSERT(!trycatch.HasCaught());
- if (lpRetValue)
- lpRetValue->ForceSetValue(hValue);
+ CHECK(!trycatch.HasCaught());
+ if (pRetValue)
+ pRetValue->ForceSetValue(GetIsolate(), hValue);
return true;
}
}
- if (lpRetValue)
- lpRetValue->ForceSetValue(CreateReturnValue(GetIsolate(), &trycatch));
+ if (pRetValue) {
+ pRetValue->ForceSetValue(GetIsolate(),
+ CreateReturnValue(GetIsolate(), &trycatch));
+ }
return false;
}
- v8::Local<v8::Value> hNewThis = v8::Local<v8::Value>::New(
- GetIsolate(), lpNewThisObject->DirectGetValue());
- ASSERT(!hNewThis.IsEmpty());
- v8::Local<v8::String> hEval =
- v8::String::NewFromUtf8(GetIsolate(),
- "(function () { return eval(arguments[0]); })",
- v8::NewStringType::kNormal)
- .ToLocalChecked();
+ v8::Local<v8::String> hEval = fxv8::NewStringHelper(
+ GetIsolate(), "(function () { return eval(arguments[0]); })");
v8::Local<v8::Script> hWrapper =
v8::Script::Compile(hContext, hEval).ToLocalChecked();
v8::Local<v8::Value> hWrapperValue;
if (hWrapper->Run(hContext).ToLocal(&hWrapperValue)) {
- ASSERT(!trycatch.HasCaught());
+ CHECK(!trycatch.HasCaught());
+ CHECK(hWrapperValue->IsFunction());
v8::Local<v8::Function> hWrapperFn = hWrapperValue.As<v8::Function>();
v8::Local<v8::Value> rgArgs[] = {hScriptString};
v8::Local<v8::Value> hValue;
- if (hWrapperFn->Call(hContext, hNewThis.As<v8::Object>(), 1, rgArgs)
- .ToLocal(&hValue)) {
- ASSERT(!trycatch.HasCaught());
- if (lpRetValue)
- lpRetValue->ForceSetValue(hValue);
+ if (hWrapperFn->Call(hContext, hNewThis, 1, rgArgs).ToLocal(&hValue)) {
+ DCHECK(!trycatch.HasCaught());
+ if (pRetValue)
+ pRetValue->ForceSetValue(GetIsolate(), hValue);
return true;
}
}
@@ -321,7 +299,9 @@
}
#endif // NDEBUG
- if (lpRetValue)
- lpRetValue->ForceSetValue(CreateReturnValue(GetIsolate(), &trycatch));
+ if (pRetValue) {
+ pRetValue->ForceSetValue(GetIsolate(),
+ CreateReturnValue(GetIsolate(), &trycatch));
+ }
return false;
}
diff --git a/fxjs/xfa/cfxjse_context.h b/fxjs/xfa/cfxjse_context.h
index b519e77..4217b2b 100644
--- a/fxjs/xfa/cfxjse_context.h
+++ b/fxjs/xfa/cfxjse_context.h
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,14 +10,16 @@
#include <memory>
#include <vector>
-#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/bytestring.h"
#include "core/fxcrt/unowned_ptr.h"
-#include "v8/include/v8.h"
+#include "v8/include/cppgc/persistent.h"
+#include "v8/include/v8-forward.h"
+#include "v8/include/v8-persistent-handle.h"
-class CFXJS_Engine;
class CFXJSE_Class;
class CFXJSE_HostObject;
class CFXJSE_Value;
+class CXFA_ThisProxy;
struct FXJSE_CLASS_DESCRIPTOR;
class CFXJSE_Context {
@@ -25,34 +27,39 @@
static std::unique_ptr<CFXJSE_Context> Create(
v8::Isolate* pIsolate,
const FXJSE_CLASS_DESCRIPTOR* pGlobalClass,
- CFXJSE_HostObject* pGlobalObject);
+ CFXJSE_HostObject* pGlobalObject,
+ CXFA_ThisProxy* pProxy);
- explicit CFXJSE_Context(v8::Isolate* pIsolate);
~CFXJSE_Context();
- v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); }
+ v8::Isolate* GetIsolate() const { return m_pIsolate; }
v8::Local<v8::Context> GetContext();
- std::unique_ptr<CFXJSE_Value> GetGlobalObject();
+ v8::Local<v8::Object> GetGlobalObject();
+
void AddClass(std::unique_ptr<CFXJSE_Class> pClass);
CFXJSE_Class* GetClassByName(ByteStringView szName) const;
void EnableCompatibleMode();
- bool ExecuteScript(const char* szScript,
- CFXJSE_Value* lpRetValue,
- CFXJSE_Value* lpNewThisObject);
+
+ // Note: `pNewThisObject` may be empty.
+ bool ExecuteScript(ByteStringView bsScript,
+ CFXJSE_Value* pRetValue,
+ v8::Local<v8::Object> pNewThisObject);
private:
+ CFXJSE_Context(v8::Isolate* pIsolate, CXFA_ThisProxy* pProxy);
CFXJSE_Context(const CFXJSE_Context&) = delete;
CFXJSE_Context& operator=(const CFXJSE_Context&) = delete;
v8::Global<v8::Context> m_hContext;
UnownedPtr<v8::Isolate> m_pIsolate;
std::vector<std::unique_ptr<CFXJSE_Class>> m_rgClasses;
+ cppgc::Persistent<CXFA_ThisProxy> m_pProxy;
};
void FXJSE_UpdateObjectBinding(v8::Local<v8::Object> hObject,
- CFXJSE_HostObject* lpNewBinding);
+ CFXJSE_HostObject* pNewBinding);
void FXJSE_ClearObjectBinding(v8::Local<v8::Object> hJSObject);
-CFXJSE_HostObject* FXJSE_RetrieveObjectBinding(v8::Local<v8::Object> hJSObject);
+CFXJSE_HostObject* FXJSE_RetrieveObjectBinding(v8::Local<v8::Value> hValue);
#endif // FXJS_XFA_CFXJSE_CONTEXT_H_
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index 9be2498..601ffb4 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,34 +9,38 @@
#include <utility>
#include "core/fxcrt/autorestorer.h"
-#include "core/fxcrt/cfx_widetextbuf.h"
#include "core/fxcrt/fx_extension.h"
+#include "core/fxcrt/stl_util.h"
+#include "core/fxcrt/widetext_buffer.h"
#include "fxjs/cjs_runtime.h"
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_class.h"
#include "fxjs/xfa/cfxjse_context.h"
#include "fxjs/xfa/cfxjse_formcalc_context.h"
+#include "fxjs/xfa/cfxjse_isolatetracker.h"
+#include "fxjs/xfa/cfxjse_nodehelper.h"
#include "fxjs/xfa/cfxjse_resolveprocessor.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "fxjs/xfa/cjx_object.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
+#include "third_party/base/containers/contains.h"
+#include "v8/include/v8-function-callback.h"
+#include "v8/include/v8-function.h"
+#include "v8/include/v8-object.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_localemgr.h"
#include "xfa/fxfa/parser/cxfa_node.h"
-#include "xfa/fxfa/parser/cxfa_nodehelper.h"
#include "xfa/fxfa/parser/cxfa_object.h"
#include "xfa/fxfa/parser/cxfa_thisproxy.h"
-#include "xfa/fxfa/parser/cxfa_treelist.h"
+#include "xfa/fxfa/parser/cxfa_variables.h"
#include "xfa/fxfa/parser/xfa_basic_data.h"
-#include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
#include "xfa/fxfa/parser/xfa_utils.h"
using pdfium::fxjse::kClassTag;
-const FXJSE_CLASS_DESCRIPTOR GlobalClassDescriptor = {
+const FXJSE_CLASS_DESCRIPTOR kGlobalClassDescriptor = {
kClassTag, // tag
"Root", // name
nullptr, // methods
@@ -47,7 +51,7 @@
CFXJSE_Engine::NormalMethodCall,
};
-const FXJSE_CLASS_DESCRIPTOR NormalClassDescriptor = {
+const FXJSE_CLASS_DESCRIPTOR kNormalClassDescriptor = {
kClassTag, // tag
"XFAObject", // name
nullptr, // methods
@@ -58,7 +62,7 @@
CFXJSE_Engine::NormalMethodCall,
};
-const FXJSE_CLASS_DESCRIPTOR VariablesClassDescriptor = {
+const FXJSE_CLASS_DESCRIPTOR kVariablesClassDescriptor = {
kClassTag, // tag
"XFAScriptObject", // name
nullptr, // methods
@@ -73,28 +77,46 @@
const char kFormCalcRuntime[] = "pfm_rt";
-CXFA_ThisProxy* ToThisProxy(CFXJSE_Value* pValue) {
- CFXJSE_HostObject* pHostObject = pValue->ToHostObject();
- return pHostObject ? ToThisProxy(pHostObject->AsCXFAObject()) : nullptr;
-}
-
} // namespace
+CFXJSE_Engine::ResolveResult::ResolveResult() = default;
+
+CFXJSE_Engine::ResolveResult::ResolveResult(const ResolveResult& that) =
+ default;
+
+CFXJSE_Engine::ResolveResult& CFXJSE_Engine::ResolveResult::operator=(
+ const ResolveResult& that) = default;
+
+CFXJSE_Engine::ResolveResult::~ResolveResult() = default;
+
// static
CXFA_Object* CFXJSE_Engine::ToObject(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- if (!info.Holder()->IsObject())
+ return ToObject(info.GetIsolate(), info.Holder());
+}
+
+// static
+CXFA_Object* CFXJSE_Engine::ToObject(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> value) {
+ if (!value->IsObject())
return nullptr;
- CFXJSE_HostObject* pHostObj =
- FXJSE_RetrieveObjectBinding(info.Holder().As<v8::Object>());
- return pHostObj ? pHostObj->AsCXFAObject() : nullptr;
+ return ToObject(FXJSE_RetrieveObjectBinding(value.As<v8::Object>()));
}
// static.
-CXFA_Object* CFXJSE_Engine::ToObject(CFXJSE_Value* pValue) {
- CFXJSE_HostObject* pHostObj = pValue->ToHostObject();
- return pHostObj ? pHostObj->AsCXFAObject() : nullptr;
+CXFA_Object* CFXJSE_Engine::ToObject(v8::Isolate* pIsolate,
+ CFXJSE_Value* pValue) {
+ return ToObject(pValue->ToHostObject(pIsolate));
+}
+
+// static
+CXFA_Object* CFXJSE_Engine::ToObject(CFXJSE_HostObject* pHostObj) {
+ if (!pHostObj)
+ return nullptr;
+
+ CJX_Object* pJSObject = pHostObj->AsCJXObject();
+ return pJSObject ? pJSObject->GetXFAObject() : nullptr;
}
CFXJSE_Engine::CFXJSE_Engine(CXFA_Document* pDocument,
@@ -103,311 +125,352 @@
m_pSubordinateRuntime(fxjs_runtime),
m_pDocument(pDocument),
m_JsContext(CFXJSE_Context::Create(fxjs_runtime->GetIsolate(),
- &GlobalClassDescriptor,
- pDocument->GetRoot())),
- m_ResolveProcessor(pdfium::MakeUnique<CFXJSE_ResolveProcessor>()) {
+ &kGlobalClassDescriptor,
+ pDocument->GetRoot()->JSObject(),
+ nullptr)),
+ m_NodeHelper(std::make_unique<CFXJSE_NodeHelper>()),
+ m_ResolveProcessor(
+ std::make_unique<CFXJSE_ResolveProcessor>(this, m_NodeHelper.get())) {
RemoveBuiltInObjs(m_JsContext.get());
m_JsContext->EnableCompatibleMode();
// Don't know if this can happen before we remove the builtin objs and set
// compatibility mode.
m_pJsClass =
- CFXJSE_Class::Create(m_JsContext.get(), &NormalClassDescriptor, false);
+ CFXJSE_Class::Create(m_JsContext.get(), &kNormalClassDescriptor, false);
}
CFXJSE_Engine::~CFXJSE_Engine() {
- for (const auto& pair : m_mapVariableToContext)
- delete ToThisProxy(pair.second->GetGlobalObject().get());
+ // This is what ensures that the v8 object bound to a CJX_Object
+ // no longer retains that binding since it will outlive that object.
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
+ for (const auto& pair : m_mapObjectToObject) {
+ const v8::Global<v8::Object>& binding = pair.second;
+ FXJSE_ClearObjectBinding(v8::Local<v8::Object>::New(GetIsolate(), binding));
+ }
+}
- for (const auto& pair : m_mapObjectToValue)
- pair.second->ClearHostObject();
+CFXJSE_Engine::EventParamScope::EventParamScope(CFXJSE_Engine* pEngine,
+ CXFA_Node* pTarget,
+ CXFA_EventParam* pEventParam)
+ : m_pEngine(pEngine),
+ m_pPrevTarget(pEngine->GetEventTarget()),
+ m_pPrevEventParam(pEngine->GetEventParam()) {
+ m_pEngine->m_pTarget = pTarget;
+ m_pEngine->m_eventParam = pEventParam;
+}
+
+CFXJSE_Engine::EventParamScope::~EventParamScope() {
+ m_pEngine->m_pTarget = m_pPrevTarget;
+ m_pEngine->m_eventParam = m_pPrevEventParam;
}
bool CFXJSE_Engine::RunScript(CXFA_Script::Type eScriptType,
WideStringView wsScript,
CFXJSE_Value* hRetValue,
CXFA_Object* pThisObject) {
- ByteString btScript;
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
AutoRestorer<CXFA_Script::Type> typeRestorer(&m_eScriptType);
m_eScriptType = eScriptType;
+
+ ByteString btScript;
if (eScriptType == CXFA_Script::Type::Formcalc) {
- if (!m_FM2JSContext) {
- m_FM2JSContext = pdfium::MakeUnique<CFXJSE_FormCalcContext>(
+ if (!m_FormCalcContext) {
+ m_FormCalcContext = std::make_unique<CFXJSE_FormCalcContext>(
GetIsolate(), m_JsContext.get(), m_pDocument.Get());
}
- CFX_WideTextBuf wsJavaScript;
- if (!CFXJSE_FormCalcContext::Translate(wsScript, &wsJavaScript)) {
- hRetValue->SetUndefined();
+ absl::optional<WideTextBuffer> wsJavaScript =
+ CFXJSE_FormCalcContext::Translate(m_pDocument->GetHeap(), wsScript);
+ if (!wsJavaScript.has_value()) {
+ hRetValue->SetUndefined(GetIsolate());
return false;
}
- btScript = FX_UTF8Encode(wsJavaScript.AsStringView());
+ btScript = FX_UTF8Encode(wsJavaScript.value().AsStringView());
} else {
btScript = FX_UTF8Encode(wsScript);
}
- AutoRestorer<UnownedPtr<CXFA_Object>> nodeRestorer(&m_pThisObject);
+ AutoRestorer<cppgc::Persistent<CXFA_Object>> nodeRestorer(&m_pThisObject);
m_pThisObject = pThisObject;
- CFXJSE_Value* pValue =
- pThisObject ? GetOrCreateJSBindingFromMap(pThisObject) : nullptr;
- IJS_Runtime::ScopedEventContext ctx(m_pSubordinateRuntime.Get());
- return m_JsContext->ExecuteScript(btScript.c_str(), hRetValue, pValue);
+ v8::Local<v8::Object> pThisBinding;
+ if (pThisObject)
+ pThisBinding = GetOrCreateJSBindingFromMap(pThisObject);
+
+ IJS_Runtime::ScopedEventContext ctx(m_pSubordinateRuntime);
+ return m_JsContext->ExecuteScript(btScript.AsStringView(), hRetValue,
+ pThisBinding);
}
bool CFXJSE_Engine::QueryNodeByFlag(CXFA_Node* refNode,
WideStringView propname,
- CFXJSE_Value* pValue,
- uint32_t dwFlag,
- bool bSetting) {
+ v8::Local<v8::Value>* pValue,
+ Mask<XFA_ResolveFlag> dwFlag) {
if (!refNode)
return false;
- XFA_RESOLVENODE_RS resolveRs;
- if (!ResolveObjects(refNode, propname, &resolveRs, dwFlag, nullptr))
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+ ResolveObjects(refNode, propname, dwFlag);
+ if (!maybeResult.has_value())
return false;
- if (resolveRs.dwFlags == XFA_ResolveNode_RSType_Nodes) {
- pValue->Assign(
- GetOrCreateJSBindingFromMap(resolveRs.objects.front().Get()));
+
+ if (maybeResult.value().type == ResolveResult::Type::kNodes) {
+ *pValue =
+ GetOrCreateJSBindingFromMap(maybeResult.value().objects.front().Get());
return true;
}
- if (resolveRs.dwFlags == XFA_ResolveNode_RSType_Attribute &&
- resolveRs.script_attribute.callback) {
- CJX_Object* jsObject = resolveRs.objects.front()->JSObject();
- (*resolveRs.script_attribute.callback)(
- jsObject, pValue, bSetting, resolveRs.script_attribute.attribute);
+ if (maybeResult.value().type == ResolveResult::Type::kAttribute &&
+ maybeResult.value().script_attribute.callback) {
+ CJX_Object* jsObject = maybeResult.value().objects.front()->JSObject();
+ (*maybeResult.value().script_attribute.callback)(
+ GetIsolate(), jsObject, pValue, false,
+ maybeResult.value().script_attribute.attribute);
+ }
+ return true;
+}
+
+bool CFXJSE_Engine::UpdateNodeByFlag(CXFA_Node* refNode,
+ WideStringView propname,
+ v8::Local<v8::Value> pValue,
+ Mask<XFA_ResolveFlag> dwFlag) {
+ if (!refNode)
+ return false;
+
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+ ResolveObjects(refNode, propname, dwFlag);
+ if (!maybeResult.has_value())
+ return false;
+
+ if (maybeResult.value().type == ResolveResult::Type::kAttribute &&
+ maybeResult.value().script_attribute.callback) {
+ CJX_Object* jsObject = maybeResult.value().objects.front()->JSObject();
+ (*maybeResult.value().script_attribute.callback)(
+ GetIsolate(), jsObject, &pValue, true,
+ maybeResult.value().script_attribute.attribute);
}
return true;
}
// static
-void CFXJSE_Engine::GlobalPropertySetter(CFXJSE_Value* pObject,
+void CFXJSE_Engine::GlobalPropertySetter(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
ByteStringView szPropName,
- CFXJSE_Value* pValue) {
- CXFA_Object* lpOrginalNode = ToObject(pObject);
- CXFA_Document* pDoc = lpOrginalNode->GetDocument();
- CFXJSE_Engine* lpScriptContext = pDoc->GetScriptContext();
- CXFA_Node* pRefNode = ToNode(lpScriptContext->GetThisObject());
- if (lpOrginalNode->IsThisProxy())
- pRefNode = ToNode(lpScriptContext->GetVariablesThis(lpOrginalNode, false));
+ v8::Local<v8::Value> pValue) {
+ CXFA_Object* pOriginalNode = ToObject(pIsolate, pObject);
+ CXFA_Document* pDoc = pOriginalNode->GetDocument();
+ CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
+ CXFA_Node* pRefNode = ToNode(pScriptContext->GetThisObject());
+ if (pOriginalNode->IsThisProxy())
+ pRefNode = ToNode(pScriptContext->GetVariablesThis(pOriginalNode));
WideString wsPropName = WideString::FromUTF8(szPropName);
- if (lpScriptContext->QueryNodeByFlag(
+ if (pScriptContext->UpdateNodeByFlag(
pRefNode, wsPropName.AsStringView(), pValue,
- XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings |
- XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
- XFA_RESOLVENODE_Attributes,
- true)) {
+ Mask<XFA_ResolveFlag>{
+ XFA_ResolveFlag::kParent, XFA_ResolveFlag::kSiblings,
+ XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kProperties,
+ XFA_ResolveFlag::kAttributes})) {
return;
}
- if (lpOrginalNode->IsThisProxy() && pValue && pValue->IsUndefined()) {
- pObject->DeleteObjectProperty(szPropName);
+ if (pOriginalNode->IsThisProxy() && fxv8::IsUndefined(pValue)) {
+ fxv8::ReentrantDeleteObjectPropertyHelper(pScriptContext->GetIsolate(),
+ pObject, szPropName);
return;
}
CXFA_FFNotify* pNotify = pDoc->GetNotify();
if (!pNotify)
return;
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
- auto* pCJSRuntime =
- static_cast<CJS_Runtime*>(hDoc->GetDocEnvironment()->GetIJSRuntime(hDoc));
+ CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
+ auto* pCJSRuntime = static_cast<CJS_Runtime*>(hDoc->GetIJSRuntime());
if (!pCJSRuntime)
return;
- v8::HandleScope handle_scope(lpScriptContext->GetIsolate());
IJS_Runtime::ScopedEventContext pContext(pCJSRuntime);
- pCJSRuntime->SetValueByNameInGlobalObject(
- szPropName, v8::Local<v8::Value>::New(lpScriptContext->GetIsolate(),
- pValue->DirectGetValue()));
+ pCJSRuntime->SetValueByNameInGlobalObject(szPropName, pValue);
}
// static
-void CFXJSE_Engine::GlobalPropertyGetter(CFXJSE_Value* pObject,
- ByteStringView szPropName,
- CFXJSE_Value* pValue) {
- CXFA_Object* pOriginalObject = ToObject(pObject);
+v8::Local<v8::Value> CFXJSE_Engine::GlobalPropertyGetter(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
+ ByteStringView szPropName) {
+ CXFA_Object* pOriginalObject = ToObject(pIsolate, pObject);
CXFA_Document* pDoc = pOriginalObject->GetDocument();
- CFXJSE_Engine* lpScriptContext = pDoc->GetScriptContext();
+ CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
WideString wsPropName = WideString::FromUTF8(szPropName);
- pValue->SetUndefined(); // Assume failure.
- if (lpScriptContext->GetType() == CXFA_Script::Type::Formcalc) {
- if (szPropName == kFormCalcRuntime) {
- lpScriptContext->m_FM2JSContext->GlobalPropertyGetter(pValue);
- return;
- }
- XFA_HashCode uHashCode = static_cast<XFA_HashCode>(
- FX_HashCode_GetW(wsPropName.AsStringView(), false));
+ // Assume failure.
+ v8::Local<v8::Value> pValue = fxv8::NewUndefinedHelper(pIsolate);
+
+ if (pScriptContext->GetType() == CXFA_Script::Type::Formcalc) {
+ if (szPropName == kFormCalcRuntime)
+ return pScriptContext->m_FormCalcContext->GlobalPropertyGetter();
+
+ XFA_HashCode uHashCode =
+ static_cast<XFA_HashCode>(FX_HashCode_GetW(wsPropName.AsStringView()));
if (uHashCode != XFA_HASHCODE_Layout) {
CXFA_Object* pObj =
- lpScriptContext->GetDocument()->GetXFAObject(uHashCode);
- if (pObj) {
- pValue->Assign(lpScriptContext->GetOrCreateJSBindingFromMap(pObj));
- return;
- }
+ pScriptContext->GetDocument()->GetXFAObject(uHashCode);
+ if (pObj)
+ return pScriptContext->GetOrCreateJSBindingFromMap(pObj);
}
}
- CXFA_Node* pRefNode = ToNode(lpScriptContext->GetThisObject());
- if (pOriginalObject->IsThisProxy()) {
- pRefNode =
- ToNode(lpScriptContext->GetVariablesThis(pOriginalObject, false));
+ CXFA_Node* pRefNode = ToNode(pScriptContext->GetThisObject());
+ if (pOriginalObject->IsThisProxy())
+ pRefNode = ToNode(pScriptContext->GetVariablesThis(pOriginalObject));
+
+ if (pScriptContext->QueryNodeByFlag(
+ pRefNode, wsPropName.AsStringView(), &pValue,
+ Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kChildren,
+ XFA_ResolveFlag::kProperties,
+ XFA_ResolveFlag::kAttributes})) {
+ return pValue;
}
- if (lpScriptContext->QueryNodeByFlag(
- pRefNode, wsPropName.AsStringView(), pValue,
- XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
- XFA_RESOLVENODE_Attributes,
- false)) {
- return;
- }
- if (lpScriptContext->QueryNodeByFlag(
- pRefNode, wsPropName.AsStringView(), pValue,
- XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings, false)) {
- return;
+ if (pScriptContext->QueryNodeByFlag(
+ pRefNode, wsPropName.AsStringView(), &pValue,
+ Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kParent,
+ XFA_ResolveFlag::kSiblings})) {
+ return pValue;
}
CXFA_Object* pScriptObject =
- lpScriptContext->GetVariablesThis(pOriginalObject, true);
- if (pScriptObject && lpScriptContext->QueryVariableValue(
- pScriptObject->AsNode(), szPropName, pValue, true)) {
- return;
+ pScriptContext->GetVariablesScript(pOriginalObject);
+ if (pScriptObject && pScriptContext->QueryVariableValue(
+ CXFA_Script::FromNode(pScriptObject->AsNode()),
+ szPropName, &pValue)) {
+ return pValue;
}
CXFA_FFNotify* pNotify = pDoc->GetNotify();
if (!pNotify)
- return;
+ return pValue;
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
- auto* pCJSRuntime =
- static_cast<CJS_Runtime*>(hDoc->GetDocEnvironment()->GetIJSRuntime(hDoc));
+ CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
+ auto* pCJSRuntime = static_cast<CJS_Runtime*>(hDoc->GetIJSRuntime());
if (!pCJSRuntime)
- return;
+ return pValue;
- v8::HandleScope handle_scope(lpScriptContext->GetIsolate());
IJS_Runtime::ScopedEventContext pContext(pCJSRuntime);
- v8::Local<v8::Value> temp_value;
- if (!pCJSRuntime->GetValueByNameFromGlobalObject(szPropName, &temp_value))
- return;
+ v8::Local<v8::Value> temp_value =
+ pCJSRuntime->GetValueByNameFromGlobalObject(szPropName);
- if (temp_value.IsEmpty())
- return;
-
- pValue->ForceSetValue(temp_value);
-}
-
-int32_t CFXJSE_Engine::GlobalPropTypeGetter(CFXJSE_Value* pOriginalValue,
- ByteStringView szPropName,
- bool bQueryIn) {
- CXFA_Object* pObject = ToObject(pOriginalValue);
- if (!pObject)
- return FXJSE_ClassPropType_None;
-
- CFXJSE_Engine* lpScriptContext = pObject->GetDocument()->GetScriptContext();
- pObject = lpScriptContext->GetVariablesThis(pObject, false);
- WideString wsPropName = WideString::FromUTF8(szPropName);
- if (pObject->JSObject()->HasMethod(wsPropName))
- return FXJSE_ClassPropType_Method;
-
- return FXJSE_ClassPropType_Property;
+ return !temp_value.IsEmpty() ? temp_value : pValue;
}
// static
-void CFXJSE_Engine::NormalPropertyGetter(CFXJSE_Value* pOriginalValue,
- ByteStringView szPropName,
- CFXJSE_Value* pReturnValue) {
- pReturnValue->SetUndefined(); // Assume failure.
- CXFA_Object* pOriginalObject = ToObject(pOriginalValue);
+FXJSE_ClassPropType CFXJSE_Engine::GlobalPropTypeGetter(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pHolder,
+ ByteStringView szPropName,
+ bool bQueryIn) {
+ CXFA_Object* pObject = ToObject(pIsolate, pHolder);
+ if (!pObject)
+ return FXJSE_ClassPropType::kNone;
+
+ CFXJSE_Engine* pScriptContext = pObject->GetDocument()->GetScriptContext();
+ pObject = pScriptContext->GetVariablesThis(pObject);
+ WideString wsPropName = WideString::FromUTF8(szPropName);
+ if (pObject->JSObject()->HasMethod(wsPropName))
+ return FXJSE_ClassPropType::kMethod;
+
+ return FXJSE_ClassPropType::kProperty;
+}
+
+// static
+v8::Local<v8::Value> CFXJSE_Engine::NormalPropertyGetter(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pHolder,
+ ByteStringView szPropName) {
+ CXFA_Object* pOriginalObject = ToObject(pIsolate, pHolder);
if (!pOriginalObject)
- return;
+ return fxv8::NewUndefinedHelper(pIsolate);
+
+ CFXJSE_Engine* pScriptContext =
+ pOriginalObject->GetDocument()->GetScriptContext();
WideString wsPropName = WideString::FromUTF8(szPropName);
- CFXJSE_Engine* lpScriptContext =
- pOriginalObject->GetDocument()->GetScriptContext();
- CXFA_Object* pObject =
- lpScriptContext->GetVariablesThis(pOriginalObject, false);
if (wsPropName.EqualsASCII("xfa")) {
- CFXJSE_Value* pValue = lpScriptContext->GetOrCreateJSBindingFromMap(
- lpScriptContext->GetDocument()->GetRoot());
- pReturnValue->Assign(pValue);
- return;
+ return pScriptContext->GetOrCreateJSBindingFromMap(
+ pScriptContext->GetDocument()->GetRoot());
}
- bool bRet = lpScriptContext->QueryNodeByFlag(
- ToNode(pObject), wsPropName.AsStringView(), pReturnValue,
- XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
- XFA_RESOLVENODE_Attributes,
- false);
- if (bRet)
- return;
-
- if (pObject == lpScriptContext->GetThisObject() ||
- (lpScriptContext->GetType() == CXFA_Script::Type::Javascript &&
- !lpScriptContext->IsStrictScopeInJavaScript())) {
- bRet = lpScriptContext->QueryNodeByFlag(
- ToNode(pObject), wsPropName.AsStringView(), pReturnValue,
- XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings, false);
+ v8::Local<v8::Value> pReturnValue = fxv8::NewUndefinedHelper(pIsolate);
+ CXFA_Object* pObject = pScriptContext->GetVariablesThis(pOriginalObject);
+ CXFA_Node* pRefNode = ToNode(pObject);
+ if (pScriptContext->QueryNodeByFlag(
+ pRefNode, wsPropName.AsStringView(), &pReturnValue,
+ Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kChildren,
+ XFA_ResolveFlag::kProperties,
+ XFA_ResolveFlag::kAttributes})) {
+ return pReturnValue;
}
- if (bRet)
- return;
-
+ if (pObject == pScriptContext->GetThisObject() ||
+ (pScriptContext->GetType() == CXFA_Script::Type::Javascript &&
+ !pScriptContext->IsStrictScopeInJavaScript())) {
+ if (pScriptContext->QueryNodeByFlag(
+ pRefNode, wsPropName.AsStringView(), &pReturnValue,
+ Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kParent,
+ XFA_ResolveFlag::kSiblings})) {
+ return pReturnValue;
+ }
+ }
CXFA_Object* pScriptObject =
- lpScriptContext->GetVariablesThis(pOriginalObject, true);
+ pScriptContext->GetVariablesScript(pOriginalObject);
if (!pScriptObject)
- return;
+ return pReturnValue;
- bRet = lpScriptContext->QueryVariableValue(ToNode(pScriptObject), szPropName,
- pReturnValue, true);
- if (bRet)
- return;
-
- Optional<XFA_SCRIPTATTRIBUTEINFO> info = XFA_GetScriptAttributeByName(
+ if (pScriptContext->QueryVariableValue(
+ CXFA_Script::FromNode(pScriptObject->AsNode()), szPropName,
+ &pReturnValue)) {
+ return pReturnValue;
+ }
+ absl::optional<XFA_SCRIPTATTRIBUTEINFO> info = XFA_GetScriptAttributeByName(
pObject->GetElementType(), wsPropName.AsStringView());
if (info.has_value()) {
- CJX_Object* jsObject = pObject->JSObject();
- (*info.value().callback)(jsObject, pReturnValue, false,
- info.value().attribute);
- return;
+ (*info.value().callback)(pIsolate, pObject->JSObject(), &pReturnValue,
+ false, info.value().attribute);
+ return pReturnValue;
}
CXFA_FFNotify* pNotify = pObject->GetDocument()->GetNotify();
if (!pNotify)
- return;
+ return pReturnValue;
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
- auto* pCJSRuntime =
- static_cast<CJS_Runtime*>(hDoc->GetDocEnvironment()->GetIJSRuntime(hDoc));
+ CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
+ auto* pCJSRuntime = static_cast<CJS_Runtime*>(hDoc->GetIJSRuntime());
if (!pCJSRuntime)
- return;
+ return pReturnValue;
- v8::HandleScope handle_scope(lpScriptContext->GetIsolate());
IJS_Runtime::ScopedEventContext pContext(pCJSRuntime);
- v8::Local<v8::Value> temp_local;
- if (!pCJSRuntime->GetValueByNameFromGlobalObject(szPropName, &temp_local))
- return;
+ v8::Local<v8::Value> temp_local =
+ pCJSRuntime->GetValueByNameFromGlobalObject(szPropName);
- if (temp_local.IsEmpty())
- return;
-
- pReturnValue->ForceSetValue(temp_local);
+ return !temp_local.IsEmpty() ? temp_local : pReturnValue;
}
// static
-void CFXJSE_Engine::NormalPropertySetter(CFXJSE_Value* pOriginalValue,
+void CFXJSE_Engine::NormalPropertySetter(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pHolder,
ByteStringView szPropName,
- CFXJSE_Value* pReturnValue) {
- CXFA_Object* pOriginalObject = ToObject(pOriginalValue);
+ v8::Local<v8::Value> pValue) {
+ CXFA_Object* pOriginalObject = ToObject(pIsolate, pHolder);
if (!pOriginalObject)
return;
- CFXJSE_Engine* lpScriptContext =
+ CFXJSE_Engine* pScriptContext =
pOriginalObject->GetDocument()->GetScriptContext();
- CXFA_Object* pObject =
- lpScriptContext->GetVariablesThis(pOriginalObject, false);
+ if (pScriptContext->IsResolvingNodes())
+ return;
+
+ CXFA_Object* pObject = pScriptContext->GetVariablesThis(pOriginalObject);
WideString wsPropName = WideString::FromUTF8(szPropName);
WideStringView wsPropNameView = wsPropName.AsStringView();
- Optional<XFA_SCRIPTATTRIBUTEINFO> info =
+ absl::optional<XFA_SCRIPTATTRIBUTEINFO> info =
XFA_GetScriptAttributeByName(pObject->GetElementType(), wsPropNameView);
if (info.has_value()) {
CJX_Object* jsObject = pObject->JSObject();
- (*info.value().callback)(jsObject, pReturnValue, true,
+ (*info.value().callback)(pIsolate, jsObject, &pValue, true,
info.value().attribute);
return;
}
@@ -430,7 +493,7 @@
info = XFA_GetScriptAttributeByName(pPropOrChild->GetElementType(),
L"{default}");
if (info.has_value()) {
- pPropOrChild->JSObject()->ScriptSomDefaultValue(pReturnValue, true,
+ pPropOrChild->JSObject()->ScriptSomDefaultValue(pIsolate, &pValue, true,
XFA_Attribute::Unknown);
return;
}
@@ -438,32 +501,36 @@
}
CXFA_Object* pScriptObject =
- lpScriptContext->GetVariablesThis(pOriginalObject, true);
+ pScriptContext->GetVariablesScript(pOriginalObject);
if (pScriptObject) {
- lpScriptContext->QueryVariableValue(ToNode(pScriptObject), szPropName,
- pReturnValue, false);
+ pScriptContext->UpdateVariableValue(
+ CXFA_Script::FromNode(pScriptObject->AsNode()), szPropName, pValue);
}
}
-int32_t CFXJSE_Engine::NormalPropTypeGetter(CFXJSE_Value* pOriginalValue,
- ByteStringView szPropName,
- bool bQueryIn) {
- CXFA_Object* pObject = ToObject(pOriginalValue);
+FXJSE_ClassPropType CFXJSE_Engine::NormalPropTypeGetter(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pHolder,
+ ByteStringView szPropName,
+ bool bQueryIn) {
+ CXFA_Object* pObject = ToObject(pIsolate, pHolder);
if (!pObject)
- return FXJSE_ClassPropType_None;
+ return FXJSE_ClassPropType::kNone;
- CFXJSE_Engine* lpScriptContext = pObject->GetDocument()->GetScriptContext();
- pObject = lpScriptContext->GetVariablesThis(pObject, false);
+ CFXJSE_Engine* pScriptContext = pObject->GetDocument()->GetScriptContext();
+ pObject = pScriptContext->GetVariablesThis(pObject);
XFA_Element eType = pObject->GetElementType();
WideString wsPropName = WideString::FromUTF8(szPropName);
if (pObject->JSObject()->HasMethod(wsPropName))
- return FXJSE_ClassPropType_Method;
+ return FXJSE_ClassPropType::kMethod;
- if (bQueryIn &&
- !XFA_GetScriptAttributeByName(eType, wsPropName.AsStringView())) {
- return FXJSE_ClassPropType_None;
+ if (bQueryIn) {
+ absl::optional<XFA_SCRIPTATTRIBUTEINFO> maybe_info =
+ XFA_GetScriptAttributeByName(eType, wsPropName.AsStringView());
+ if (!maybe_info.has_value())
+ return FXJSE_ClassPropType::kNone;
}
- return FXJSE_ClassPropType_Property;
+ return FXJSE_ClassPropType::kProperty;
}
CJS_Result CFXJSE_Engine::NormalMethodCall(
@@ -473,8 +540,8 @@
if (!pObject)
return CJS_Result::Failure(L"no Holder() present.");
- CFXJSE_Engine* lpScriptContext = pObject->GetDocument()->GetScriptContext();
- pObject = lpScriptContext->GetVariablesThis(pObject, false);
+ CFXJSE_Engine* pScriptContext = pObject->GetDocument()->GetScriptContext();
+ pObject = pScriptContext->GetVariablesThis(pObject);
std::vector<v8::Local<v8::Value>> parameters;
for (int i = 0; i < info.Length(); i++)
@@ -491,154 +558,184 @@
return m_eScriptType;
}
-CFXJSE_Context* CFXJSE_Engine::CreateVariablesContext(CXFA_Node* pScriptNode,
+void CFXJSE_Engine::AddObjectToUpArray(CXFA_Node* pNode) {
+ m_upObjectArray.push_back(pNode);
+}
+
+CXFA_Node* CFXJSE_Engine::LastObjectFromUpArray() {
+ return !m_upObjectArray.empty() ? m_upObjectArray.back() : nullptr;
+}
+
+CFXJSE_Context* CFXJSE_Engine::CreateVariablesContext(CXFA_Script* pScriptNode,
CXFA_Node* pSubform) {
if (!pScriptNode || !pSubform)
return nullptr;
- auto pNewContext =
- CFXJSE_Context::Create(GetIsolate(), &VariablesClassDescriptor,
- new CXFA_ThisProxy(pSubform, pScriptNode));
+ auto* proxy = cppgc::MakeGarbageCollected<CXFA_ThisProxy>(
+ pScriptNode->GetDocument()->GetHeap()->GetAllocationHandle(), pSubform,
+ pScriptNode);
+ auto pNewContext = CFXJSE_Context::Create(
+ GetIsolate(), &kVariablesClassDescriptor, proxy->JSObject(), proxy);
RemoveBuiltInObjs(pNewContext.get());
pNewContext->EnableCompatibleMode();
CFXJSE_Context* pResult = pNewContext.get();
- m_mapVariableToContext[pScriptNode] = std::move(pNewContext);
+ m_mapVariableToContext[pScriptNode->JSObject()] = std::move(pNewContext);
return pResult;
}
-CXFA_Object* CFXJSE_Engine::GetVariablesThis(CXFA_Object* pObject,
- bool bScriptNode) {
+CXFA_Object* CFXJSE_Engine::GetVariablesThis(CXFA_Object* pObject) {
CXFA_ThisProxy* pProxy = ToThisProxy(pObject);
- if (!pProxy)
- return pObject;
-
- return bScriptNode ? pProxy->GetScriptNode() : pProxy->GetThisNode();
+ return pProxy ? pProxy->GetThisNode() : pObject;
}
-bool CFXJSE_Engine::RunVariablesScript(CXFA_Node* pScriptNode) {
+CXFA_Object* CFXJSE_Engine::GetVariablesScript(CXFA_Object* pObject) {
+ CXFA_ThisProxy* pProxy = ToThisProxy(pObject);
+ return pProxy ? pProxy->GetScriptNode() : pObject;
+}
+
+void CFXJSE_Engine::RunVariablesScript(CXFA_Script* pScriptNode) {
if (!pScriptNode)
- return false;
+ return;
- if (pScriptNode->GetElementType() != XFA_Element::Script)
- return true;
+ auto* pParent = CXFA_Variables::FromNode(pScriptNode->GetParent());
+ if (!pParent)
+ return;
- CXFA_Node* pParent = pScriptNode->GetParent();
- if (!pParent || pParent->GetElementType() != XFA_Element::Variables)
- return false;
-
- auto it = m_mapVariableToContext.find(pScriptNode);
+ auto it = m_mapVariableToContext.find(pScriptNode->JSObject());
if (it != m_mapVariableToContext.end() && it->second)
- return true;
+ return;
CXFA_Node* pTextNode = pScriptNode->GetFirstChild();
if (!pTextNode)
- return false;
+ return;
- Optional<WideString> wsScript =
+ absl::optional<WideString> wsScript =
pTextNode->JSObject()->TryCData(XFA_Attribute::Value, true);
- if (!wsScript)
- return false;
+ if (!wsScript.has_value())
+ return;
ByteString btScript = wsScript->ToUTF8();
- auto hRetValue = pdfium::MakeUnique<CFXJSE_Value>(GetIsolate());
+ auto hRetValue = std::make_unique<CFXJSE_Value>();
CXFA_Node* pThisObject = pParent->GetParent();
CFXJSE_Context* pVariablesContext =
CreateVariablesContext(pScriptNode, pThisObject);
- AutoRestorer<UnownedPtr<CXFA_Object>> nodeRestorer(&m_pThisObject);
+ AutoRestorer<cppgc::Persistent<CXFA_Object>> nodeRestorer(&m_pThisObject);
m_pThisObject = pThisObject;
- return pVariablesContext->ExecuteScript(btScript.c_str(), hRetValue.get(),
- nullptr);
+ pVariablesContext->ExecuteScript(btScript.AsStringView(), hRetValue.get(),
+ v8::Local<v8::Object>());
}
-bool CFXJSE_Engine::QueryVariableValue(CXFA_Node* pScriptNode,
+CFXJSE_Context* CFXJSE_Engine::VariablesContextForScriptNode(
+ CXFA_Script* pScriptNode) {
+ if (!pScriptNode)
+ return nullptr;
+
+ auto* variablesNode = CXFA_Variables::FromNode(pScriptNode->GetParent());
+ if (!variablesNode)
+ return nullptr;
+
+ auto it = m_mapVariableToContext.find(pScriptNode->JSObject());
+ return it != m_mapVariableToContext.end() ? it->second.get() : nullptr;
+}
+
+bool CFXJSE_Engine::QueryVariableValue(CXFA_Script* pScriptNode,
ByteStringView szPropName,
- CFXJSE_Value* pValue,
- bool bGetter) {
- if (!pScriptNode || pScriptNode->GetElementType() != XFA_Element::Script)
+ v8::Local<v8::Value>* pValue) {
+ CFXJSE_Context* pVariableContext = VariablesContextForScriptNode(pScriptNode);
+ if (!pVariableContext)
return false;
- CXFA_Node* variablesNode = pScriptNode->GetParent();
- if (!variablesNode ||
- variablesNode->GetElementType() != XFA_Element::Variables)
+ v8::Local<v8::Object> pObject = pVariableContext->GetGlobalObject();
+ if (!fxv8::ReentrantHasObjectOwnPropertyHelper(GetIsolate(), pObject,
+ szPropName)) {
return false;
-
- auto it = m_mapVariableToContext.find(pScriptNode);
- if (it == m_mapVariableToContext.end() || !it->second)
- return false;
-
- CFXJSE_Context* pVariableContext = it->second.get();
- std::unique_ptr<CFXJSE_Value> pObject = pVariableContext->GetGlobalObject();
- auto hVariableValue = pdfium::MakeUnique<CFXJSE_Value>(GetIsolate());
- if (!bGetter) {
- pObject->SetObjectOwnProperty(szPropName, pValue);
- return true;
}
- if (!pObject->HasObjectOwnProperty(szPropName, false))
- return false;
-
- pObject->GetObjectProperty(szPropName, hVariableValue.get());
- if (hVariableValue->IsFunction())
- pValue->SetFunctionBind(hVariableValue.get(), pObject.get());
- else if (bGetter)
- pValue->Assign(hVariableValue.get());
- else
- hVariableValue.get()->Assign(pValue);
+ v8::Local<v8::Value> hVariableValue =
+ fxv8::ReentrantGetObjectPropertyHelper(GetIsolate(), pObject, szPropName);
+ if (fxv8::IsFunction(hVariableValue)) {
+ v8::Local<v8::Function> maybeFunc = CFXJSE_Value::NewBoundFunction(
+ GetIsolate(), hVariableValue.As<v8::Function>(), pObject);
+ if (!maybeFunc.IsEmpty())
+ *pValue = maybeFunc;
+ } else {
+ *pValue = hVariableValue;
+ }
return true;
}
-void CFXJSE_Engine::RemoveBuiltInObjs(CFXJSE_Context* pContext) const {
- const ByteStringView kObjNames[2] = {"Number", "Date"};
- std::unique_ptr<CFXJSE_Value> pObject = pContext->GetGlobalObject();
- auto hProp = pdfium::MakeUnique<CFXJSE_Value>(GetIsolate());
- for (const auto& obj : kObjNames) {
- if (pObject->GetObjectProperty(obj, hProp.get()))
- pObject->DeleteObjectProperty(obj);
- }
-}
-
-bool CFXJSE_Engine::ResolveObjects(CXFA_Object* refObject,
- WideStringView wsExpression,
- XFA_RESOLVENODE_RS* resolveNodeRS,
- uint32_t dwStyles,
- CXFA_Node* bindNode) {
- if (wsExpression.IsEmpty())
+bool CFXJSE_Engine::UpdateVariableValue(CXFA_Script* pScriptNode,
+ ByteStringView szPropName,
+ v8::Local<v8::Value> pValue) {
+ CFXJSE_Context* pVariableContext = VariablesContextForScriptNode(pScriptNode);
+ if (!pVariableContext)
return false;
- if (m_eScriptType != CXFA_Script::Type::Formcalc ||
- (dwStyles & (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings))) {
+ v8::Local<v8::Object> pObject = pVariableContext->GetGlobalObject();
+ fxv8::ReentrantSetObjectOwnPropertyHelper(GetIsolate(), pObject, szPropName,
+ pValue);
+ return true;
+}
+
+void CFXJSE_Engine::RemoveBuiltInObjs(CFXJSE_Context* pContext) {
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
+ v8::Local<v8::Object> pObject = pContext->GetGlobalObject();
+ fxv8::ReentrantDeleteObjectPropertyHelper(GetIsolate(), pObject, "Number");
+ fxv8::ReentrantDeleteObjectPropertyHelper(GetIsolate(), pObject, "Date");
+}
+
+absl::optional<CFXJSE_Engine::ResolveResult> CFXJSE_Engine::ResolveObjects(
+ CXFA_Object* refObject,
+ WideStringView wsExpression,
+ Mask<XFA_ResolveFlag> dwStyles) {
+ return ResolveObjectsWithBindNode(refObject, wsExpression, dwStyles, nullptr);
+}
+
+absl::optional<CFXJSE_Engine::ResolveResult>
+CFXJSE_Engine::ResolveObjectsWithBindNode(CXFA_Object* refObject,
+ WideStringView wsExpression,
+ Mask<XFA_ResolveFlag> dwStyles,
+ CXFA_Node* bindNode) {
+ if (wsExpression.IsEmpty())
+ return absl::nullopt;
+
+ AutoRestorer<bool> resolving_restorer(&m_bResolvingNodes);
+ m_bResolvingNodes = true;
+
+ const bool bParentOrSiblings =
+ !!(dwStyles & Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kParent,
+ XFA_ResolveFlag::kSiblings});
+ if (m_eScriptType != CXFA_Script::Type::Formcalc || bParentOrSiblings)
m_upObjectArray.clear();
- }
- if (refObject && refObject->IsNode() &&
- (dwStyles & (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings))) {
+ if (refObject && refObject->IsNode() && bParentOrSiblings)
m_upObjectArray.push_back(refObject->AsNode());
- }
+ ResolveResult result;
bool bNextCreate = false;
- CXFA_NodeHelper* pNodeHelper = m_ResolveProcessor->GetNodeHelper();
- if (dwStyles & XFA_RESOLVENODE_CreateNode)
- pNodeHelper->SetCreateNodeType(bindNode);
+ if (dwStyles & XFA_ResolveFlag::kCreateNode)
+ m_NodeHelper->SetCreateNodeType(bindNode);
- pNodeHelper->m_pCreateParent = nullptr;
- pNodeHelper->m_iCurAllStart = -1;
+ m_NodeHelper->m_pCreateParent = nullptr;
+ m_NodeHelper->m_iCurAllStart = -1;
- CFXJSE_ResolveNodeData rndFind(this);
+ CFXJSE_ResolveProcessor::NodeData rndFind;
int32_t nStart = 0;
int32_t nLevel = 0;
- std::vector<UnownedPtr<CXFA_Object>> findObjects;
+ std::vector<cppgc::Member<CXFA_Object>> findObjects;
findObjects.emplace_back(refObject ? refObject : m_pDocument->GetRoot());
int32_t nNodes = 0;
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
while (true) {
- nNodes = pdfium::CollectionSize<int32_t>(findObjects);
+ nNodes = fxcrt::CollectionSize<int32_t>(findObjects);
int32_t i = 0;
rndFind.m_dwStyles = dwStyles;
m_ResolveProcessor->SetCurStart(nStart);
nStart = m_ResolveProcessor->GetFilter(wsExpression, nStart, rndFind);
if (nStart < 1) {
- if ((dwStyles & XFA_RESOLVENODE_CreateNode) && !bNextCreate) {
+ if ((dwStyles & XFA_ResolveFlag::kCreateNode) && !bNextCreate) {
CXFA_Node* pDataNode = nullptr;
- nStart = pNodeHelper->m_iCurAllStart;
+ nStart = m_NodeHelper->m_iCurAllStart;
if (nStart != -1) {
pDataNode = m_pDocument->GetNotBindNode(findObjects);
if (pDataNode) {
@@ -652,9 +749,9 @@
findObjects.emplace_back(pDataNode);
break;
}
- dwStyles |= XFA_RESOLVENODE_Bind;
+ dwStyles |= XFA_ResolveFlag::kBind;
findObjects.clear();
- findObjects.emplace_back(pNodeHelper->m_pAllStartParent.Get());
+ findObjects.emplace_back(m_NodeHelper->m_pAllStartParent.Get());
continue;
}
break;
@@ -662,62 +759,64 @@
if (bNextCreate) {
int32_t checked_length =
pdfium::base::checked_cast<int32_t>(wsExpression.GetLength());
- if (pNodeHelper->CreateNode(rndFind.m_wsName, rndFind.m_wsCondition,
- nStart == checked_length, this)) {
+ if (m_NodeHelper->CreateNode(rndFind.m_wsName, rndFind.m_wsCondition,
+ nStart == checked_length, this)) {
continue;
}
break;
}
- std::vector<UnownedPtr<CXFA_Object>> retObjects;
+ std::vector<cppgc::Member<CXFA_Object>> retObjects;
while (i < nNodes) {
bool bDataBind = false;
- if (((dwStyles & XFA_RESOLVENODE_Bind) ||
- (dwStyles & XFA_RESOLVENODE_CreateNode)) &&
+ if (((dwStyles & XFA_ResolveFlag::kBind) ||
+ (dwStyles & XFA_ResolveFlag::kCreateNode)) &&
nNodes > 1) {
- CFXJSE_ResolveNodeData rndBind(nullptr);
+ CFXJSE_ResolveProcessor::NodeData rndBind;
m_ResolveProcessor->GetFilter(wsExpression, nStart, rndBind);
- m_ResolveProcessor->SetIndexDataBind(rndBind.m_wsCondition, i, nNodes);
+ i = m_ResolveProcessor->IndexForDataBind(rndBind.m_wsCondition, nNodes);
bDataBind = true;
}
rndFind.m_CurObject = findObjects[i++].Get();
rndFind.m_nLevel = nLevel;
- rndFind.m_dwFlag = XFA_ResolveNode_RSType_Nodes;
- if (!m_ResolveProcessor->Resolve(rndFind))
+ rndFind.m_Result.type = ResolveResult::Type::kNodes;
+ if (!m_ResolveProcessor->Resolve(GetIsolate(), rndFind))
continue;
- if (rndFind.m_dwFlag == XFA_ResolveNode_RSType_Attribute &&
- rndFind.m_ScriptAttribute.callback &&
+ if (rndFind.m_Result.type == ResolveResult::Type::kAttribute &&
+ rndFind.m_Result.script_attribute.callback &&
nStart <
pdfium::base::checked_cast<int32_t>(wsExpression.GetLength())) {
- auto pValue = pdfium::MakeUnique<CFXJSE_Value>(GetIsolate());
- CJX_Object* jsObject = rndFind.m_Objects.front()->JSObject();
- (*rndFind.m_ScriptAttribute.callback)(
- jsObject, pValue.get(), false, rndFind.m_ScriptAttribute.attribute);
- if (!pValue->IsEmpty())
- rndFind.m_Objects.front() = ToObject(pValue.get());
+ v8::Local<v8::Value> pValue;
+ CJX_Object* jsObject = rndFind.m_Result.objects.front()->JSObject();
+ (*rndFind.m_Result.script_attribute.callback)(
+ GetIsolate(), jsObject, &pValue, false,
+ rndFind.m_Result.script_attribute.attribute);
+ if (!pValue.IsEmpty()) {
+ rndFind.m_Result.objects.front() = ToObject(GetIsolate(), pValue);
+ }
}
if (!m_upObjectArray.empty())
m_upObjectArray.pop_back();
- retObjects.insert(retObjects.end(), rndFind.m_Objects.begin(),
- rndFind.m_Objects.end());
- rndFind.m_Objects.clear();
+ retObjects.insert(retObjects.end(), rndFind.m_Result.objects.begin(),
+ rndFind.m_Result.objects.end());
+ rndFind.m_Result.objects.clear();
if (bDataBind)
break;
}
findObjects.clear();
- nNodes = pdfium::CollectionSize<int32_t>(retObjects);
+ nNodes = fxcrt::CollectionSize<int32_t>(retObjects);
if (nNodes < 1) {
- if (dwStyles & XFA_RESOLVENODE_CreateNode) {
+ if (dwStyles & XFA_ResolveFlag::kCreateNode) {
bNextCreate = true;
- if (!pNodeHelper->m_pCreateParent) {
- pNodeHelper->m_pCreateParent = ToNode(rndFind.m_CurObject.Get());
- pNodeHelper->m_iCreateCount = 1;
+ if (!m_NodeHelper->m_pCreateParent) {
+ m_NodeHelper->m_pCreateParent = ToNode(rndFind.m_CurObject);
+ m_NodeHelper->m_iCreateCount = 1;
}
int32_t checked_length =
pdfium::base::checked_cast<int32_t>(wsExpression.GetLength());
- if (pNodeHelper->CreateNode(rndFind.m_wsName, rndFind.m_wsCondition,
- nStart == checked_length, this)) {
+ if (m_NodeHelper->CreateNode(rndFind.m_wsName, rndFind.m_wsCondition,
+ nStart == checked_length, this)) {
continue;
}
}
@@ -725,101 +824,95 @@
}
findObjects = std::move(retObjects);
- rndFind.m_Objects.clear();
- if (nLevel == 0)
- dwStyles &= ~(XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings);
-
+ rndFind.m_Result.objects.clear();
+ if (nLevel == 0) {
+ dwStyles.Clear(XFA_ResolveFlag::kParent);
+ dwStyles.Clear(XFA_ResolveFlag::kSiblings);
+ }
nLevel++;
}
if (!bNextCreate) {
- resolveNodeRS->dwFlags = rndFind.m_dwFlag;
+ result.type = rndFind.m_Result.type;
if (nNodes > 0) {
- resolveNodeRS->objects.insert(resolveNodeRS->objects.end(),
- findObjects.begin(), findObjects.end());
+ result.objects.insert(result.objects.end(), findObjects.begin(),
+ findObjects.end());
}
- if (rndFind.m_dwFlag == XFA_ResolveNode_RSType_Attribute) {
- resolveNodeRS->script_attribute = rndFind.m_ScriptAttribute;
- return true;
+ if (rndFind.m_Result.type == ResolveResult::Type::kAttribute) {
+ result.script_attribute = rndFind.m_Result.script_attribute;
+ return result;
}
}
- if (dwStyles & (XFA_RESOLVENODE_CreateNode | XFA_RESOLVENODE_Bind |
- XFA_RESOLVENODE_BindNew)) {
- if (pNodeHelper->m_pCreateParent)
- resolveNodeRS->objects.emplace_back(pNodeHelper->m_pCreateParent.Get());
+ if ((dwStyles & XFA_ResolveFlag::kCreateNode) ||
+ (dwStyles & XFA_ResolveFlag::kBind) ||
+ (dwStyles & XFA_ResolveFlag::kBindNew)) {
+ if (m_NodeHelper->m_pCreateParent)
+ result.objects.emplace_back(m_NodeHelper->m_pCreateParent.Get());
else
- pNodeHelper->CreateNodeForCondition(rndFind.m_wsCondition);
+ m_NodeHelper->CreateNodeForCondition(rndFind.m_wsCondition);
- resolveNodeRS->dwFlags = pNodeHelper->m_iCreateFlag;
- if (resolveNodeRS->dwFlags == XFA_ResolveNode_RSType_CreateNodeOne) {
- if (pNodeHelper->m_iCurAllStart != -1)
- resolveNodeRS->dwFlags = XFA_ResolveNode_RSType_CreateNodeMidAll;
+ result.type = m_NodeHelper->m_iCreateFlag;
+ if (result.type == ResolveResult::Type::kCreateNodeOne) {
+ if (m_NodeHelper->m_iCurAllStart != -1)
+ result.type = ResolveResult::Type::kCreateNodeMidAll;
}
- if (!bNextCreate && (dwStyles & XFA_RESOLVENODE_CreateNode))
- resolveNodeRS->dwFlags = XFA_ResolveNode_RSType_ExistNodes;
+ if (!bNextCreate && (dwStyles & XFA_ResolveFlag::kCreateNode))
+ result.type = ResolveResult::Type::kExistNodes;
- return !resolveNodeRS->objects.empty();
+ if (result.objects.empty())
+ return absl::nullopt;
+
+ return result;
}
- return nNodes > 0;
+ if (nNodes == 0)
+ return absl::nullopt;
+
+ return result;
}
-void CFXJSE_Engine::AddToCacheList(std::unique_ptr<CXFA_List> pList) {
- m_CacheList.push_back(std::move(pList));
+v8::Local<v8::Object> CFXJSE_Engine::GetOrCreateJSBindingFromMap(
+ CXFA_Object* pObject) {
+ RunVariablesScript(CXFA_Script::FromNode(pObject->AsNode()));
+
+ CJX_Object* pCJXObject = pObject->JSObject();
+ auto iter = m_mapObjectToObject.find(pCJXObject);
+ if (iter != m_mapObjectToObject.end())
+ return v8::Local<v8::Object>::New(GetIsolate(), iter->second);
+
+ v8::Local<v8::Object> binding = pCJXObject->NewBoundV8Object(
+ GetIsolate(), m_pJsClass->GetTemplate(GetIsolate()));
+
+ m_mapObjectToObject[pCJXObject].Reset(GetIsolate(), binding);
+ return binding;
}
-CFXJSE_Value* CFXJSE_Engine::GetOrCreateJSBindingFromMap(CXFA_Object* pObject) {
- if (pObject->IsNode())
- RunVariablesScript(pObject->AsNode());
-
- auto iter = m_mapObjectToValue.find(pObject);
- if (iter != m_mapObjectToValue.end())
- return iter->second.get();
-
- auto jsValue = pdfium::MakeUnique<CFXJSE_Value>(GetIsolate());
- jsValue->SetHostObject(pObject, m_pJsClass.Get());
-
- CFXJSE_Value* pValue = jsValue.get();
- m_mapObjectToValue.insert(std::make_pair(pObject, std::move(jsValue)));
- return pValue;
-}
-
-void CFXJSE_Engine::RemoveJSBindingFromMap(CXFA_Object* pObject) {
- auto iter = m_mapObjectToValue.find(pObject);
- if (iter == m_mapObjectToValue.end())
- return;
-
- iter->second->ClearHostObject();
- m_mapObjectToValue.erase(iter);
-}
-
-void CFXJSE_Engine::SetNodesOfRunScript(std::vector<CXFA_Node*>* pArray) {
+void CFXJSE_Engine::SetNodesOfRunScript(
+ std::vector<cppgc::Persistent<CXFA_Node>>* pArray) {
m_pScriptNodeArray = pArray;
}
void CFXJSE_Engine::AddNodesOfRunScript(CXFA_Node* pNode) {
- if (m_pScriptNodeArray && !pdfium::ContainsValue(*m_pScriptNodeArray, pNode))
- m_pScriptNodeArray->push_back(pNode);
+ if (m_pScriptNodeArray && !pdfium::Contains(*m_pScriptNodeArray, pNode))
+ m_pScriptNodeArray->emplace_back(pNode);
}
CXFA_Object* CFXJSE_Engine::ToXFAObject(v8::Local<v8::Value> obj) {
- if (obj.IsEmpty() || !obj->IsObject())
+ if (!fxv8::IsObject(obj))
return nullptr;
CFXJSE_HostObject* pHostObj =
FXJSE_RetrieveObjectBinding(obj.As<v8::Object>());
- return pHostObj ? pHostObj->AsCXFAObject() : nullptr;
+ if (!pHostObj)
+ return nullptr;
+
+ CJX_Object* pJSObject = pHostObj->AsCJXObject();
+ return pJSObject ? pJSObject->GetXFAObject() : nullptr;
}
-v8::Local<v8::Value> CFXJSE_Engine::NewXFAObject(
- CXFA_Object* obj,
- v8::Global<v8::FunctionTemplate>& tmpl) {
+v8::Local<v8::Object> CFXJSE_Engine::NewNormalXFAObject(CXFA_Object* obj) {
v8::EscapableHandleScope scope(GetIsolate());
- v8::Local<v8::FunctionTemplate> klass =
- v8::Local<v8::FunctionTemplate>::New(GetIsolate(), tmpl);
- v8::Local<v8::Object> object = klass->InstanceTemplate()
- ->NewInstance(m_JsContext->GetContext())
- .ToLocalChecked();
- FXJSE_UpdateObjectBinding(object, obj);
+ v8::Local<v8::Object> object = obj->JSObject()->NewBoundV8Object(
+ GetIsolate(), GetJseNormalClass()->GetTemplate(GetIsolate()));
return scope.Escape(object);
}
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h
index addf0cc..c6a95c3 100644
--- a/fxjs/xfa/cfxjse_engine.h
+++ b/fxjs/xfa/cfxjse_engine.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,133 +9,210 @@
#include <map>
#include <memory>
+#include <type_traits>
#include <vector>
+#include "core/fxcrt/mask.h"
#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/cfx_v8.h"
-#include "v8/include/v8.h"
+#include "v8/include/cppgc/persistent.h"
+#include "v8/include/v8-forward.h"
+#include "v8/include/v8-persistent-handle.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_script.h"
-#include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
+#include "xfa/fxfa/parser/xfa_basic_data.h"
class CFXJSE_Class;
class CFXJSE_Context;
class CFXJSE_FormCalcContext;
+class CFXJSE_HostObject;
+class CFXJSE_NodeHelper;
class CFXJSE_ResolveProcessor;
+class CFXJSE_Value;
class CJS_Runtime;
-class CXFA_List;
-// Flags for |dwStyles| argument to CFXJSE_Engine::ResolveObjects().
-#define XFA_RESOLVENODE_Children 0x0001
-#define XFA_RESOLVENODE_TagName 0x0002
-#define XFA_RESOLVENODE_Attributes 0x0004
-#define XFA_RESOLVENODE_Properties 0x0008
-#define XFA_RESOLVENODE_Siblings 0x0020
-#define XFA_RESOLVENODE_Parent 0x0040
-#define XFA_RESOLVENODE_AnyChild 0x0080
-#define XFA_RESOLVENODE_ALL 0x0100
-#define XFA_RESOLVENODE_CreateNode 0x0400
-#define XFA_RESOLVENODE_Bind 0x0800
-#define XFA_RESOLVENODE_BindNew 0x1000
+enum class XFA_ResolveFlag : uint16_t {
+ kChildren = 1 << 0,
+ kTagName = 1 << 1,
+ kAttributes = 1 << 2,
+ kProperties = 1 << 3,
+ kSiblings = 1 << 5,
+ kParent = 1 << 6,
+ kAnyChild = 1 << 7,
+ kALL = 1 << 8,
+ kCreateNode = 1 << 10,
+ kBind = 1 << 11,
+ kBindNew = 1 << 12,
+};
class CFXJSE_Engine final : public CFX_V8 {
public:
+ class ResolveResult {
+ CPPGC_STACK_ALLOCATED(); // Allow raw/unowned pointers.
+
+ public:
+ enum class Type {
+ kNodes = 0,
+ kAttribute,
+ kCreateNodeOne,
+ kCreateNodeAll,
+ kCreateNodeMidAll,
+ kExistNodes,
+ };
+
+ ResolveResult();
+ ResolveResult(const ResolveResult& that);
+ ResolveResult& operator=(const ResolveResult& that);
+ ~ResolveResult();
+
+ Type type = Type::kNodes;
+ XFA_SCRIPTATTRIBUTEINFO script_attribute = {};
+
+ // Vector of Member would be correct for stack-based vectors, if
+ // STL worked with cppgc.
+ std::vector<cppgc::Member<CXFA_Object>> objects;
+ };
+
static CXFA_Object* ToObject(const v8::FunctionCallbackInfo<v8::Value>& info);
- static CXFA_Object* ToObject(CFXJSE_Value* pValue);
- static void GlobalPropertyGetter(CFXJSE_Value* pObject,
+ static CXFA_Object* ToObject(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> value);
+ static CXFA_Object* ToObject(v8::Isolate* pIsolate, CFXJSE_Value* pValue);
+ static CXFA_Object* ToObject(CFXJSE_HostObject* pHostObj);
+ static v8::Local<v8::Value> GlobalPropertyGetter(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
+ ByteStringView szPropName);
+ static void GlobalPropertySetter(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
ByteStringView szPropName,
- CFXJSE_Value* pValue);
- static void GlobalPropertySetter(CFXJSE_Value* pObject,
+ v8::Local<v8::Value> pValue);
+ static v8::Local<v8::Value> NormalPropertyGetter(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
+ ByteStringView szPropName);
+ static void NormalPropertySetter(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
ByteStringView szPropName,
- CFXJSE_Value* pValue);
- static void NormalPropertyGetter(CFXJSE_Value* pObject,
- ByteStringView szPropName,
- CFXJSE_Value* pValue);
- static void NormalPropertySetter(CFXJSE_Value* pObject,
- ByteStringView szPropName,
- CFXJSE_Value* pValue);
+ v8::Local<v8::Value> pValue);
static CJS_Result NormalMethodCall(
const v8::FunctionCallbackInfo<v8::Value>& info,
const WideString& functionName);
- static int32_t NormalPropTypeGetter(CFXJSE_Value* pObject,
- ByteStringView szPropName,
- bool bQueryIn);
- static int32_t GlobalPropTypeGetter(CFXJSE_Value* pObject,
- ByteStringView szPropName,
- bool bQueryIn);
+ static FXJSE_ClassPropType NormalPropTypeGetter(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
+ ByteStringView szPropName,
+ bool bQueryIn);
+ static FXJSE_ClassPropType GlobalPropTypeGetter(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
+ ByteStringView szPropName,
+ bool bQueryIn);
CFXJSE_Engine(CXFA_Document* pDocument, CJS_Runtime* fxjs_runtime);
~CFXJSE_Engine() override;
- void SetEventParam(CXFA_EventParam* param) { m_eventParam = param; }
- CXFA_EventParam* GetEventParam() const { return m_eventParam.Get(); }
+ class EventParamScope {
+ CPPGC_STACK_ALLOCATED();
+
+ public:
+ EventParamScope(CFXJSE_Engine* pEngine,
+ CXFA_Node* pTarget,
+ CXFA_EventParam* pEventParam);
+ ~EventParamScope();
+
+ private:
+ UnownedPtr<CFXJSE_Engine> m_pEngine;
+ UnownedPtr<CXFA_Node> m_pPrevTarget;
+ UnownedPtr<CXFA_EventParam> m_pPrevEventParam;
+ };
+ friend class EventParamScope;
+
+ CXFA_Node* GetEventTarget() const { return m_pTarget; }
+ CXFA_EventParam* GetEventParam() const { return m_eventParam; }
bool RunScript(CXFA_Script::Type eScriptType,
WideStringView wsScript,
CFXJSE_Value* pRetValue,
CXFA_Object* pThisObject);
- bool ResolveObjects(CXFA_Object* refObject,
- WideStringView wsExpression,
- XFA_RESOLVENODE_RS* resolveNodeRS,
- uint32_t dwStyles,
- CXFA_Node* bindNode);
+ absl::optional<ResolveResult> ResolveObjects(CXFA_Object* refObject,
+ WideStringView wsExpression,
+ Mask<XFA_ResolveFlag> dwStyles);
- CFXJSE_Value* GetOrCreateJSBindingFromMap(CXFA_Object* pObject);
- void RemoveJSBindingFromMap(CXFA_Object* pObject);
+ absl::optional<ResolveResult> ResolveObjectsWithBindNode(
+ CXFA_Object* refObject,
+ WideStringView wsExpression,
+ Mask<XFA_ResolveFlag> dwStyles,
+ CXFA_Node* bindNode);
- void AddToCacheList(std::unique_ptr<CXFA_List> pList);
- CXFA_Object* GetThisObject() const { return m_pThisObject.Get(); }
+ v8::Local<v8::Object> GetOrCreateJSBindingFromMap(CXFA_Object* pObject);
- void SetNodesOfRunScript(std::vector<CXFA_Node*>* pArray);
+ CXFA_Object* GetThisObject() const { return m_pThisObject; }
+ CFXJSE_Class* GetJseNormalClass() const { return m_pJsClass; }
+ CXFA_Document* GetDocument() const { return m_pDocument.Get(); }
+
+ void SetNodesOfRunScript(std::vector<cppgc::Persistent<CXFA_Node>>* pArray);
void AddNodesOfRunScript(CXFA_Node* pNode);
- CFXJSE_Class* GetJseNormalClass() const { return m_pJsClass.Get(); }
void SetRunAtType(XFA_AttributeValue eRunAt) { m_eRunAtType = eRunAt; }
bool IsRunAtClient() { return m_eRunAtType != XFA_AttributeValue::Server; }
CXFA_Script::Type GetType();
- std::vector<CXFA_Node*>* GetUpObjectArray() { return &m_upObjectArray; }
- CXFA_Document* GetDocument() const { return m_pDocument.Get(); }
+
+ void AddObjectToUpArray(CXFA_Node* pNode);
+ CXFA_Node* LastObjectFromUpArray();
CXFA_Object* ToXFAObject(v8::Local<v8::Value> obj);
- v8::Local<v8::Value> NewXFAObject(CXFA_Object* obj,
- v8::Global<v8::FunctionTemplate>& tmpl);
+ v8::Local<v8::Object> NewNormalXFAObject(CXFA_Object* obj);
+
+ bool IsResolvingNodes() const { return m_bResolvingNodes; }
+
+ CFXJSE_Context* GetJseContextForTest() const { return GetJseContext(); }
private:
- CFXJSE_Context* CreateVariablesContext(CXFA_Node* pScriptNode,
+ CFXJSE_Context* GetJseContext() const { return m_JsContext.get(); }
+ CFXJSE_Context* CreateVariablesContext(CXFA_Script* pScriptNode,
CXFA_Node* pSubform);
- void RemoveBuiltInObjs(CFXJSE_Context* pContext) const;
+ void RemoveBuiltInObjs(CFXJSE_Context* pContext);
bool QueryNodeByFlag(CXFA_Node* refNode,
WideStringView propname,
- CFXJSE_Value* pValue,
- uint32_t dwFlag,
- bool bSetting);
+ v8::Local<v8::Value>* pValue,
+ Mask<XFA_ResolveFlag> dwFlag);
+ bool UpdateNodeByFlag(CXFA_Node* refNode,
+ WideStringView propname,
+ v8::Local<v8::Value> pValue,
+ Mask<XFA_ResolveFlag> dwFlag);
bool IsStrictScopeInJavaScript();
- CXFA_Object* GetVariablesThis(CXFA_Object* pObject, bool bScriptNode);
- bool QueryVariableValue(CXFA_Node* pScriptNode,
+ CXFA_Object* GetVariablesThis(CXFA_Object* pObject);
+ CXFA_Object* GetVariablesScript(CXFA_Object* pObject);
+ CFXJSE_Context* VariablesContextForScriptNode(CXFA_Script* pScriptNode);
+ bool QueryVariableValue(CXFA_Script* pScriptNode,
ByteStringView szPropName,
- CFXJSE_Value* pValue,
- bool bGetter);
- bool RunVariablesScript(CXFA_Node* pScriptNode);
+ v8::Local<v8::Value>* pValue);
+ bool UpdateVariableValue(CXFA_Script* pScriptNode,
+ ByteStringView szPropName,
+ v8::Local<v8::Value> pValue);
+ void RunVariablesScript(CXFA_Script* pScriptNode);
UnownedPtr<CJS_Runtime> const m_pSubordinateRuntime;
- UnownedPtr<CXFA_Document> const m_pDocument;
+ cppgc::WeakPersistent<CXFA_Document> const m_pDocument;
std::unique_ptr<CFXJSE_Context> m_JsContext;
UnownedPtr<CFXJSE_Class> m_pJsClass;
CXFA_Script::Type m_eScriptType = CXFA_Script::Type::Unknown;
- std::map<CXFA_Object*, std::unique_ptr<CFXJSE_Value>> m_mapObjectToValue;
- std::map<CXFA_Object*, std::unique_ptr<CFXJSE_Context>>
+ // |m_mapObjectToValue| is what ensures the v8 object bound to a
+ // CJX_Object remains valid for the lifetime of the engine.
+ std::map<cppgc::Persistent<CJX_Object>, v8::Global<v8::Object>>
+ m_mapObjectToObject;
+ std::map<cppgc::Persistent<CJX_Object>, std::unique_ptr<CFXJSE_Context>>
m_mapVariableToContext;
+ cppgc::Persistent<CXFA_Node> m_pTarget;
UnownedPtr<CXFA_EventParam> m_eventParam;
- std::vector<CXFA_Node*> m_upObjectArray;
- // CacheList holds the List items so we can clean them up when we're done.
- std::vector<std::unique_ptr<CXFA_List>> m_CacheList;
- UnownedPtr<std::vector<CXFA_Node*>> m_pScriptNodeArray;
+ std::vector<cppgc::Persistent<CXFA_Node>> m_upObjectArray;
+ UnownedPtr<std::vector<cppgc::Persistent<CXFA_Node>>> m_pScriptNodeArray;
+ std::unique_ptr<CFXJSE_NodeHelper> const m_NodeHelper;
std::unique_ptr<CFXJSE_ResolveProcessor> const m_ResolveProcessor;
- std::unique_ptr<CFXJSE_FormCalcContext> m_FM2JSContext;
- UnownedPtr<CXFA_Object> m_pThisObject;
+ std::unique_ptr<CFXJSE_FormCalcContext> m_FormCalcContext;
+ cppgc::Persistent<CXFA_Object> m_pThisObject;
XFA_AttributeValue m_eRunAtType = XFA_AttributeValue::Client;
+ bool m_bResolvingNodes = false;
};
#endif // FXJS_XFA_CFXJSE_ENGINE_H_
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index 7a6796c..4fc19d7 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,31 +6,47 @@
#include "fxjs/xfa/cfxjse_formcalc_context.h"
-#include <algorithm>
-#include <cstdlib>
-#include <string>
-#include <utility>
+#include <ctype.h>
+#include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
-#include "core/fxcrt/cfx_widetextbuf.h"
+#include <algorithm>
+#include <limits>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "core/fxcrt/cfx_datetime.h"
+#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_random.h"
-#include "fxjs/xfa/cfxjse_arguments.h"
+#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/widetext_buffer.h"
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_class.h"
#include "fxjs/xfa/cfxjse_context.h"
#include "fxjs/xfa/cfxjse_engine.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "fxjs/xfa/cjx_object.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/base/check_op.h"
+#include "third_party/base/cxx17_backports.h"
+#include "third_party/base/numerics/safe_conversions.h"
+#include "v8/include/v8-container.h"
+#include "v8/include/v8-function-callback.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fgas/crt/cfgas_decimal.h"
-#include "xfa/fgas/crt/locale_iface.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
-#include "xfa/fxfa/fm2js/cxfa_fmparser.h"
-#include "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h"
+#include "xfa/fxfa/formcalc/cxfa_fmparser.h"
+#include "xfa/fxfa/formcalc/cxfa_fmtojavascriptdepth.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_localevalue.h"
#include "xfa/fxfa/parser/cxfa_node.h"
+#include "xfa/fxfa/parser/cxfa_thisproxy.h"
#include "xfa/fxfa/parser/cxfa_timezoneprovider.h"
+#include "xfa/fxfa/parser/gced_locale_iface.h"
#include "xfa/fxfa/parser/xfa_utils.h"
using pdfium::fxjse::kClassTag;
@@ -38,13 +54,17 @@
namespace {
+// Maximum number of characters Acrobat can fit in a text box.
+constexpr int kMaxCharCount = 15654908;
+
const double kFinancialPrecision = 0.00000001;
const wchar_t kStrCode[] = L"0123456789abcdef";
struct XFA_FMHtmlReserveCode {
- uint32_t m_uCode;
- const char* m_htmlReserve;
+ uint16_t m_uCode;
+ // Inline string data reduces size for small strings.
+ const char m_htmlReserve[10];
};
// Sorted by |m_htmlReserve|.
@@ -181,7 +201,7 @@
{9824, "spades"}, {9827, "clubs"}, {9829, "hearts"}, {9830, "diams"},
};
-const FXJSE_FUNCTION_DESCRIPTOR kFormCalcFM2JSFunctions[] = {
+const FXJSE_FUNCTION_DESCRIPTOR kFormCalcFunctions[] = {
{kFuncTag, "Abs", CFXJSE_FormCalcContext::Abs},
{kFuncTag, "Avg", CFXJSE_FormCalcContext::Avg},
{kFuncTag, "Ceil", CFXJSE_FormCalcContext::Ceil},
@@ -280,7 +300,7 @@
255, 2, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 1, 255, 255, 255, 255, 255, 255, 255, 255,
};
-static_assert(FX_ArraySize(kAltTableDate) == L'a' - L'A' + 1,
+static_assert(std::size(kAltTableDate) == L'a' - L'A' + 1,
"Invalid kAltTableDate size.");
const uint8_t kAltTableTime[] = {
@@ -288,7 +308,7 @@
255, 6, 255, 255, 255, 255, 255, 7, 255, 255, 255,
255, 255, 1, 17, 255, 255, 255, 255, 255, 255, 255,
};
-static_assert(FX_ArraySize(kAltTableTime) == L'a' - L'A' + 1,
+static_assert(std::size(kAltTableTime) == L'a' - L'A' + 1,
"Invalid kAltTableTime size.");
void AlternateDateTimeSymbols(WideString* pPattern,
@@ -322,37 +342,34 @@
}
}
-std::pair<bool, uint32_t> PatternStringType(ByteStringView bsPattern) {
+std::pair<bool, CXFA_LocaleValue::ValueType> PatternStringType(
+ ByteStringView bsPattern) {
WideString wsPattern = WideString::FromUTF8(bsPattern);
if (L"datetime" == wsPattern.First(8))
- return {true, XFA_VT_DATETIME};
+ return {true, CXFA_LocaleValue::ValueType::kDateTime};
if (L"date" == wsPattern.First(4)) {
auto pos = wsPattern.Find(L"time");
- uint32_t type =
- pos.has_value() && pos.value() != 0 ? XFA_VT_DATETIME : XFA_VT_DATE;
- return {true, type};
+ if (pos.has_value() && pos.value() != 0)
+ return {true, CXFA_LocaleValue::ValueType::kDateTime};
+ return {true, CXFA_LocaleValue::ValueType::kDate};
}
if (L"time" == wsPattern.First(4))
- return {true, XFA_VT_TIME};
+ return {true, CXFA_LocaleValue::ValueType::kTime};
if (L"text" == wsPattern.First(4))
- return {true, XFA_VT_TEXT};
+ return {true, CXFA_LocaleValue::ValueType::kText};
if (L"num" == wsPattern.First(3)) {
- uint32_t type;
- if (L"integer" == wsPattern.Substr(4, 7)) {
- type = XFA_VT_INTEGER;
- } else if (L"decimal" == wsPattern.Substr(4, 7)) {
- type = XFA_VT_DECIMAL;
- } else if (L"currency" == wsPattern.Substr(4, 8)) {
- type = XFA_VT_FLOAT;
- } else if (L"percent" == wsPattern.Substr(4, 7)) {
- type = XFA_VT_FLOAT;
- } else {
- type = XFA_VT_FLOAT;
- }
- return {true, type};
+ if (L"integer" == wsPattern.Substr(4, 7))
+ return {true, CXFA_LocaleValue::ValueType::kInteger};
+ if (L"decimal" == wsPattern.Substr(4, 7))
+ return {true, CXFA_LocaleValue::ValueType::kDecimal};
+ if (L"currency" == wsPattern.Substr(4, 8))
+ return {true, CXFA_LocaleValue::ValueType::kFloat};
+ if (L"percent" == wsPattern.Substr(4, 7))
+ return {true, CXFA_LocaleValue::ValueType::kFloat};
+ return {true, CXFA_LocaleValue::ValueType::kFloat};
}
- uint32_t type = XFA_VT_NULL;
+ CXFA_LocaleValue::ValueType type = CXFA_LocaleValue::ValueType::kNull;
wsPattern.MakeLower();
const wchar_t* pData = wsPattern.c_str();
int32_t iLength = wsPattern.GetLength();
@@ -371,11 +388,11 @@
}
if (wsPatternChar == 'h' || wsPatternChar == 'k')
- return {false, XFA_VT_TIME};
+ return {false, CXFA_LocaleValue::ValueType::kTime};
if (wsPatternChar == 'x' || wsPatternChar == 'o' || wsPatternChar == '0')
- return {false, XFA_VT_TEXT};
+ return {false, CXFA_LocaleValue::ValueType::kText};
if (wsPatternChar == 'v' || wsPatternChar == '8' || wsPatternChar == '$')
- return {false, XFA_VT_FLOAT};
+ return {false, CXFA_LocaleValue::ValueType::kFloat};
if (wsPatternChar == 'y' || wsPatternChar == 'j') {
iIndex++;
wchar_t timePatternChar;
@@ -387,35 +404,31 @@
continue;
}
if (!bSingleQuotation && timePatternChar == 't')
- return {false, XFA_VT_DATETIME};
+ return {false, CXFA_LocaleValue::ValueType::kDateTime};
iIndex++;
}
- return {false, XFA_VT_DATE};
+ return {false, CXFA_LocaleValue::ValueType::kDate};
}
if (wsPatternChar == 'a') {
- type = XFA_VT_TEXT;
+ type = CXFA_LocaleValue::ValueType::kText;
} else if (wsPatternChar == 'z' || wsPatternChar == 's' ||
wsPatternChar == 'e' || wsPatternChar == ',' ||
wsPatternChar == '.') {
- type = XFA_VT_FLOAT;
+ type = CXFA_LocaleValue::ValueType::kFloat;
}
iIndex++;
}
-
- if (type == XFA_VT_NULL)
- type = XFA_VT_TEXT | XFA_VT_FLOAT;
return {false, type};
}
-CFXJSE_FormCalcContext* ToFormCalcContext(CFXJSE_Value* pValue) {
- CFXJSE_HostObject* pHostObj = pValue->ToHostObject();
+CFXJSE_FormCalcContext* ToFormCalcContext(CFXJSE_HostObject* pHostObj) {
return pHostObj ? pHostObj->AsFormCalcContext() : nullptr;
}
-LocaleIface* LocaleFromString(CXFA_Document* pDoc,
- CXFA_LocaleMgr* pMgr,
- ByteStringView bsLocale) {
+GCedLocaleIface* LocaleFromString(CXFA_Document* pDoc,
+ CXFA_LocaleMgr* pMgr,
+ ByteStringView bsLocale) {
if (!bsLocale.IsEmpty())
return pMgr->GetLocaleByName(WideString::FromUTF8(bsLocale));
@@ -427,21 +440,21 @@
if (!bsFormat.IsEmpty())
return WideString::FromUTF8(bsFormat);
- return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Default);
+ return pLocale->GetDatePattern(LocaleIface::DateTimeSubcategory::kDefault);
}
-FX_LOCALEDATETIMESUBCATEGORY SubCategoryFromInt(int32_t iStyle) {
+LocaleIface::DateTimeSubcategory SubCategoryFromInt(int32_t iStyle) {
switch (iStyle) {
case 1:
- return FX_LOCALEDATETIMESUBCATEGORY_Short;
+ return LocaleIface::DateTimeSubcategory::kShort;
case 3:
- return FX_LOCALEDATETIMESUBCATEGORY_Long;
+ return LocaleIface::DateTimeSubcategory::kLong;
case 4:
- return FX_LOCALEDATETIMESUBCATEGORY_Full;
+ return LocaleIface::DateTimeSubcategory::kFull;
case 0:
case 2:
default:
- return FX_LOCALEDATETIMESUBCATEGORY_Medium;
+ return LocaleIface::DateTimeSubcategory::kMedium;
}
}
@@ -455,7 +468,7 @@
if (!pLocale)
return ByteString();
- FX_LOCALEDATETIMESUBCATEGORY category = SubCategoryFromInt(iStyle);
+ LocaleIface::DateTimeSubcategory category = SubCategoryFromInt(iStyle);
WideString wsLocal = bIsDate ? pLocale->GetDatePattern(category)
: pLocale->GetTimePattern(category);
if (!bStandard)
@@ -469,7 +482,7 @@
}
bool IsPartOfNumber(char ch) {
- return std::isdigit(ch) || ch == '-' || ch == '.';
+ return isdigit(ch) || ch == '-' || ch == '.';
}
bool IsPartOfNumberW(wchar_t ch) {
@@ -517,7 +530,7 @@
char szYear[5];
szYear[4] = '\0';
for (int32_t i = 0; i < 4; ++i) {
- if (!std::isdigit(pData[i]))
+ if (!isdigit(pData[i]))
return false;
szYear[i] = pData[i];
@@ -530,7 +543,7 @@
iStyle = pData[4] == '-' ? 1 : 0;
size_t iPosOff = iStyle == 0 ? 4 : 5;
- if (!std::isdigit(pData[iPosOff]) || !std::isdigit(pData[iPosOff + 1]))
+ if (!isdigit(pData[iPosOff]) || !isdigit(pData[iPosOff + 1]))
return false;
char szBuffer[3] = {};
@@ -549,7 +562,7 @@
if (pData.size() == 7)
return true;
}
- if (!std::isdigit(pData[iPosOff]) || !std::isdigit(pData[iPosOff + 1]))
+ if (!isdigit(pData[iPosOff]) || !isdigit(pData[iPosOff + 1]))
return false;
szBuffer[0] = pData[iPosOff];
@@ -595,7 +608,7 @@
size_t iZone = 0;
size_t i = 0;
while (i < pData.size()) {
- if (!std::isdigit(pData[i]) && pData[i] != ':') {
+ if (!isdigit(pData[i]) && pData[i] != ':') {
iZone = i;
break;
}
@@ -608,11 +621,11 @@
size_t iPos = 0;
size_t iIndex = 0;
while (iIndex < iZone) {
- if (!std::isdigit(pData[iIndex]))
+ if (!isdigit(pData[iIndex]))
return false;
szBuffer[0] = pData[iIndex];
- if (!std::isdigit(pData[iIndex + 1]))
+ if (!isdigit(pData[iIndex + 1]))
return false;
szBuffer[1] = pData[iIndex + 1];
@@ -654,7 +667,7 @@
char szMilliSeconds[kSubSecondLength + 1];
for (int j = 0; j < kSubSecondLength; ++j) {
char c = pData[iIndex + j];
- if (!std::isdigit(c))
+ if (!isdigit(c))
return false;
szMilliSeconds[j] = c;
}
@@ -682,11 +695,11 @@
}
iPos = 0;
while (iIndex < pData.size()) {
- if (!std::isdigit(pData[iIndex]))
+ if (!isdigit(pData[iIndex]))
return false;
szBuffer[0] = pData[iIndex];
- if (!std::isdigit(pData[iIndex + 1]))
+ if (!isdigit(pData[iIndex + 1]))
return false;
szBuffer[1] = pData[iIndex + 1];
@@ -728,45 +741,29 @@
int32_t* pMilliSecond,
int32_t* pZoneHour,
int32_t* pZoneMinute) {
- int32_t& iYear = *pYear;
- int32_t& iMonth = *pMonth;
- int32_t& iDay = *pDay;
- int32_t& iHour = *pHour;
- int32_t& iMinute = *pMinute;
- int32_t& iSecond = *pSecond;
- int32_t& iMilliSecond = *pMilliSecond;
- int32_t& iZoneHour = *pZoneHour;
- int32_t& iZoneMinute = *pZoneMinute;
-
- iYear = 0;
- iMonth = 0;
- iDay = 0;
- iHour = 0;
- iMinute = 0;
- iSecond = 0;
-
- if (pData.empty())
- return false;
+ *pYear = 0;
+ *pMonth = 0;
+ *pDay = 0;
+ *pHour = 0;
+ *pMinute = 0;
+ *pSecond = 0;
size_t iIndex = 0;
- while (pData[iIndex] != 'T' && pData[iIndex] != 't') {
- if (iIndex >= pData.size())
- return false;
+ while (iIndex < pData.size()) {
+ if (pData[iIndex] == 'T' || pData[iIndex] == 't')
+ break;
++iIndex;
}
- if (iIndex != 8 && iIndex != 10)
+ if (iIndex == pData.size() || (iIndex != 8 && iIndex != 10))
return false;
+ pdfium::span<const char> pDateSpan = pData.subspan(0, iIndex);
+ pdfium::span<const char> pTimeSpan = pData.subspan(iIndex + 1);
+
int32_t iStyle = -1;
- if (!IsIsoDateFormat(pData.subspan(0, iIndex), &iStyle, &iYear, &iMonth,
- &iDay)) {
- return false;
- }
- if (pData[iIndex] != 'T' && pData[iIndex] != 't')
- return true;
-
- return IsIsoTimeFormat(pData.subspan(iIndex + 1), &iHour, &iMinute, &iSecond,
- &iMilliSecond, &iZoneHour, &iZoneMinute);
+ return IsIsoDateFormat(pDateSpan, &iStyle, pYear, pMonth, pDay) &&
+ IsIsoTimeFormat(pTimeSpan, pHour, pMinute, pSecond, pMilliSecond,
+ pZoneHour, pZoneMinute);
}
int32_t DateString2Num(ByteStringView bsDate) {
@@ -820,7 +817,7 @@
++dDays;
++i;
}
- return (int32_t)dDays;
+ return static_cast<int32_t>(dDays);
}
void GetLocalTimeZone(int32_t* pHour, int32_t* pMin, int32_t* pSec) {
@@ -869,7 +866,7 @@
WideString DecodeURL(const WideString& wsURL) {
const wchar_t* pData = wsURL.c_str();
size_t iLen = wsURL.GetLength();
- CFX_WideTextBuf wsResultBuf;
+ WideTextBuffer wsResultBuf;
for (size_t i = 0; i < iLen; ++i) {
wchar_t ch = pData[i];
if ('%' != ch) {
@@ -891,14 +888,13 @@
}
wsResultBuf.AppendChar(chTemp);
}
- wsResultBuf.AppendChar(0);
return wsResultBuf.MakeString();
}
WideString DecodeMLInternal(const WideString& wsHTML, bool bIsHTML) {
const wchar_t* pData = wsHTML.c_str();
size_t iLen = wsHTML.GetLength();
- CFX_WideTextBuf wsResultBuf;
+ WideTextBuffer wsResultBuf;
for (size_t i = 0; i < iLen; ++i) {
wchar_t ch = pData[i];
if (ch != '&') {
@@ -959,8 +955,6 @@
wsResultBuf.AppendChar('>');
}
}
-
- wsResultBuf.AppendChar(0);
return wsResultBuf.MakeString();
}
@@ -980,13 +974,13 @@
'\'', '(', ')', ','};
WideString wsURL = WideString::FromUTF8(bsURL.AsStringView());
- CFX_WideTextBuf wsResultBuf;
+ WideTextBuffer wsResultBuf;
wchar_t szEncode[4];
szEncode[0] = '%';
szEncode[3] = 0;
for (wchar_t ch : wsURL) {
size_t i = 0;
- size_t iCount = FX_ArraySize(kStrUnsafe);
+ size_t iCount = std::size(kStrUnsafe);
while (i < iCount) {
if (ch == kStrUnsafe[i]) {
int32_t iIndex = ch / 16;
@@ -1001,7 +995,7 @@
continue;
i = 0;
- iCount = FX_ArraySize(kStrReserved);
+ iCount = std::size(kStrReserved);
while (i < iCount) {
if (ch == kStrReserved[i]) {
int32_t iIndex = ch / 16;
@@ -1016,7 +1010,7 @@
continue;
i = 0;
- iCount = FX_ArraySize(kStrSpecial);
+ iCount = std::size(kStrSpecial);
while (i < iCount) {
if (ch == kStrSpecial[i]) {
wsResultBuf.AppendChar(ch);
@@ -1066,7 +1060,6 @@
}
}
}
- wsResultBuf.AppendChar(0);
return wsResultBuf.MakeString();
}
@@ -1076,7 +1069,7 @@
szEncode[0] = '&';
szEncode[1] = '#';
szEncode[2] = 'x';
- CFX_WideTextBuf wsResultBuf;
+ WideTextBuffer wsResultBuf;
for (uint32_t ch : wsHTML) {
WideString htmlReserve;
if (HTMLCode2STR(ch, &htmlReserve)) {
@@ -1106,13 +1099,12 @@
// TODO(tsepez): Handle codepoint not in BMP.
}
}
- wsResultBuf.AppendChar(0);
return wsResultBuf.MakeString();
}
WideString EncodeXML(const ByteString& bsXML) {
WideString wsXML = WideString::FromUTF8(bsXML.AsStringView());
- CFX_WideTextBuf wsResultBuf;
+ WideTextBuffer wsResultBuf;
wchar_t szEncode[9];
szEncode[0] = '&';
szEncode[1] = '#';
@@ -1171,25 +1163,21 @@
}
}
}
- wsResultBuf.AppendChar(0);
return wsResultBuf.MakeString();
}
ByteString TrillionUS(ByteStringView bsData) {
- static const ByteStringView pUnits[] = {"zero", "one", "two", "three",
- "four", "five", "six", "seven",
- "eight", "nine"};
- static const ByteStringView pCapUnits[] = {"Zero", "One", "Two", "Three",
- "Four", "Five", "Six", "Seven",
- "Eight", "Nine"};
- static const ByteStringView pTens[] = {
+ static const char kUnits[][6] = {"zero", "one", "two", "three", "four",
+ "five", "six", "seven", "eight", "nine"};
+ static const char kCapUnits[][6] = {"Zero", "One", "Two", "Three", "Four",
+ "Five", "Six", "Seven", "Eight", "Nine"};
+ static const char kTens[][10] = {
"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen",
"Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
- static const ByteStringView pLastTens[] = {"Twenty", "Thirty", "Forty",
- "Fifty", "Sixty", "Seventy",
- "Eighty", "Ninety"};
- static const ByteStringView pComm[] = {" Hundred ", " Thousand ", " Million ",
- " Billion ", "Trillion"};
+ static const char kLastTens[][8] = {"Twenty", "Thirty", "Forty", "Fifty",
+ "Sixty", "Seventy", "Eighty", "Ninety"};
+ static const char kComm[][11] = {" Hundred ", " Thousand ", " Million ",
+ " Billion ", "Trillion"};
const char* pData = bsData.unterminated_c_str();
int32_t iLength = bsData.GetLength();
int32_t iComm = 0;
@@ -1206,89 +1194,86 @@
if (iFirstCount == 0)
iFirstCount = 3;
- std::ostringstream strBuf;
+ ByteString strBuf;
int32_t iIndex = 0;
if (iFirstCount == 3) {
if (pData[iIndex] != '0') {
- strBuf << pCapUnits[pData[iIndex] - '0'];
- strBuf << pComm[0];
+ strBuf += kCapUnits[pData[iIndex] - '0'];
+ strBuf += kComm[0];
}
if (pData[iIndex + 1] == '0') {
- strBuf << pCapUnits[pData[iIndex + 2] - '0'];
+ strBuf += kCapUnits[pData[iIndex + 2] - '0'];
} else {
if (pData[iIndex + 1] > '1') {
- strBuf << pLastTens[pData[iIndex + 1] - '2'];
- strBuf << "-";
- strBuf << pUnits[pData[iIndex + 2] - '0'];
+ strBuf += kLastTens[pData[iIndex + 1] - '2'];
+ strBuf += "-";
+ strBuf += kUnits[pData[iIndex + 2] - '0'];
} else if (pData[iIndex + 1] == '1') {
- strBuf << pTens[pData[iIndex + 2] - '0'];
+ strBuf += kTens[pData[iIndex + 2] - '0'];
} else if (pData[iIndex + 1] == '0') {
- strBuf << pCapUnits[pData[iIndex + 2] - '0'];
+ strBuf += kCapUnits[pData[iIndex + 2] - '0'];
}
}
iIndex += 3;
} else if (iFirstCount == 2) {
if (pData[iIndex] == '0') {
- strBuf << pCapUnits[pData[iIndex + 1] - '0'];
+ strBuf += kCapUnits[pData[iIndex + 1] - '0'];
} else {
if (pData[iIndex] > '1') {
- strBuf << pLastTens[pData[iIndex] - '2'];
- strBuf << "-";
- strBuf << pUnits[pData[iIndex + 1] - '0'];
+ strBuf += kLastTens[pData[iIndex] - '2'];
+ strBuf += "-";
+ strBuf += kUnits[pData[iIndex + 1] - '0'];
} else if (pData[iIndex] == '1') {
- strBuf << pTens[pData[iIndex + 1] - '0'];
+ strBuf += kTens[pData[iIndex + 1] - '0'];
} else if (pData[iIndex] == '0') {
- strBuf << pCapUnits[pData[iIndex + 1] - '0'];
+ strBuf += kCapUnits[pData[iIndex + 1] - '0'];
}
}
iIndex += 2;
} else if (iFirstCount == 1) {
- strBuf << pCapUnits[pData[iIndex] - '0'];
+ strBuf += kCapUnits[pData[iIndex] - '0'];
++iIndex;
}
if (iLength > 3 && iFirstCount > 0) {
- strBuf << pComm[iComm];
+ strBuf += kComm[iComm];
--iComm;
}
while (iIndex < iLength) {
if (pData[iIndex] != '0') {
- strBuf << pCapUnits[pData[iIndex] - '0'];
- strBuf << pComm[0];
+ strBuf += kCapUnits[pData[iIndex] - '0'];
+ strBuf += kComm[0];
}
if (pData[iIndex + 1] == '0') {
- strBuf << pCapUnits[pData[iIndex + 2] - '0'];
+ strBuf += kCapUnits[pData[iIndex + 2] - '0'];
} else {
if (pData[iIndex + 1] > '1') {
- strBuf << pLastTens[pData[iIndex + 1] - '2'];
- strBuf << "-";
- strBuf << pUnits[pData[iIndex + 2] - '0'];
+ strBuf += kLastTens[pData[iIndex + 1] - '2'];
+ strBuf += "-";
+ strBuf += kUnits[pData[iIndex + 2] - '0'];
} else if (pData[iIndex + 1] == '1') {
- strBuf << pTens[pData[iIndex + 2] - '0'];
+ strBuf += kTens[pData[iIndex + 2] - '0'];
} else if (pData[iIndex + 1] == '0') {
- strBuf << pCapUnits[pData[iIndex + 2] - '0'];
+ strBuf += kCapUnits[pData[iIndex + 2] - '0'];
}
}
if (iIndex < iLength - 3) {
- strBuf << pComm[iComm];
+ strBuf += kComm[iComm];
--iComm;
}
iIndex += 3;
}
- return ByteString(strBuf);
+ return strBuf;
}
-ByteString WordUS(const ByteString& bsData, int32_t iStyle) {
- const char* pData = bsData.c_str();
- int32_t iLength = bsData.GetLength();
- if (iStyle < 0 || iStyle > 2) {
+ByteString WordUS(ByteStringView bsData, int32_t iStyle) {
+ if (iStyle < 0 || iStyle > 2)
return ByteString();
- }
- std::ostringstream strBuf;
-
+ int32_t iLength = bsData.GetLength();
+ ByteString strBuf;
int32_t iIndex = 0;
while (iIndex < iLength) {
- if (pData[iIndex] == '.')
+ if (bsData[iIndex] == '.')
break;
++iIndex;
}
@@ -1299,535 +1284,641 @@
if (!iCount && iInteger - iIndex > 0)
iCount = 12;
- strBuf << TrillionUS(ByteStringView(pData + iIndex, iCount));
+ strBuf += TrillionUS(bsData.Substr(iIndex, iCount));
iIndex += iCount;
if (iIndex < iInteger)
- strBuf << " Trillion ";
+ strBuf += " Trillion ";
}
if (iStyle > 0)
- strBuf << " Dollars";
+ strBuf += " Dollars";
if (iStyle > 1 && iInteger < iLength) {
- strBuf << " And ";
+ strBuf += " And ";
iIndex = iInteger + 1;
while (iIndex < iLength) {
int32_t iCount = (iLength - iIndex) % 12;
if (!iCount && iLength - iIndex > 0)
iCount = 12;
- strBuf << TrillionUS(ByteStringView(pData + iIndex, iCount));
+ strBuf += TrillionUS(bsData.Substr(iIndex, iCount));
iIndex += iCount;
if (iIndex < iLength)
- strBuf << " Trillion ";
+ strBuf += " Trillion ";
}
- strBuf << " Cents";
+ strBuf += " Cents";
}
- return ByteString(strBuf);
+ return strBuf;
+}
+
+v8::Local<v8::Value> GetObjectDefaultValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject) {
+ CXFA_Node* pNode = ToNode(CFXJSE_Engine::ToObject(pIsolate, pObject));
+ if (!pNode)
+ return fxv8::NewNullHelper(pIsolate);
+
+ v8::Local<v8::Value> value;
+ pNode->JSObject()->ScriptSomDefaultValue(pIsolate, &value, false,
+ XFA_Attribute::Unknown);
+ return value;
+}
+
+bool SetObjectDefaultValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
+ v8::Local<v8::Value> hNewValue) {
+ CXFA_Node* pNode = ToNode(CFXJSE_Engine::ToObject(pIsolate, pObject));
+ if (!pNode)
+ return false;
+
+ pNode->JSObject()->ScriptSomDefaultValue(pIsolate, &hNewValue, true,
+ XFA_Attribute::Unknown);
+ return true;
+}
+
+v8::Local<v8::Value> GetExtractedValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ if (fxv8::IsArray(pValue)) {
+ v8::Local<v8::Array> arr = pValue.As<v8::Array>();
+ uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
+ if (iLength < 3)
+ return fxv8::NewUndefinedHelper(pIsolate);
+
+ v8::Local<v8::Value> propertyValue =
+ fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 1);
+ v8::Local<v8::Value> jsValue =
+ fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 2);
+ if (!fxv8::IsObject(jsValue))
+ return fxv8::NewUndefinedHelper(pIsolate);
+
+ v8::Local<v8::Object> jsObjectValue = jsValue.As<v8::Object>();
+ if (fxv8::IsNull(propertyValue))
+ return GetObjectDefaultValue(pIsolate, jsObjectValue);
+
+ ByteString bsName =
+ fxv8::ReentrantToByteStringHelper(pIsolate, propertyValue);
+ return fxv8::ReentrantGetObjectPropertyHelper(pIsolate, jsObjectValue,
+ bsName.AsStringView());
+ }
+
+ if (fxv8::IsObject(pValue))
+ return GetObjectDefaultValue(pIsolate, pValue.As<v8::Object>());
+
+ return pValue;
+}
+
+v8::Local<v8::Value> GetSimpleValue(
+ const v8::FunctionCallbackInfo<v8::Value>& info,
+ uint32_t index) {
+ DCHECK(index < static_cast<uint32_t>(info.Length()));
+ return GetExtractedValue(info.GetIsolate(), info[index]);
+}
+
+bool ValueIsNull(v8::Isolate* pIsolate, v8::Local<v8::Value> arg) {
+ v8::Local<v8::Value> extracted = GetExtractedValue(pIsolate, arg);
+ return extracted.IsEmpty() || fxv8::IsNull(extracted);
+}
+
+int32_t ValueToInteger(v8::Isolate* pIsolate, v8::Local<v8::Value> arg) {
+ v8::Local<v8::Value> extracted = GetExtractedValue(pIsolate, arg);
+ if (extracted.IsEmpty())
+ return 0;
+
+ if (fxv8::IsObject(extracted) || fxv8::IsArray(extracted))
+ return ValueToInteger(pIsolate, extracted);
+
+ if (fxv8::IsString(extracted)) {
+ ByteString bsValue = fxv8::ReentrantToByteStringHelper(pIsolate, extracted);
+ return FXSYS_atoi(bsValue.c_str());
+ }
+
+ return fxv8::ReentrantToInt32Helper(pIsolate, extracted);
+}
+
+float ValueToFloat(v8::Isolate* pIsolate, v8::Local<v8::Value> arg) {
+ v8::Local<v8::Value> extracted = GetExtractedValue(pIsolate, arg);
+ if (extracted.IsEmpty())
+ return 0.0f;
+
+ if (fxv8::IsUndefined(extracted))
+ return 0.0f;
+
+ if (fxv8::IsObject(extracted) || fxv8::IsArray(extracted))
+ return ValueToFloat(pIsolate, extracted);
+
+ if (fxv8::IsString(extracted)) {
+ ByteString bsValue = fxv8::ReentrantToByteStringHelper(pIsolate, extracted);
+ return strtof(bsValue.c_str(), nullptr);
+ }
+
+ return fxv8::ReentrantToFloatHelper(pIsolate, extracted);
+}
+
+double ValueToDouble(v8::Isolate* pIsolate, v8::Local<v8::Value> arg) {
+ v8::Local<v8::Value> extracted = GetExtractedValue(pIsolate, arg);
+ if (extracted.IsEmpty())
+ return 0.0;
+
+ if (fxv8::IsUndefined(extracted))
+ return 0.0;
+
+ if (fxv8::IsObject(extracted) || fxv8::IsArray(extracted))
+ return ValueToDouble(pIsolate, extracted);
+
+ if (fxv8::IsString(extracted)) {
+ ByteString bsValue = fxv8::ReentrantToByteStringHelper(pIsolate, extracted);
+ return strtod(bsValue.c_str(), nullptr);
+ }
+
+ return fxv8::ReentrantToDoubleHelper(pIsolate, extracted);
+}
+
+absl::optional<double> ExtractDouble(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> src) {
+ if (src.IsEmpty())
+ return 0.0;
+
+ if (!fxv8::IsArray(src))
+ return ValueToDouble(pIsolate, src);
+
+ v8::Local<v8::Array> arr = src.As<v8::Array>();
+ uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
+ if (iLength < 3)
+ return absl::nullopt;
+
+ v8::Local<v8::Value> propertyValue =
+ fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 1);
+ v8::Local<v8::Value> jsValue =
+ fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 2);
+ if (fxv8::IsNull(propertyValue) || !fxv8::IsObject(jsValue))
+ return ValueToDouble(pIsolate, jsValue);
+
+ ByteString bsName =
+ fxv8::ReentrantToByteStringHelper(pIsolate, propertyValue);
+ return ValueToDouble(
+ pIsolate, fxv8::ReentrantGetObjectPropertyHelper(
+ pIsolate, jsValue.As<v8::Object>(), bsName.AsStringView()));
+}
+
+ByteString ValueToUTF8String(v8::Isolate* pIsolate, v8::Local<v8::Value> arg) {
+ if (arg.IsEmpty())
+ return ByteString();
+
+ if (fxv8::IsNull(arg) || fxv8::IsUndefined(arg))
+ return ByteString();
+
+ if (fxv8::IsBoolean(arg))
+ return fxv8::ReentrantToBooleanHelper(pIsolate, arg) ? "1" : "0";
+
+ return fxv8::ReentrantToByteStringHelper(pIsolate, arg);
+}
+
+bool SimpleValueCompare(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> firstValue,
+ v8::Local<v8::Value> secondValue) {
+ if (firstValue.IsEmpty())
+ return false;
+
+ if (fxv8::IsString(firstValue)) {
+ const ByteString first = ValueToUTF8String(pIsolate, firstValue);
+ const ByteString second = ValueToUTF8String(pIsolate, secondValue);
+ return first == second;
+ }
+ if (fxv8::IsNumber(firstValue)) {
+ const float first = ValueToFloat(pIsolate, firstValue);
+ const float second = ValueToFloat(pIsolate, secondValue);
+ return first == second;
+ }
+ if (fxv8::IsBoolean(firstValue)) {
+ const bool first = fxv8::ReentrantToBooleanHelper(pIsolate, firstValue);
+ const bool second = fxv8::ReentrantToBooleanHelper(pIsolate, secondValue);
+ return first == second;
+ }
+ return fxv8::IsNull(firstValue) && fxv8::IsNull(secondValue);
+}
+
+std::vector<v8::Local<v8::Value>> UnfoldArgs(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ std::vector<v8::Local<v8::Value>> results;
+ v8::Isolate* pIsolate = info.GetIsolate();
+ for (int i = 1; i < info.Length(); ++i) {
+ v8::Local<v8::Value> arg = info[i];
+ if (fxv8::IsArray(arg)) {
+ v8::Local<v8::Array> arr = arg.As<v8::Array>();
+ uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
+ if (iLength < 3)
+ continue;
+
+ v8::Local<v8::Value> propertyValue =
+ fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 1);
+
+ for (uint32_t j = 2; j < iLength; j++) {
+ v8::Local<v8::Value> jsValue =
+ fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, j);
+
+ if (!fxv8::IsObject(jsValue)) {
+ results.push_back(fxv8::NewUndefinedHelper(pIsolate));
+ } else if (fxv8::IsNull(propertyValue)) {
+ results.push_back(
+ GetObjectDefaultValue(pIsolate, jsValue.As<v8::Object>()));
+ } else {
+ ByteString bsName =
+ fxv8::ReentrantToByteStringHelper(pIsolate, propertyValue);
+ results.push_back(fxv8::ReentrantGetObjectPropertyHelper(
+ pIsolate, jsValue.As<v8::Object>(), bsName.AsStringView()));
+ }
+ }
+ } else if (fxv8::IsObject(arg)) {
+ results.push_back(GetObjectDefaultValue(pIsolate, arg.As<v8::Object>()));
+ } else {
+ results.push_back(arg);
+ }
+ }
+ return results;
+}
+
+// Returns empty value on failure.
+v8::Local<v8::Value> GetObjectForName(CFXJSE_HostObject* pHostObject,
+ ByteStringView bsAccessorName) {
+ CXFA_Document* pDoc = ToFormCalcContext(pHostObject)->GetDocument();
+ if (!pDoc)
+ return v8::Local<v8::Value>();
+
+ CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+ pScriptContext->ResolveObjects(
+ pScriptContext->GetThisObject(),
+ WideString::FromUTF8(bsAccessorName).AsStringView(),
+ Mask<XFA_ResolveFlag>{
+ XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kProperties,
+ XFA_ResolveFlag::kSiblings, XFA_ResolveFlag::kParent});
+ if (!maybeResult.has_value() ||
+ maybeResult.value().type != CFXJSE_Engine::ResolveResult::Type::kNodes ||
+ maybeResult.value().objects.empty()) {
+ return v8::Local<v8::Value>();
+ }
+ return pScriptContext->GetOrCreateJSBindingFromMap(
+ maybeResult.value().objects.front().Get());
+}
+
+absl::optional<CFXJSE_Engine::ResolveResult> ResolveObjects(
+ CFXJSE_HostObject* pHostObject,
+ v8::Local<v8::Value> pRefValue,
+ ByteStringView bsSomExp,
+ bool bDotAccessor,
+ bool bHasNoResolveName) {
+ CXFA_Document* pDoc = ToFormCalcContext(pHostObject)->GetDocument();
+ if (!pDoc)
+ return absl::nullopt;
+
+ v8::Isolate* pIsolate = ToFormCalcContext(pHostObject)->GetIsolate();
+ WideString wsSomExpression = WideString::FromUTF8(bsSomExp);
+ CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
+ CXFA_Object* pNode = nullptr;
+ Mask<XFA_ResolveFlag> dwFlags;
+ if (bDotAccessor) {
+ if (fxv8::IsNull(pRefValue)) {
+ pNode = pScriptContext->GetThisObject();
+ dwFlags = {XFA_ResolveFlag::kSiblings, XFA_ResolveFlag::kParent};
+ } else {
+ pNode = CFXJSE_Engine::ToObject(pIsolate, pRefValue);
+ if (!pNode)
+ return absl::nullopt;
+
+ if (bHasNoResolveName) {
+ WideString wsName;
+ if (CXFA_Node* pXFANode = pNode->AsNode()) {
+ absl::optional<WideString> ret =
+ pXFANode->JSObject()->TryAttribute(XFA_Attribute::Name, false);
+ if (ret.has_value())
+ wsName = ret.value();
+ }
+ if (wsName.IsEmpty())
+ wsName = L"#" + WideString::FromASCII(pNode->GetClassName());
+
+ wsSomExpression = wsName + wsSomExpression;
+ dwFlags = XFA_ResolveFlag::kSiblings;
+ } else {
+ dwFlags = (bsSomExp == "*")
+ ? Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kChildren}
+ : Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kChildren,
+ XFA_ResolveFlag::kAttributes,
+ XFA_ResolveFlag::kProperties};
+ }
+ }
+ } else {
+ pNode = CFXJSE_Engine::ToObject(pIsolate, pRefValue);
+ dwFlags = XFA_ResolveFlag::kAnyChild;
+ }
+ return pScriptContext->ResolveObjects(pNode, wsSomExpression.AsStringView(),
+ dwFlags);
+}
+
+std::vector<v8::Local<v8::Value>> ParseResolveResult(
+ CFXJSE_HostObject* pHostObject,
+ const CFXJSE_Engine::ResolveResult& resolveNodeRS,
+ v8::Local<v8::Value> pParentValue,
+ bool* bAttribute) {
+ std::vector<v8::Local<v8::Value>> resultValues;
+ CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pHostObject);
+ v8::Isolate* pIsolate = pContext->GetIsolate();
+
+ if (resolveNodeRS.type == CFXJSE_Engine::ResolveResult::Type::kNodes) {
+ *bAttribute = false;
+ CFXJSE_Engine* pScriptContext = pContext->GetDocument()->GetScriptContext();
+ for (auto& pObject : resolveNodeRS.objects) {
+ resultValues.push_back(
+ pScriptContext->GetOrCreateJSBindingFromMap(pObject.Get()));
+ }
+ return resultValues;
+ }
+
+ *bAttribute = true;
+ if (resolveNodeRS.script_attribute.callback &&
+ resolveNodeRS.script_attribute.eValueType == XFA_ScriptType::Object) {
+ for (auto& pObject : resolveNodeRS.objects) {
+ v8::Local<v8::Value> pValue;
+ CJX_Object* jsObject = pObject->JSObject();
+ (*resolveNodeRS.script_attribute.callback)(
+ pIsolate, jsObject, &pValue, false,
+ resolveNodeRS.script_attribute.attribute);
+ resultValues.push_back(pValue);
+ *bAttribute = false;
+ }
+ }
+ if (*bAttribute && fxv8::IsObject(pParentValue))
+ resultValues.push_back(pParentValue);
+
+ return resultValues;
+}
+
+// Returns 0 if the provided `arg` is an invalid payment period count.
+int GetValidatedPaymentPeriods(v8::Isolate* isolate, v8::Local<v8::Value> arg) {
+ double periods = ValueToDouble(isolate, arg);
+ if (periods < 1 ||
+ periods > static_cast<double>(std::numeric_limits<int32_t>::max())) {
+ return 0;
+ }
+
+ return static_cast<int>(periods);
}
} // namespace
-const FXJSE_CLASS_DESCRIPTOR kFormCalcFM2JSDescriptor = {
- kClassTag, // tag
- "XFA_FM2JS_FormCalcClass", // name
- kFormCalcFM2JSFunctions, // methods
- FX_ArraySize(kFormCalcFM2JSFunctions), // number of methods
- nullptr, // dynamic prop type
- nullptr, // dynamic prop getter
- nullptr, // dynamic prop setter
- nullptr, // dynamic prop method call
+const FXJSE_CLASS_DESCRIPTOR kFormCalcDescriptor = {
+ kClassTag, // tag
+ "XFA_FormCalcClass", // name
+ kFormCalcFunctions, // methods
+ std::size(kFormCalcFunctions), // number of methods
+ nullptr, // dynamic prop type
+ nullptr, // dynamic prop getter
+ nullptr, // dynamic prop setter
+ nullptr, // dynamic prop method call
};
// static
-void CFXJSE_FormCalcContext::Abs(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Abs");
+void CFXJSE_FormCalcContext::Abs(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Abs");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
- if (ValueIsNull(pThis, argOne.get())) {
- args.GetReturnValue()->SetNull();
+ if (ValueIsNull(info.GetIsolate(), info[0])) {
+ info.GetReturnValue().SetNull();
return;
}
-
- double dValue = ValueToDouble(pThis, argOne.get());
+ double dValue = ValueToDouble(info.GetIsolate(), info[0]);
if (dValue < 0)
dValue = -dValue;
- args.GetReturnValue()->SetDouble(dValue);
+ info.GetReturnValue().Set(dValue);
}
// static
-void CFXJSE_FormCalcContext::Avg(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
- if (argc < 1) {
- args.GetReturnValue()->SetNull();
- return;
- }
-
- v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
+void CFXJSE_FormCalcContext::Avg(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
uint32_t uCount = 0;
double dSum = 0.0;
- for (int32_t i = 0; i < argc; i++) {
- std::unique_ptr<CFXJSE_Value> argValue = args.GetValue(i);
- if (argValue->IsNull())
- continue;
+ auto fn = [&uCount, &dSum](v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ dSum += ValueToDouble(pIsolate, pValue);
+ uCount++;
+ };
+ if (!ToFormCalcContext(pThis)->ApplyToExpansion(fn, info, /*bStrict=*/false))
+ return;
- if (!argValue->IsArray()) {
- dSum += ValueToDouble(pThis, argValue.get());
- uCount++;
- continue;
- }
-
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValue->GetObjectProperty("length", lengthValue.get());
- int32_t iLength = lengthValue->ToInteger();
-
- if (iLength > 2) {
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValue->GetObjectPropertyByIdx(1, propertyValue.get());
-
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- if (propertyValue->IsNull()) {
- for (int32_t j = 2; j < iLength; j++) {
- argValue->GetObjectPropertyByIdx(j, jsObjectValue.get());
- auto defaultPropValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(jsObjectValue.get(), defaultPropValue.get());
- if (defaultPropValue->IsNull())
- continue;
-
- dSum += ValueToDouble(pThis, defaultPropValue.get());
- uCount++;
- }
- } else {
- for (int32_t j = 2; j < iLength; j++) {
- argValue->GetObjectPropertyByIdx(j, jsObjectValue.get());
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- jsObjectValue->GetObjectProperty(
- propertyValue->ToString().AsStringView(), newPropertyValue.get());
- if (newPropertyValue->IsNull())
- continue;
-
- dSum += ValueToDouble(pThis, newPropertyValue.get());
- uCount++;
- }
- }
- }
- }
if (uCount == 0) {
- args.GetReturnValue()->SetNull();
+ info.GetReturnValue().SetNull();
return;
}
-
- args.GetReturnValue()->SetDouble(dSum / uCount);
+ info.GetReturnValue().Set(dSum / uCount);
}
// static
-void CFXJSE_FormCalcContext::Ceil(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Ceil");
+void CFXJSE_FormCalcContext::Ceil(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Ceil");
return;
}
- std::unique_ptr<CFXJSE_Value> argValue = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, argValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argValue = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- args.GetReturnValue()->SetFloat(ceil(ValueToFloat(pThis, argValue.get())));
+ info.GetReturnValue().Set(ceil(ValueToFloat(info.GetIsolate(), argValue)));
}
// static
-void CFXJSE_FormCalcContext::Count(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
- int32_t iCount = 0;
- for (int32_t i = 0; i < args.GetLength(); i++) {
- std::unique_ptr<CFXJSE_Value> argValue = args.GetValue(i);
- if (argValue->IsNull())
- continue;
+void CFXJSE_FormCalcContext::Count(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ uint32_t iCount = 0;
+ auto fn = [&iCount](v8::Isolate* pIsolate, v8::Local<v8::Value> pvalue) {
+ ++iCount;
+ };
+ if (!ToFormCalcContext(pThis)->ApplyToExpansion(fn, info, /*bStrict=*/true))
+ return;
- if (argValue->IsArray()) {
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValue->GetObjectProperty("length", lengthValue.get());
-
- int32_t iLength = lengthValue->ToInteger();
- if (iLength <= 2) {
- pContext->ThrowArgumentMismatchException();
- return;
- }
-
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValue->GetObjectPropertyByIdx(1, propertyValue.get());
- argValue->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (propertyValue->IsNull()) {
- for (int32_t j = 2; j < iLength; j++) {
- argValue->GetObjectPropertyByIdx(j, jsObjectValue.get());
- GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
- if (!newPropertyValue->IsNull())
- iCount++;
- }
- } else {
- for (int32_t j = 2; j < iLength; j++) {
- argValue->GetObjectPropertyByIdx(j, jsObjectValue.get());
- jsObjectValue->GetObjectProperty(
- propertyValue->ToString().AsStringView(), newPropertyValue.get());
- iCount += newPropertyValue->IsNull() ? 0 : 1;
- }
- }
- } else if (argValue->IsObject()) {
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(argValue.get(), newPropertyValue.get());
- if (!newPropertyValue->IsNull())
- iCount++;
- } else {
- iCount++;
- }
- }
- args.GetReturnValue()->SetInteger(iCount);
+ info.GetReturnValue().Set(iCount);
}
// static
-void CFXJSE_FormCalcContext::Floor(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Floor");
+void CFXJSE_FormCalcContext::Floor(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Floor");
return;
}
- std::unique_ptr<CFXJSE_Value> argValue = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, argValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argValue = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- args.GetReturnValue()->SetFloat(floor(ValueToFloat(pThis, argValue.get())));
+ info.GetReturnValue().Set(floor(ValueToFloat(info.GetIsolate(), argValue)));
}
// static
-void CFXJSE_FormCalcContext::Max(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
+void CFXJSE_FormCalcContext::Max(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
uint32_t uCount = 0;
double dMaxValue = 0.0;
- for (int32_t i = 0; i < args.GetLength(); i++) {
- std::unique_ptr<CFXJSE_Value> argValue = args.GetValue(i);
- if (argValue->IsNull())
- continue;
+ auto fn = [&uCount, &dMaxValue](v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ ++uCount;
+ double dValue = ValueToDouble(pIsolate, pValue);
+ dMaxValue = uCount == 1 ? dValue : std::max(dMaxValue, dValue);
+ };
+ if (!ToFormCalcContext(pThis)->ApplyToExpansion(fn, info, /*bStrict=*/true))
+ return;
- if (argValue->IsArray()) {
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValue->GetObjectProperty("length", lengthValue.get());
- int32_t iLength = lengthValue->ToInteger();
- if (iLength <= 2) {
- pContext->ThrowArgumentMismatchException();
- return;
- }
-
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValue->GetObjectPropertyByIdx(1, propertyValue.get());
- argValue->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (propertyValue->IsNull()) {
- for (int32_t j = 2; j < iLength; j++) {
- argValue->GetObjectPropertyByIdx(j, jsObjectValue.get());
- GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
- if (newPropertyValue->IsNull())
- continue;
-
- uCount++;
- double dValue = ValueToDouble(pThis, newPropertyValue.get());
- dMaxValue = (uCount == 1) ? dValue : std::max(dMaxValue, dValue);
- }
- } else {
- for (int32_t j = 2; j < iLength; j++) {
- argValue->GetObjectPropertyByIdx(j, jsObjectValue.get());
- jsObjectValue->GetObjectProperty(
- propertyValue->ToString().AsStringView(), newPropertyValue.get());
- if (newPropertyValue->IsNull())
- continue;
-
- uCount++;
- double dValue = ValueToDouble(pThis, newPropertyValue.get());
- dMaxValue = (uCount == 1) ? dValue : std::max(dMaxValue, dValue);
- }
- }
- } else if (argValue->IsObject()) {
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(argValue.get(), newPropertyValue.get());
- if (newPropertyValue->IsNull())
- continue;
-
- uCount++;
- double dValue = ValueToDouble(pThis, newPropertyValue.get());
- dMaxValue = (uCount == 1) ? dValue : std::max(dMaxValue, dValue);
- } else {
- uCount++;
- double dValue = ValueToDouble(pThis, argValue.get());
- dMaxValue = (uCount == 1) ? dValue : std::max(dMaxValue, dValue);
- }
- }
if (uCount == 0) {
- args.GetReturnValue()->SetNull();
+ info.GetReturnValue().SetNull();
return;
}
-
- args.GetReturnValue()->SetDouble(dMaxValue);
+ info.GetReturnValue().Set(dMaxValue);
}
// static
-void CFXJSE_FormCalcContext::Min(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
+void CFXJSE_FormCalcContext::Min(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
uint32_t uCount = 0;
double dMinValue = 0.0;
- for (int32_t i = 0; i < args.GetLength(); i++) {
- std::unique_ptr<CFXJSE_Value> argValue = args.GetValue(i);
- if (argValue->IsNull())
- continue;
+ auto fn = [&uCount, &dMinValue](v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ ++uCount;
+ double dValue = ValueToDouble(pIsolate, pValue);
+ dMinValue = uCount == 1 ? dValue : std::min(dMinValue, dValue);
+ };
+ if (!ToFormCalcContext(pThis)->ApplyToExpansion(fn, info, /*bStrict=*/true))
+ return;
- if (argValue->IsArray()) {
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValue->GetObjectProperty("length", lengthValue.get());
- int32_t iLength = lengthValue->ToInteger();
- if (iLength <= 2) {
- pContext->ThrowArgumentMismatchException();
- return;
- }
-
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValue->GetObjectPropertyByIdx(1, propertyValue.get());
- argValue->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (propertyValue->IsNull()) {
- for (int32_t j = 2; j < iLength; j++) {
- argValue->GetObjectPropertyByIdx(j, jsObjectValue.get());
- GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
- if (newPropertyValue->IsNull())
- continue;
-
- uCount++;
- double dValue = ValueToDouble(pThis, newPropertyValue.get());
- dMinValue = uCount == 1 ? dValue : std::min(dMinValue, dValue);
- }
- } else {
- for (int32_t j = 2; j < iLength; j++) {
- argValue->GetObjectPropertyByIdx(j, jsObjectValue.get());
- jsObjectValue->GetObjectProperty(
- propertyValue->ToString().AsStringView(), newPropertyValue.get());
- if (newPropertyValue->IsNull())
- continue;
-
- uCount++;
- double dValue = ValueToDouble(pThis, newPropertyValue.get());
- dMinValue = uCount == 1 ? dValue : std::min(dMinValue, dValue);
- }
- }
- } else if (argValue->IsObject()) {
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(argValue.get(), newPropertyValue.get());
- if (newPropertyValue->IsNull())
- continue;
-
- uCount++;
- double dValue = ValueToDouble(pThis, newPropertyValue.get());
- dMinValue = uCount == 1 ? dValue : std::min(dMinValue, dValue);
- } else {
- uCount++;
- double dValue = ValueToDouble(pThis, argValue.get());
- dMinValue = uCount == 1 ? dValue : std::min(dMinValue, dValue);
- }
- }
if (uCount == 0) {
- args.GetReturnValue()->SetNull();
+ info.GetReturnValue().SetNull();
return;
}
-
- args.GetReturnValue()->SetDouble(dMinValue);
+ info.GetReturnValue().Set(dMinValue);
}
// static
-void CFXJSE_FormCalcContext::Mod(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Mod(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 2) {
- pContext->ThrowParamCountMismatchException(L"Mod");
+ if (info.Length() != 2) {
+ pContext->ThrowParamCountMismatchException("Mod");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
- std::unique_ptr<CFXJSE_Value> argTwo = args.GetValue(1);
- if (argOne->IsNull() || argTwo->IsNull()) {
- args.GetReturnValue()->SetNull();
+ if (fxv8::IsNull(info[0]) || fxv8::IsNull(info[1])) {
+ info.GetReturnValue().SetNull();
return;
}
- bool argOneResult;
- double dDividend = ExtractDouble(pThis, argOne.get(), &argOneResult);
- bool argTwoResult;
- double dDivisor = ExtractDouble(pThis, argTwo.get(), &argTwoResult);
- if (!argOneResult || !argTwoResult) {
+ absl::optional<double> maybe_dividend =
+ ExtractDouble(info.GetIsolate(), info[0]);
+ absl::optional<double> maybe_divisor =
+ ExtractDouble(info.GetIsolate(), info[1]);
+ if (!maybe_dividend.has_value() || !maybe_divisor.has_value()) {
pContext->ThrowArgumentMismatchException();
return;
}
- if (dDivisor == 0.0) {
+ double dividend = maybe_dividend.value();
+ double divisor = maybe_divisor.value();
+ if (divisor == 0.0) {
pContext->ThrowDivideByZeroException();
return;
}
- args.GetReturnValue()->SetDouble(dDividend -
- dDivisor * (int32_t)(dDividend / dDivisor));
+ info.GetReturnValue().Set(dividend -
+ divisor * static_cast<int32_t>(dividend / divisor));
}
// static
-void CFXJSE_FormCalcContext::Round(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Round(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- int32_t argc = args.GetLength();
+ int32_t argc = info.Length();
if (argc < 1 || argc > 2) {
- pContext->ThrowParamCountMismatchException(L"Round");
+ pContext->ThrowParamCountMismatchException("Round");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
- if (argOne->IsNull()) {
- args.GetReturnValue()->SetNull();
+ if (fxv8::IsNull(info[0])) {
+ info.GetReturnValue().SetNull();
return;
}
- bool dValueRet;
- double dValue = ExtractDouble(pThis, argOne.get(), &dValueRet);
- if (!dValueRet) {
+ absl::optional<double> maybe_value =
+ ExtractDouble(info.GetIsolate(), info[0]);
+ if (!maybe_value.has_value()) {
pContext->ThrowArgumentMismatchException();
return;
}
+ double dValue = maybe_value.value();
uint8_t uPrecision = 0;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> argTwo = args.GetValue(1);
- if (argTwo->IsNull()) {
- args.GetReturnValue()->SetNull();
+ if (fxv8::IsNull(info[1])) {
+ info.GetReturnValue().SetNull();
return;
}
-
- bool dPrecisionRet;
- double dPrecision = ExtractDouble(pThis, argTwo.get(), &dPrecisionRet);
- if (!dPrecisionRet) {
+ absl::optional<double> maybe_precision =
+ ExtractDouble(info.GetIsolate(), info[1]);
+ if (!maybe_precision.has_value()) {
pContext->ThrowArgumentMismatchException();
return;
}
-
+ double dPrecision = maybe_precision.value();
uPrecision = static_cast<uint8_t>(pdfium::clamp(dPrecision, 0.0, 12.0));
}
CFGAS_Decimal decimalValue(static_cast<float>(dValue), uPrecision);
- args.GetReturnValue()->SetDouble(decimalValue.ToDouble());
+ info.GetReturnValue().Set(decimalValue.ToDouble());
}
// static
-void CFXJSE_FormCalcContext::Sum(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
- if (argc == 0) {
- args.GetReturnValue()->SetNull();
- return;
- }
-
- CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
+void CFXJSE_FormCalcContext::Sum(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
uint32_t uCount = 0;
double dSum = 0.0;
- for (int32_t i = 0; i < argc; i++) {
- std::unique_ptr<CFXJSE_Value> argValue = args.GetValue(i);
- if (argValue->IsNull())
- continue;
+ auto fn = [&uCount, &dSum](v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ ++uCount;
+ dSum += ValueToDouble(pIsolate, pValue);
+ };
+ if (!ToFormCalcContext(pThis)->ApplyToExpansion(fn, info, /*bStrict=*/true))
+ return;
- if (argValue->IsArray()) {
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValue->GetObjectProperty("length", lengthValue.get());
- int32_t iLength = lengthValue->ToInteger();
- if (iLength <= 2) {
- pContext->ThrowArgumentMismatchException();
- return;
- }
-
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValue->GetObjectPropertyByIdx(1, propertyValue.get());
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- if (propertyValue->IsNull()) {
- for (int32_t j = 2; j < iLength; j++) {
- argValue->GetObjectPropertyByIdx(j, jsObjectValue.get());
- GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
- if (newPropertyValue->IsNull())
- continue;
-
- dSum += ValueToDouble(pThis, jsObjectValue.get());
- uCount++;
- }
- } else {
- for (int32_t j = 2; j < iLength; j++) {
- argValue->GetObjectPropertyByIdx(j, jsObjectValue.get());
- jsObjectValue->GetObjectProperty(
- propertyValue->ToString().AsStringView(), newPropertyValue.get());
- if (newPropertyValue->IsNull())
- continue;
-
- dSum += ValueToDouble(pThis, newPropertyValue.get());
- uCount++;
- }
- }
- } else if (argValue->IsObject()) {
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(argValue.get(), newPropertyValue.get());
- if (newPropertyValue->IsNull())
- continue;
-
- dSum += ValueToDouble(pThis, argValue.get());
- uCount++;
- } else {
- dSum += ValueToDouble(pThis, argValue.get());
- uCount++;
- }
- }
if (uCount == 0) {
- args.GetReturnValue()->SetNull();
+ info.GetReturnValue().SetNull();
return;
}
-
- args.GetReturnValue()->SetDouble(dSum);
+ info.GetReturnValue().Set(dSum);
}
// static
-void CFXJSE_FormCalcContext::Date(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 0) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Date");
+void CFXJSE_FormCalcContext::Date(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 0) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Date");
return;
}
@@ -1835,140 +1926,141 @@
FXSYS_time(¤tTime);
struct tm* pTmStruct = gmtime(¤tTime);
- args.GetReturnValue()->SetInteger(DateString2Num(
+ info.GetReturnValue().Set(DateString2Num(
ByteString::Format("%d%02d%02d", pTmStruct->tm_year + 1900,
pTmStruct->tm_mon + 1, pTmStruct->tm_mday)
.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Date2Num(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Date2Num(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Date2Num");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Date2Num");
return;
}
- std::unique_ptr<CFXJSE_Value> dateValue = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, dateValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> dateValue = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), dateValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsDate = ValueToUTF8String(dateValue.get());
+ ByteString bsDate = ValueToUTF8String(info.GetIsolate(), dateValue);
ByteString bsFormat;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> formatValue = GetSimpleValue(pThis, args, 1);
- if (ValueIsNull(pThis, formatValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> formatValue = GetSimpleValue(info, 1);
+ if (ValueIsNull(info.GetIsolate(), formatValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsFormat = ValueToUTF8String(formatValue.get());
+ bsFormat = ValueToUTF8String(info.GetIsolate(), formatValue);
}
ByteString bsLocale;
if (argc > 2) {
- std::unique_ptr<CFXJSE_Value> localeValue = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, localeValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), localeValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsLocale = ValueToUTF8String(localeValue.get());
+ bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
}
ByteString bsIsoDate =
Local2IsoDate(pThis, bsDate.AsStringView(), bsFormat.AsStringView(),
bsLocale.AsStringView());
- args.GetReturnValue()->SetInteger(DateString2Num(bsIsoDate.AsStringView()));
+ info.GetReturnValue().Set(DateString2Num(bsIsoDate.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::DateFmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::DateFmt(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc > 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Date2Num");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Date2Num");
return;
}
int32_t iStyle = 0;
if (argc > 0) {
- std::unique_ptr<CFXJSE_Value> argStyle = GetSimpleValue(pThis, args, 0);
- if (argStyle->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> infotyle = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(infotyle)) {
+ info.GetReturnValue().SetNull();
return;
}
- iStyle = (int32_t)ValueToFloat(pThis, argStyle.get());
+ iStyle = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), infotyle));
if (iStyle < 0 || iStyle > 4)
iStyle = 0;
}
ByteString bsLocale;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> argLocale = GetSimpleValue(pThis, args, 1);
- if (argLocale->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argLocale = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argLocale)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsLocale = ValueToUTF8String(argLocale.get());
+ bsLocale = ValueToUTF8String(info.GetIsolate(), argLocale);
}
ByteString bsFormat =
GetStandardDateFormat(pThis, iStyle, bsLocale.AsStringView());
- args.GetReturnValue()->SetString(bsFormat.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsFormat.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::IsoDate2Num(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"IsoDate2Num");
+void CFXJSE_FormCalcContext::IsoDate2Num(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("IsoDate2Num");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (argOne->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsArg = ValueToUTF8String(argOne.get());
- args.GetReturnValue()->SetInteger(DateString2Num(bsArg.AsStringView()));
+ ByteString bsArg = ValueToUTF8String(info.GetIsolate(), argOne);
+ info.GetReturnValue().Set(DateString2Num(bsArg.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::IsoTime2Num(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::IsoTime2Num(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 1) {
- pContext->ThrowParamCountMismatchException(L"IsoTime2Num");
+ if (info.Length() != 1) {
+ pContext->ThrowParamCountMismatchException("IsoTime2Num");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, argOne.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
CXFA_Document* pDoc = pContext->GetDocument();
CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
- ByteString bsArg = ValueToUTF8String(argOne.get());
+ ByteString bsArg = ValueToUTF8String(info.GetIsolate(), argOne);
auto pos = bsArg.Find('T', 0);
if (!pos.has_value() || pos.value() == bsArg.GetLength() - 1) {
- args.GetReturnValue()->SetInteger(0);
+ info.GetReturnValue().Set(0);
return;
}
bsArg = bsArg.Last(bsArg.GetLength() - (pos.value() + 1));
- CXFA_LocaleValue timeValue(XFA_VT_TIME,
+ CXFA_LocaleValue timeValue(CXFA_LocaleValue::ValueType::kTime,
WideString::FromUTF8(bsArg.AsStringView()), pMgr);
if (!timeValue.IsValid()) {
- args.GetReturnValue()->SetInteger(0);
+ info.GetReturnValue().Set(0);
return;
}
@@ -1981,7 +2073,7 @@
// TODO(dsinclair): See if there is other time conversion code in pdfium and
// consolidate.
int32_t mins = hour * 60 + min;
- mins -= (pMgr->GetDefLocale()->GetTimeZone().tzHour * 60);
+ mins -= pMgr->GetDefLocale()->GetTimeZoneInMinutes();
while (mins > 1440)
mins -= 1440;
while (mins < 0)
@@ -1989,123 +2081,126 @@
hour = mins / 60;
min = mins % 60;
- args.GetReturnValue()->SetInteger(hour * 3600000 + min * 60000 +
- second * 1000 + milSecond + 1);
+ info.GetReturnValue().Set(hour * 3600000 + min * 60000 + second * 1000 +
+ milSecond + 1);
}
// static
-void CFXJSE_FormCalcContext::LocalDateFmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::LocalDateFmt(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc > 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"LocalDateFmt");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("LocalDateFmt");
return;
}
int32_t iStyle = 0;
if (argc > 0) {
- std::unique_ptr<CFXJSE_Value> argStyle = GetSimpleValue(pThis, args, 0);
- if (argStyle->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> infotyle = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(infotyle)) {
+ info.GetReturnValue().SetNull();
return;
}
- iStyle = (int32_t)ValueToFloat(pThis, argStyle.get());
+ iStyle = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), infotyle));
if (iStyle > 4 || iStyle < 0)
iStyle = 0;
}
ByteString bsLocale;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> argLocale = GetSimpleValue(pThis, args, 1);
- if (argLocale->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argLocale = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argLocale)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsLocale = ValueToUTF8String(argLocale.get());
+ bsLocale = ValueToUTF8String(info.GetIsolate(), argLocale);
}
ByteString bsFormat =
GetLocalDateFormat(pThis, iStyle, bsLocale.AsStringView(), false);
- args.GetReturnValue()->SetString(bsFormat.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsFormat.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::LocalTimeFmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::LocalTimeFmt(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc > 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"LocalTimeFmt");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("LocalTimeFmt");
return;
}
int32_t iStyle = 0;
if (argc > 0) {
- std::unique_ptr<CFXJSE_Value> argStyle = GetSimpleValue(pThis, args, 0);
- if (argStyle->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> infotyle = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(infotyle)) {
+ info.GetReturnValue().SetNull();
return;
}
- iStyle = (int32_t)ValueToFloat(pThis, argStyle.get());
+ iStyle = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), infotyle));
if (iStyle > 4 || iStyle < 0)
iStyle = 0;
}
ByteString bsLocale;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> argLocale = GetSimpleValue(pThis, args, 1);
- if (argLocale->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argLocale = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argLocale)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsLocale = ValueToUTF8String(argLocale.get());
+ bsLocale = ValueToUTF8String(info.GetIsolate(), argLocale);
}
ByteString bsFormat =
GetLocalTimeFormat(pThis, iStyle, bsLocale.AsStringView(), false);
- args.GetReturnValue()->SetString(bsFormat.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsFormat.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Num2Date(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Num2Date(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Num2Date");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Num2Date");
return;
}
- std::unique_ptr<CFXJSE_Value> dateValue = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, dateValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> dateValue = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), dateValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- int32_t dDate = (int32_t)ValueToFloat(pThis, dateValue.get());
+ int32_t dDate =
+ static_cast<int32_t>(ValueToFloat(info.GetIsolate(), dateValue));
if (dDate < 1) {
- args.GetReturnValue()->SetNull();
+ info.GetReturnValue().SetNull();
return;
}
ByteString bsFormat;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> formatValue = GetSimpleValue(pThis, args, 1);
- if (ValueIsNull(pThis, formatValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> formatValue = GetSimpleValue(info, 1);
+ if (ValueIsNull(info.GetIsolate(), formatValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsFormat = ValueToUTF8String(formatValue.get());
+ bsFormat = ValueToUTF8String(info.GetIsolate(), formatValue);
}
ByteString bsLocale;
if (argc > 2) {
- std::unique_ptr<CFXJSE_Value> localeValue = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, localeValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), localeValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsLocale = ValueToUTF8String(localeValue.get());
+ bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
}
int32_t iYear = 1900;
@@ -2204,242 +2299,247 @@
pThis,
ByteString::Format("%d%02d%02d", iYear + i, iMonth, iDay).AsStringView(),
bsFormat.AsStringView(), bsLocale.AsStringView());
- args.GetReturnValue()->SetString(bsLocalDate.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsLocalDate.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Num2GMTime(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Num2GMTime(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Num2GMTime");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Num2GMTime");
return;
}
- std::unique_ptr<CFXJSE_Value> timeValue = GetSimpleValue(pThis, args, 0);
- if (timeValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> timeValue = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(timeValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- int32_t iTime = (int32_t)ValueToFloat(pThis, timeValue.get());
+ int32_t iTime =
+ static_cast<int32_t>(ValueToFloat(info.GetIsolate(), timeValue));
if (abs(iTime) < 1.0) {
- args.GetReturnValue()->SetNull();
+ info.GetReturnValue().SetNull();
return;
}
ByteString bsFormat;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> formatValue = GetSimpleValue(pThis, args, 1);
- if (formatValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> formatValue = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(formatValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsFormat = ValueToUTF8String(formatValue.get());
+ bsFormat = ValueToUTF8String(info.GetIsolate(), formatValue);
}
ByteString bsLocale;
if (argc > 2) {
- std::unique_ptr<CFXJSE_Value> localeValue = GetSimpleValue(pThis, args, 2);
- if (localeValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
+ if (fxv8::IsNull(localeValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsLocale = ValueToUTF8String(localeValue.get());
+ bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
}
ByteString bsGMTTime = Num2AllTime(pThis, iTime, bsFormat.AsStringView(),
bsLocale.AsStringView(), true);
- args.GetReturnValue()->SetString(bsGMTTime.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsGMTTime.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Num2Time(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Num2Time(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Num2Time");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Num2Time");
return;
}
- std::unique_ptr<CFXJSE_Value> timeValue = GetSimpleValue(pThis, args, 0);
- if (timeValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> timeValue = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(timeValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- float fTime = ValueToFloat(pThis, timeValue.get());
+ float fTime = ValueToFloat(info.GetIsolate(), timeValue);
if (fabs(fTime) < 1.0) {
- args.GetReturnValue()->SetNull();
+ info.GetReturnValue().SetNull();
return;
}
ByteString bsFormat;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> formatValue = GetSimpleValue(pThis, args, 1);
- if (formatValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> formatValue = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(formatValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsFormat = ValueToUTF8String(formatValue.get());
+ bsFormat = ValueToUTF8String(info.GetIsolate(), formatValue);
}
ByteString bsLocale;
if (argc > 2) {
- std::unique_ptr<CFXJSE_Value> localeValue = GetSimpleValue(pThis, args, 2);
- if (localeValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
+ if (fxv8::IsNull(localeValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsLocale = ValueToUTF8String(localeValue.get());
+ bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
}
ByteString bsLocalTime =
Num2AllTime(pThis, static_cast<int32_t>(fTime), bsFormat.AsStringView(),
bsLocale.AsStringView(), false);
- args.GetReturnValue()->SetString(bsLocalTime.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsLocalTime.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Time(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 0) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Time");
+void CFXJSE_FormCalcContext::Time(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 0) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Time");
return;
}
time_t now;
FXSYS_time(&now);
-
struct tm* pGmt = gmtime(&now);
- args.GetReturnValue()->SetInteger(
+ info.GetReturnValue().Set(
(pGmt->tm_hour * 3600 + pGmt->tm_min * 60 + pGmt->tm_sec) * 1000);
}
// static
-void CFXJSE_FormCalcContext::Time2Num(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Time2Num(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Time2Num");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Time2Num");
return;
}
ByteString bsTime;
- std::unique_ptr<CFXJSE_Value> timeValue = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, timeValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> timeValue = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), timeValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsTime = ValueToUTF8String(timeValue.get());
+ bsTime = ValueToUTF8String(info.GetIsolate(), timeValue);
ByteString bsFormat;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> formatValue = GetSimpleValue(pThis, args, 1);
- if (ValueIsNull(pThis, formatValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> formatValue = GetSimpleValue(info, 1);
+ if (ValueIsNull(info.GetIsolate(), formatValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsFormat = ValueToUTF8String(formatValue.get());
+ bsFormat = ValueToUTF8String(info.GetIsolate(), formatValue);
}
ByteString bsLocale;
if (argc > 2) {
- std::unique_ptr<CFXJSE_Value> localeValue = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, localeValue.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), localeValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsLocale = ValueToUTF8String(localeValue.get());
+ bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
}
CXFA_Document* pDoc = ToFormCalcContext(pThis)->GetDocument();
CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
- LocaleIface* pLocale = nullptr;
- if (bsLocale.IsEmpty()) {
- CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
- pLocale = pThisNode->GetLocale();
- } else {
+ GCedLocaleIface* pLocale = nullptr;
+ if (!bsLocale.IsEmpty()) {
pLocale =
pMgr->GetLocaleByName(WideString::FromUTF8(bsLocale.AsStringView()));
}
+ if (!pLocale) {
+ CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
+ pLocale = pThisNode->GetLocale();
+ }
WideString wsFormat;
- if (bsFormat.IsEmpty())
- wsFormat = pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default);
- else
+ if (bsFormat.IsEmpty()) {
+ wsFormat =
+ pLocale->GetTimePattern(LocaleIface::DateTimeSubcategory::kDefault);
+ } else {
wsFormat = WideString::FromUTF8(bsFormat.AsStringView());
-
+ }
wsFormat = L"time{" + wsFormat + L"}";
- CXFA_LocaleValue localeValue(XFA_VT_TIME,
+ CXFA_LocaleValue localeValue(CXFA_LocaleValue::ValueType::kTime,
WideString::FromUTF8(bsTime.AsStringView()),
wsFormat, pLocale, pMgr);
if (!localeValue.IsValid()) {
- args.GetReturnValue()->SetInteger(0);
+ info.GetReturnValue().Set(0);
return;
}
CFX_DateTime uniTime = localeValue.GetTime();
int32_t hour = uniTime.GetHour();
- int32_t min = uniTime.GetMinute();
- int32_t second = uniTime.GetSecond();
- int32_t milSecond = uniTime.GetMillisecond();
- int32_t mins = hour * 60 + min;
+ int32_t minute = uniTime.GetMinute();
+ const int32_t second = uniTime.GetSecond();
+ const int32_t millisecond = uniTime.GetMillisecond();
- mins -= (CXFA_TimeZoneProvider().GetTimeZone().tzHour * 60);
- while (mins > 1440)
- mins -= 1440;
+ constexpr int kMinutesInDay = 24 * 60;
+ int32_t minutes_with_tz =
+ hour * 60 + minute - CXFA_TimeZoneProvider().GetTimeZoneInMinutes();
+ minutes_with_tz %= kMinutesInDay;
+ if (minutes_with_tz < 0)
+ minutes_with_tz += kMinutesInDay;
- while (mins < 0)
- mins += 1440;
-
- hour = mins / 60;
- min = mins % 60;
- args.GetReturnValue()->SetInteger(hour * 3600000 + min * 60000 +
- second * 1000 + milSecond + 1);
+ hour = minutes_with_tz / 60;
+ minute = minutes_with_tz % 60;
+ info.GetReturnValue().Set(hour * 3600000 + minute * 60000 + second * 1000 +
+ millisecond + 1);
}
// static
-void CFXJSE_FormCalcContext::TimeFmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::TimeFmt(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc > 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"TimeFmt");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("TimeFmt");
return;
}
int32_t iStyle = 0;
if (argc > 0) {
- std::unique_ptr<CFXJSE_Value> argStyle = GetSimpleValue(pThis, args, 0);
- if (argStyle->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> infotyle = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(infotyle)) {
+ info.GetReturnValue().SetNull();
return;
}
- iStyle = (int32_t)ValueToFloat(pThis, argStyle.get());
+ iStyle = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), infotyle));
if (iStyle > 4 || iStyle < 0)
iStyle = 0;
}
ByteString bsLocale;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> argLocale = GetSimpleValue(pThis, args, 1);
- if (argLocale->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argLocale = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argLocale)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsLocale = ValueToUTF8String(argLocale.get());
+ bsLocale = ValueToUTF8String(info.GetIsolate(), argLocale);
}
ByteString bsFormat =
GetStandardTimeFormat(pThis, iStyle, bsLocale.AsStringView());
- args.GetReturnValue()->SetString(bsFormat.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsFormat.AsStringView()));
}
// static
-ByteString CFXJSE_FormCalcContext::Local2IsoDate(CFXJSE_Value* pThis,
+ByteString CFXJSE_FormCalcContext::Local2IsoDate(CFXJSE_HostObject* pThis,
ByteStringView bsDate,
ByteStringView bsFormat,
ByteStringView bsLocale) {
@@ -2448,21 +2548,22 @@
return ByteString();
CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
- LocaleIface* pLocale = LocaleFromString(pDoc, pMgr, bsLocale);
+ GCedLocaleIface* pLocale = LocaleFromString(pDoc, pMgr, bsLocale);
if (!pLocale)
return ByteString();
WideString wsFormat = FormatFromString(pLocale, bsFormat);
- CFX_DateTime dt = CXFA_LocaleValue(XFA_VT_DATE, WideString::FromUTF8(bsDate),
- wsFormat, pLocale, pMgr)
- .GetDate();
+ CFX_DateTime dt =
+ CXFA_LocaleValue(CXFA_LocaleValue::ValueType::kDate,
+ WideString::FromUTF8(bsDate), wsFormat, pLocale, pMgr)
+ .GetDate();
return ByteString::Format("%4d-%02d-%02d", dt.GetYear(), dt.GetMonth(),
dt.GetDay());
}
// static
-ByteString CFXJSE_FormCalcContext::IsoDate2Local(CFXJSE_Value* pThis,
+ByteString CFXJSE_FormCalcContext::IsoDate2Local(CFXJSE_HostObject* pThis,
ByteStringView bsDate,
ByteStringView bsFormat,
ByteStringView bsLocale) {
@@ -2471,19 +2572,20 @@
return ByteString();
CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
- LocaleIface* pLocale = LocaleFromString(pDoc, pMgr, bsLocale);
+ GCedLocaleIface* pLocale = LocaleFromString(pDoc, pMgr, bsLocale);
if (!pLocale)
return ByteString();
WideString wsFormat = FormatFromString(pLocale, bsFormat);
WideString wsRet;
- CXFA_LocaleValue(XFA_VT_DATE, WideString::FromUTF8(bsDate), pMgr)
- .FormatPatterns(wsRet, wsFormat, pLocale, XFA_VALUEPICTURE_Display);
+ CXFA_LocaleValue(CXFA_LocaleValue::ValueType::kDate,
+ WideString::FromUTF8(bsDate), pMgr)
+ .FormatPatterns(wsRet, wsFormat, pLocale, XFA_ValuePicture::kDisplay);
return wsRet.ToUTF8();
}
// static
-ByteString CFXJSE_FormCalcContext::IsoTime2Local(CFXJSE_Value* pThis,
+ByteString CFXJSE_FormCalcContext::IsoTime2Local(CFXJSE_HostObject* pThis,
ByteStringView bsTime,
ByteStringView bsFormat,
ByteStringView bsLocale) {
@@ -2492,21 +2594,22 @@
return ByteString();
CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
- LocaleIface* pLocale = LocaleFromString(pDoc, pMgr, bsLocale);
+ GCedLocaleIface* pLocale = LocaleFromString(pDoc, pMgr, bsLocale);
if (!pLocale)
return ByteString();
WideString wsFormat = {
L"time{", FormatFromString(pLocale, bsFormat).AsStringView(), L"}"};
- CXFA_LocaleValue widgetValue(XFA_VT_TIME, WideString::FromUTF8(bsTime), pMgr);
+ CXFA_LocaleValue widgetValue(CXFA_LocaleValue::ValueType::kTime,
+ WideString::FromUTF8(bsTime), pMgr);
WideString wsRet;
widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
- XFA_VALUEPICTURE_Display);
+ XFA_ValuePicture::kDisplay);
return wsRet.ToUTF8();
}
// static
-ByteString CFXJSE_FormCalcContext::GetLocalDateFormat(CFXJSE_Value* pThis,
+ByteString CFXJSE_FormCalcContext::GetLocalDateFormat(CFXJSE_HostObject* pThis,
int32_t iStyle,
ByteStringView bsLocale,
bool bStandard) {
@@ -2519,7 +2622,7 @@
}
// static
-ByteString CFXJSE_FormCalcContext::GetLocalTimeFormat(CFXJSE_Value* pThis,
+ByteString CFXJSE_FormCalcContext::GetLocalTimeFormat(CFXJSE_HostObject* pThis,
int32_t iStyle,
ByteStringView bsLocale,
bool bStandard) {
@@ -2533,7 +2636,7 @@
// static
ByteString CFXJSE_FormCalcContext::GetStandardDateFormat(
- CFXJSE_Value* pThis,
+ CFXJSE_HostObject* pThis,
int32_t iStyle,
ByteStringView bsLocale) {
return GetLocalDateFormat(pThis, iStyle, bsLocale, true);
@@ -2541,14 +2644,14 @@
// static
ByteString CFXJSE_FormCalcContext::GetStandardTimeFormat(
- CFXJSE_Value* pThis,
+ CFXJSE_HostObject* pThis,
int32_t iStyle,
ByteStringView bsLocale) {
return GetLocalTimeFormat(pThis, iStyle, bsLocale, true);
}
// static
-ByteString CFXJSE_FormCalcContext::Num2AllTime(CFXJSE_Value* pThis,
+ByteString CFXJSE_FormCalcContext::Num2AllTime(CFXJSE_HostObject* pThis,
int32_t iTime,
ByteStringView bsFormat,
ByteStringView bsLocale,
@@ -2577,28 +2680,29 @@
}
// static
-void CFXJSE_FormCalcContext::Apr(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Apr(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 3) {
- pContext->ThrowParamCountMismatchException(L"Apr");
+ if (info.Length() != 3) {
+ pContext->ThrowParamCountMismatchException("Apr");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
- ValueIsNull(pThis, argThree.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo) ||
+ ValueIsNull(info.GetIsolate(), argThree)) {
+ info.GetReturnValue().SetNull();
return;
}
- double nPrincipal = ValueToDouble(pThis, argOne.get());
- double nPayment = ValueToDouble(pThis, argTwo.get());
- double nPeriods = ValueToDouble(pThis, argThree.get());
- if (nPrincipal <= 0 || nPayment <= 0 || nPeriods <= 0) {
+ double nPrincipal = ValueToDouble(info.GetIsolate(), argOne);
+ double nPayment = ValueToDouble(info.GetIsolate(), argTwo);
+ int nPeriods = GetValidatedPaymentPeriods(info.GetIsolate(), argThree);
+ if (nPrincipal <= 0 || nPayment <= 0 || nPeriods == 0) {
pContext->ThrowArgumentMismatchException();
return;
}
@@ -2615,7 +2719,7 @@
(r * nTemp * nPeriods * (nTemp / (1 + r)))) /
((nTemp - 1) * (nTemp - 1));
if (nDerivative == 0) {
- args.GetReturnValue()->SetNull();
+ info.GetReturnValue().SetNull();
return;
}
@@ -2626,63 +2730,65 @@
}
nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
}
- args.GetReturnValue()->SetDouble(r * 12);
+ info.GetReturnValue().Set(r * 12);
}
// static
-void CFXJSE_FormCalcContext::CTerm(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::CTerm(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 3) {
- pContext->ThrowParamCountMismatchException(L"CTerm");
+ if (info.Length() != 3) {
+ pContext->ThrowParamCountMismatchException("CTerm");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
- ValueIsNull(pThis, argThree.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo) ||
+ ValueIsNull(info.GetIsolate(), argThree)) {
+ info.GetReturnValue().SetNull();
return;
}
- float nRate = ValueToFloat(pThis, argOne.get());
- float nFutureValue = ValueToFloat(pThis, argTwo.get());
- float nInitAmount = ValueToFloat(pThis, argThree.get());
+ float nRate = ValueToFloat(info.GetIsolate(), argOne);
+ float nFutureValue = ValueToFloat(info.GetIsolate(), argTwo);
+ float nInitAmount = ValueToFloat(info.GetIsolate(), argThree);
if ((nRate <= 0) || (nFutureValue <= 0) || (nInitAmount <= 0)) {
pContext->ThrowArgumentMismatchException();
return;
}
- args.GetReturnValue()->SetFloat(log((float)(nFutureValue / nInitAmount)) /
- log((float)(1 + nRate)));
+ info.GetReturnValue().Set(log((float)(nFutureValue / nInitAmount)) /
+ log((float)(1 + nRate)));
}
// static
-void CFXJSE_FormCalcContext::FV(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::FV(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 3) {
- pContext->ThrowParamCountMismatchException(L"FV");
+ if (info.Length() != 3) {
+ pContext->ThrowParamCountMismatchException("FV");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
- ValueIsNull(pThis, argThree.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo) ||
+ ValueIsNull(info.GetIsolate(), argThree)) {
+ info.GetReturnValue().SetNull();
return;
}
- double nAmount = ValueToDouble(pThis, argOne.get());
- double nRate = ValueToDouble(pThis, argTwo.get());
- double nPeriod = ValueToDouble(pThis, argThree.get());
- if ((nRate < 0) || (nPeriod <= 0) || (nAmount <= 0)) {
+ double nAmount = ValueToDouble(info.GetIsolate(), argOne);
+ double nRate = ValueToDouble(info.GetIsolate(), argTwo);
+ int nPeriods = GetValidatedPaymentPeriods(info.GetIsolate(), argThree);
+ if (nAmount <= 0 || nRate < 0 || nPeriods == 0) {
pContext->ThrowArgumentMismatchException();
return;
}
@@ -2690,44 +2796,46 @@
double dResult = 0;
if (nRate) {
double nTemp = 1;
- for (int i = 0; i < nPeriod; ++i) {
+ for (int i = 0; i < nPeriods; ++i) {
nTemp *= 1 + nRate;
}
dResult = nAmount * (nTemp - 1) / nRate;
} else {
- dResult = nAmount * nPeriod;
+ dResult = nAmount * nPeriods;
}
- args.GetReturnValue()->SetDouble(dResult);
+ info.GetReturnValue().Set(dResult);
}
// static
-void CFXJSE_FormCalcContext::IPmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::IPmt(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 5) {
- pContext->ThrowParamCountMismatchException(L"IPmt");
+ if (info.Length() != 5) {
+ pContext->ThrowParamCountMismatchException("IPmt");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- std::unique_ptr<CFXJSE_Value> argFour = GetSimpleValue(pThis, args, 3);
- std::unique_ptr<CFXJSE_Value> argFive = GetSimpleValue(pThis, args, 4);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
- ValueIsNull(pThis, argThree.get()) || ValueIsNull(pThis, argFour.get()) ||
- ValueIsNull(pThis, argFive.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ v8::Local<v8::Value> argFour = GetSimpleValue(info, 3);
+ v8::Local<v8::Value> argFive = GetSimpleValue(info, 4);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo) ||
+ ValueIsNull(info.GetIsolate(), argThree) ||
+ ValueIsNull(info.GetIsolate(), argFour) ||
+ ValueIsNull(info.GetIsolate(), argFive)) {
+ info.GetReturnValue().SetNull();
return;
}
- float nPrincipalAmount = ValueToFloat(pThis, argOne.get());
- float nRate = ValueToFloat(pThis, argTwo.get());
- float nPayment = ValueToFloat(pThis, argThree.get());
- float nFirstMonth = ValueToFloat(pThis, argFour.get());
- float nNumberOfMonths = ValueToFloat(pThis, argFive.get());
+ float nPrincipalAmount = ValueToFloat(info.GetIsolate(), argOne);
+ float nRate = ValueToFloat(info.GetIsolate(), argTwo);
+ float nPayment = ValueToFloat(info.GetIsolate(), argThree);
+ float nFirstMonth = ValueToFloat(info.GetIsolate(), argFour);
+ float nNumberOfMonths = ValueToFloat(info.GetIsolate(), argFive);
if ((nPrincipalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
(nFirstMonth < 0) || (nNumberOfMonths < 0)) {
pContext->ThrowArgumentMismatchException();
@@ -2735,14 +2843,15 @@
}
float nRateOfMonth = nRate / 12;
- int32_t iNums =
- (int32_t)((log10((float)(nPayment / nPrincipalAmount)) -
- log10((float)(nPayment / nPrincipalAmount - nRateOfMonth))) /
- log10((float)(1 + nRateOfMonth)));
- int32_t iEnd = std::min((int32_t)(nFirstMonth + nNumberOfMonths - 1), iNums);
+ int32_t iNums = static_cast<int32_t>(
+ (log10((float)(nPayment / nPrincipalAmount)) -
+ log10((float)(nPayment / nPrincipalAmount - nRateOfMonth))) /
+ log10((float)(1 + nRateOfMonth)));
+ int32_t iEnd =
+ std::min(static_cast<int32_t>(nFirstMonth + nNumberOfMonths - 1), iNums);
if (nPayment < nPrincipalAmount * nRateOfMonth) {
- args.GetReturnValue()->SetFloat(0);
+ info.GetReturnValue().Set(0);
return;
}
@@ -2755,114 +2864,113 @@
nSum += nPrincipalAmount * nRateOfMonth;
nPrincipalAmount -= nPayment - nPrincipalAmount * nRateOfMonth;
}
- args.GetReturnValue()->SetFloat(nSum);
+ info.GetReturnValue().Set(nSum);
}
// static
-void CFXJSE_FormCalcContext::NPV(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::NPV(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- int32_t argc = args.GetLength();
- if (argc < 3) {
- pContext->ThrowParamCountMismatchException(L"NPV");
+ int32_t argc = info.Length();
+ if (argc < 2) {
+ pContext->ThrowParamCountMismatchException("NPV");
return;
}
- std::vector<std::unique_ptr<CFXJSE_Value>> argValues;
- for (int32_t i = 0; i < argc; i++) {
- argValues.push_back(GetSimpleValue(pThis, args, i));
- if (ValueIsNull(pThis, argValues[i].get())) {
- args.GetReturnValue()->SetNull();
- return;
- }
+ v8::Local<v8::Value> argValue = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argValue)) {
+ info.GetReturnValue().SetNull();
+ return;
}
- double nRate = ValueToDouble(pThis, argValues[0].get());
+ double nRate = ValueToDouble(info.GetIsolate(), argValue);
if (nRate <= 0) {
pContext->ThrowArgumentMismatchException();
return;
}
- std::vector<double> data(argc - 1);
- for (int32_t i = 1; i < argc; i++)
- data.push_back(ValueToDouble(pThis, argValues[i].get()));
+ std::vector<double> data;
+ for (int32_t i = 1; i < argc; i++) {
+ argValue = GetSimpleValue(info, i);
+ if (ValueIsNull(info.GetIsolate(), argValue)) {
+ info.GetReturnValue().SetNull();
+ return;
+ }
+ data.push_back(ValueToDouble(info.GetIsolate(), argValue));
+ }
double nSum = 0;
- int32_t iIndex = 0;
- for (int32_t i = 0; i < argc - 1; i++) {
- double nTemp = 1;
- for (int32_t j = 0; j <= i; j++)
- nTemp *= 1 + nRate;
-
- double nNum = data[iIndex++];
- nSum += nNum / nTemp;
+ double nDivisor = 1.0 + nRate;
+ while (!data.empty()) {
+ nSum += data.back();
+ nSum /= nDivisor;
+ data.pop_back();
}
- args.GetReturnValue()->SetDouble(nSum);
+ info.GetReturnValue().Set(nSum);
}
// static
-void CFXJSE_FormCalcContext::Pmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Pmt(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 3) {
- pContext->ThrowParamCountMismatchException(L"Pmt");
+ if (info.Length() != 3) {
+ pContext->ThrowParamCountMismatchException("Pmt");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
- ValueIsNull(pThis, argThree.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo) ||
+ ValueIsNull(info.GetIsolate(), argThree)) {
+ info.GetReturnValue().SetNull();
return;
}
- float nPrincipal = ValueToFloat(pThis, argOne.get());
- float nRate = ValueToFloat(pThis, argTwo.get());
- float nPeriods = ValueToFloat(pThis, argThree.get());
- if ((nPrincipal <= 0) || (nRate <= 0) || (nPeriods <= 0)) {
+ double nPrincipal = ValueToDouble(info.GetIsolate(), argOne);
+ double nRate = ValueToDouble(info.GetIsolate(), argTwo);
+ int nPeriods = GetValidatedPaymentPeriods(info.GetIsolate(), argThree);
+ if (nPrincipal <= 0 || nRate <= 0 || nPeriods == 0) {
pContext->ThrowArgumentMismatchException();
return;
}
- float nTmp = 1 + nRate;
- float nSum = nTmp;
- for (int32_t i = 0; i < nPeriods - 1; ++i)
- nSum *= nTmp;
-
- args.GetReturnValue()->SetFloat((nPrincipal * nRate * nSum) / (nSum - 1));
+ double nSum = pow(1.0 + nRate, nPeriods);
+ info.GetReturnValue().Set((nPrincipal * nRate * nSum) / (nSum - 1));
}
// static
-void CFXJSE_FormCalcContext::PPmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::PPmt(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 5) {
- pContext->ThrowParamCountMismatchException(L"PPmt");
+ if (info.Length() != 5) {
+ pContext->ThrowParamCountMismatchException("PPmt");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- std::unique_ptr<CFXJSE_Value> argFour = GetSimpleValue(pThis, args, 3);
- std::unique_ptr<CFXJSE_Value> argFive = GetSimpleValue(pThis, args, 4);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
- ValueIsNull(pThis, argThree.get()) || ValueIsNull(pThis, argFour.get()) ||
- ValueIsNull(pThis, argFive.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ v8::Local<v8::Value> argFour = GetSimpleValue(info, 3);
+ v8::Local<v8::Value> argFive = GetSimpleValue(info, 4);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo) ||
+ ValueIsNull(info.GetIsolate(), argThree) ||
+ ValueIsNull(info.GetIsolate(), argFour) ||
+ ValueIsNull(info.GetIsolate(), argFive)) {
+ info.GetReturnValue().SetNull();
return;
}
- float nPrincipalAmount = ValueToFloat(pThis, argOne.get());
- float nRate = ValueToFloat(pThis, argTwo.get());
- float nPayment = ValueToFloat(pThis, argThree.get());
- float nFirstMonth = ValueToFloat(pThis, argFour.get());
- float nNumberOfMonths = ValueToFloat(pThis, argFive.get());
+ float nPrincipalAmount = ValueToFloat(info.GetIsolate(), argOne);
+ float nRate = ValueToFloat(info.GetIsolate(), argTwo);
+ float nPayment = ValueToFloat(info.GetIsolate(), argThree);
+ float nFirstMonth = ValueToFloat(info.GetIsolate(), argFour);
+ float nNumberOfMonths = ValueToFloat(info.GetIsolate(), argFive);
if ((nPrincipalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
(nFirstMonth < 0) || (nNumberOfMonths < 0)) {
pContext->ThrowArgumentMismatchException();
@@ -2870,11 +2978,12 @@
}
float nRateOfMonth = nRate / 12;
- int32_t iNums =
- (int32_t)((log10((float)(nPayment / nPrincipalAmount)) -
- log10((float)(nPayment / nPrincipalAmount - nRateOfMonth))) /
- log10((float)(1 + nRateOfMonth)));
- int32_t iEnd = std::min((int32_t)(nFirstMonth + nNumberOfMonths - 1), iNums);
+ int32_t iNums = static_cast<int32_t>(
+ (log10((float)(nPayment / nPrincipalAmount)) -
+ log10((float)(nPayment / nPrincipalAmount - nRateOfMonth))) /
+ log10((float)(1 + nRateOfMonth)));
+ int32_t iEnd =
+ std::min(static_cast<int32_t>(nFirstMonth + nNumberOfMonths - 1), iNums);
if (nPayment < nPrincipalAmount * nRateOfMonth) {
pContext->ThrowArgumentMismatchException();
return;
@@ -2891,126 +3000,124 @@
nSum += nTemp;
nPrincipalAmount -= nTemp;
}
- args.GetReturnValue()->SetFloat(nSum);
+ info.GetReturnValue().Set(nSum);
}
// static
-void CFXJSE_FormCalcContext::PV(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::PV(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 3) {
- pContext->ThrowParamCountMismatchException(L"PV");
+ if (info.Length() != 3) {
+ pContext->ThrowParamCountMismatchException("PV");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
- ValueIsNull(pThis, argThree.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo) ||
+ ValueIsNull(info.GetIsolate(), argThree)) {
+ info.GetReturnValue().SetNull();
return;
}
- double nAmount = ValueToDouble(pThis, argOne.get());
- double nRate = ValueToDouble(pThis, argTwo.get());
- double nPeriod = ValueToDouble(pThis, argThree.get());
- if ((nAmount <= 0) || (nRate < 0) || (nPeriod <= 0)) {
+ double nAmount = ValueToDouble(info.GetIsolate(), argOne);
+ double nRate = ValueToDouble(info.GetIsolate(), argTwo);
+ int nPeriods = GetValidatedPaymentPeriods(info.GetIsolate(), argThree);
+ if (nAmount <= 0 || nRate < 0 || nPeriods == 0) {
pContext->ThrowArgumentMismatchException();
return;
}
- double nTemp = 1;
- for (int32_t i = 0; i < nPeriod; ++i)
- nTemp *= 1 + nRate;
-
- nTemp = 1 / nTemp;
- args.GetReturnValue()->SetDouble(nAmount * ((1 - nTemp) / nRate));
+ double nTemp = 1 / pow(1.0 + nRate, nPeriods);
+ info.GetReturnValue().Set(nAmount * ((1.0 - nTemp) / nRate));
}
// static
-void CFXJSE_FormCalcContext::Rate(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Rate(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 3) {
- pContext->ThrowParamCountMismatchException(L"Rate");
+ if (info.Length() != 3) {
+ pContext->ThrowParamCountMismatchException("Rate");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
- ValueIsNull(pThis, argThree.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo) ||
+ ValueIsNull(info.GetIsolate(), argThree)) {
+ info.GetReturnValue().SetNull();
return;
}
- float nFuture = ValueToFloat(pThis, argOne.get());
- float nPresent = ValueToFloat(pThis, argTwo.get());
- float nTotalNumber = ValueToFloat(pThis, argThree.get());
- if ((nFuture <= 0) || (nPresent < 0) || (nTotalNumber <= 0)) {
+ float nFuture = ValueToFloat(info.GetIsolate(), argOne);
+ float nPresent = ValueToFloat(info.GetIsolate(), argTwo);
+ int nPeriods = GetValidatedPaymentPeriods(info.GetIsolate(), argThree);
+ if (nFuture <= 0 || nPresent < 0 || nPeriods == 0) {
pContext->ThrowArgumentMismatchException();
return;
}
- args.GetReturnValue()->SetFloat(
- FXSYS_pow((float)(nFuture / nPresent), (float)(1 / nTotalNumber)) - 1);
+ info.GetReturnValue().Set(powf(nFuture / nPresent, 1.0f / nPeriods) - 1.0f);
}
// static
-void CFXJSE_FormCalcContext::Term(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Term(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 3) {
- pContext->ThrowParamCountMismatchException(L"Term");
+ if (info.Length() != 3) {
+ pContext->ThrowParamCountMismatchException("Term");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get()) ||
- ValueIsNull(pThis, argThree.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo) ||
+ ValueIsNull(info.GetIsolate(), argThree)) {
+ info.GetReturnValue().SetNull();
return;
}
- float nMount = ValueToFloat(pThis, argOne.get());
- float nRate = ValueToFloat(pThis, argTwo.get());
- float nFuture = ValueToFloat(pThis, argThree.get());
+ float nMount = ValueToFloat(info.GetIsolate(), argOne);
+ float nRate = ValueToFloat(info.GetIsolate(), argTwo);
+ float nFuture = ValueToFloat(info.GetIsolate(), argThree);
if ((nMount <= 0) || (nRate <= 0) || (nFuture <= 0)) {
pContext->ThrowArgumentMismatchException();
return;
}
- args.GetReturnValue()->SetFloat(log((float)(nFuture / nMount * nRate) + 1) /
- log((float)(1 + nRate)));
+ info.GetReturnValue().Set(log((float)(nFuture / nMount * nRate) + 1) /
+ log((float)(1 + nRate)));
}
// static
-void CFXJSE_FormCalcContext::Choose(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Choose(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- int32_t argc = args.GetLength();
+ int32_t argc = info.Length();
if (argc < 2) {
- pContext->ThrowParamCountMismatchException(L"Choose");
+ pContext->ThrowParamCountMismatchException("Choose");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
- if (ValueIsNull(pThis, argOne.get())) {
- args.GetReturnValue()->SetNull();
+ if (ValueIsNull(info.GetIsolate(), info[0])) {
+ info.GetReturnValue().SetNull();
return;
}
- int32_t iIndex = (int32_t)ValueToFloat(pThis, argOne.get());
+ int32_t iIndex =
+ static_cast<int32_t>(ValueToFloat(info.GetIsolate(), info[0]));
if (iIndex < 1) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
@@ -3018,268 +3125,261 @@
bool bStopCounterFlags = false;
int32_t iArgIndex = 1;
int32_t iValueIndex = 0;
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
while (!bFound && !bStopCounterFlags && (iArgIndex < argc)) {
- std::unique_ptr<CFXJSE_Value> argIndexValue = args.GetValue(iArgIndex);
- if (argIndexValue->IsArray()) {
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argIndexValue->GetObjectProperty("length", lengthValue.get());
- int32_t iLength = lengthValue->ToInteger();
+ v8::Local<v8::Value> argIndexValue = info[iArgIndex];
+ if (fxv8::IsArray(argIndexValue)) {
+ v8::Local<v8::Array> arr = argIndexValue.As<v8::Array>();
+ uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
if (iLength > 3)
bStopCounterFlags = true;
iValueIndex += (iLength - 2);
if (iValueIndex >= iIndex) {
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argIndexValue->GetObjectPropertyByIdx(1, propertyValue.get());
- argIndexValue->GetObjectPropertyByIdx(
- (iLength - 1) - (iValueIndex - iIndex), jsObjectValue.get());
- if (propertyValue->IsNull()) {
- GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
- } else {
- jsObjectValue->GetObjectProperty(
- propertyValue->ToString().AsStringView(), newPropertyValue.get());
+ v8::Local<v8::Value> propertyValue =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 1);
+ v8::Local<v8::Value> jsValue = fxv8::ReentrantGetArrayElementHelper(
+ info.GetIsolate(), arr, (iLength - 1) - (iValueIndex - iIndex));
+ v8::Local<v8::Value> newPropertyValue;
+ if (fxv8::IsObject(jsValue)) {
+ v8::Local<v8::Object> jsObjectValue = jsValue.As<v8::Object>();
+ if (fxv8::IsNull(propertyValue)) {
+ newPropertyValue =
+ GetObjectDefaultValue(info.GetIsolate(), jsObjectValue);
+ } else {
+ ByteString bsName = fxv8::ReentrantToByteStringHelper(
+ info.GetIsolate(), propertyValue);
+ newPropertyValue = fxv8::ReentrantGetObjectPropertyHelper(
+ info.GetIsolate(), jsObjectValue, bsName.AsStringView());
+ }
}
- ByteString bsChosen = ValueToUTF8String(newPropertyValue.get());
- args.GetReturnValue()->SetString(bsChosen.AsStringView());
+ ByteString bsChosen =
+ ValueToUTF8String(info.GetIsolate(), newPropertyValue);
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsChosen.AsStringView()));
bFound = true;
}
} else {
iValueIndex++;
if (iValueIndex == iIndex) {
- ByteString bsChosen = ValueToUTF8String(argIndexValue.get());
- args.GetReturnValue()->SetString(bsChosen.AsStringView());
+ ByteString bsChosen =
+ ValueToUTF8String(info.GetIsolate(), argIndexValue);
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsChosen.AsStringView()));
bFound = true;
}
}
iArgIndex++;
}
if (!bFound)
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
}
// static
-void CFXJSE_FormCalcContext::Exists(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Exists");
+void CFXJSE_FormCalcContext::Exists(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Exists");
return;
}
- args.GetReturnValue()->SetInteger(args.GetValue(0)->IsObject());
+ info.GetReturnValue().Set(fxv8::IsObject(info[0]));
}
// static
-void CFXJSE_FormCalcContext::HasValue(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"HasValue");
+void CFXJSE_FormCalcContext::HasValue(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("HasValue");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (!argOne->IsString()) {
- args.GetReturnValue()->SetInteger(argOne->IsNumber() ||
- argOne->IsBoolean());
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (!fxv8::IsString(argOne)) {
+ info.GetReturnValue().Set(
+ static_cast<int>(fxv8::IsNumber(argOne) || fxv8::IsBoolean(argOne)));
return;
}
- ByteString bsValue = argOne->ToString();
+ ByteString bsValue =
+ fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argOne);
bsValue.TrimLeft();
- args.GetReturnValue()->SetInteger(!bsValue.IsEmpty());
+ info.GetReturnValue().Set(static_cast<int>(!bsValue.IsEmpty()));
}
// static
-void CFXJSE_FormCalcContext::Oneof(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() < 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Oneof");
+void CFXJSE_FormCalcContext::Oneof(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() < 2) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Oneof");
return;
}
- 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) {
- if (simpleValueCompare(pThis, argOne.get(), value.get())) {
- bFlags = true;
- break;
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ for (const auto& value : UnfoldArgs(info)) {
+ if (SimpleValueCompare(info.GetIsolate(), argOne, value)) {
+ info.GetReturnValue().Set(1);
+ return;
}
}
-
- args.GetReturnValue()->SetInteger(bFlags);
+ info.GetReturnValue().Set(0);
}
// static
-void CFXJSE_FormCalcContext::Within(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Within");
+void CFXJSE_FormCalcContext::Within(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 3) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Within");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (argOne->IsNull()) {
- args.GetReturnValue()->SetUndefined();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(argOne)) {
+ info.GetReturnValue().SetUndefined();
return;
}
- std::unique_ptr<CFXJSE_Value> argLow = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> argHigh = GetSimpleValue(pThis, args, 2);
- if (argOne->IsNumber()) {
- float oneNumber = ValueToFloat(pThis, argOne.get());
- float lowNumber = ValueToFloat(pThis, argLow.get());
- float heightNumber = ValueToFloat(pThis, argHigh.get());
- args.GetReturnValue()->SetInteger((oneNumber >= lowNumber) &&
- (oneNumber <= heightNumber));
+ v8::Local<v8::Value> argLow = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> argHigh = GetSimpleValue(info, 2);
+ if (fxv8::IsNumber(argOne)) {
+ float oneNumber = ValueToFloat(info.GetIsolate(), argOne);
+ float lowNumber = ValueToFloat(info.GetIsolate(), argLow);
+ float heightNumber = ValueToFloat(info.GetIsolate(), argHigh);
+ info.GetReturnValue().Set(static_cast<int>((oneNumber >= lowNumber) &&
+ (oneNumber <= heightNumber)));
return;
}
- ByteString bsOne = ValueToUTF8String(argOne.get());
- ByteString bsLow = ValueToUTF8String(argLow.get());
- ByteString bsHeight = ValueToUTF8String(argHigh.get());
- args.GetReturnValue()->SetInteger(
- (bsOne.Compare(bsLow.AsStringView()) >= 0) &&
- (bsOne.Compare(bsHeight.AsStringView()) <= 0));
+ ByteString bsOne = ValueToUTF8String(info.GetIsolate(), argOne);
+ ByteString bsLow = ValueToUTF8String(info.GetIsolate(), argLow);
+ ByteString bsHeight = ValueToUTF8String(info.GetIsolate(), argHigh);
+ info.GetReturnValue().Set(
+ static_cast<int>((bsOne.Compare(bsLow.AsStringView()) >= 0) &&
+ (bsOne.Compare(bsHeight.AsStringView()) <= 0)));
}
// static
-void CFXJSE_FormCalcContext::If(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"If");
+void CFXJSE_FormCalcContext::If(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 3) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("If");
return;
}
- args.GetReturnValue()->Assign(GetSimpleValue(pThis, args, 0)->ToBoolean()
- ? GetSimpleValue(pThis, args, 1).get()
- : GetSimpleValue(pThis, args, 2).get());
+ const bool condition = fxv8::ReentrantToBooleanHelper(
+ info.GetIsolate(), GetSimpleValue(info, 0));
+
+ info.GetReturnValue().Set(GetSimpleValue(info, condition ? 1 : 2));
}
// static
-void CFXJSE_FormCalcContext::Eval(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Eval(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 1) {
- pContext->ThrowParamCountMismatchException(L"Eval");
+ if (info.Length() != 1) {
+ pContext->ThrowParamCountMismatchException("Eval");
return;
}
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
- std::unique_ptr<CFXJSE_Value> scriptValue = GetSimpleValue(pThis, args, 0);
- ByteString bsUtf8Script = ValueToUTF8String(scriptValue.get());
+ v8::Isolate* pIsolate = pContext->GetIsolate();
+ v8::Local<v8::Value> scriptValue = GetSimpleValue(info, 0);
+ ByteString bsUtf8Script = ValueToUTF8String(info.GetIsolate(), scriptValue);
if (bsUtf8Script.IsEmpty()) {
- args.GetReturnValue()->SetNull();
+ info.GetReturnValue().SetNull();
return;
}
- CFX_WideTextBuf wsJavaScriptBuf;
- if (!CFXJSE_FormCalcContext::Translate(
- WideString::FromUTF8(bsUtf8Script.AsStringView()).AsStringView(),
- &wsJavaScriptBuf)) {
+ WideString wsCalcScript = WideString::FromUTF8(bsUtf8Script.AsStringView());
+ absl::optional<WideTextBuffer> wsJavaScriptBuf =
+ CFXJSE_FormCalcContext::Translate(pContext->GetDocument()->GetHeap(),
+ wsCalcScript.AsStringView());
+ if (!wsJavaScriptBuf.has_value()) {
pContext->ThrowCompilerErrorException();
return;
}
+ std::unique_ptr<CFXJSE_Context> pNewContext =
+ CFXJSE_Context::Create(pIsolate, nullptr, nullptr, nullptr);
- std::unique_ptr<CFXJSE_Context> pNewContext(
- CFXJSE_Context::Create(pIsolate, nullptr, nullptr));
+ auto returnValue = std::make_unique<CFXJSE_Value>();
+ ByteString bsScript = FX_UTF8Encode(wsJavaScriptBuf.value().AsStringView());
+ pNewContext->ExecuteScript(bsScript.AsStringView(), returnValue.get(),
+ v8::Local<v8::Object>());
- auto returnValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- pNewContext->ExecuteScript(
- FX_UTF8Encode(wsJavaScriptBuf.AsStringView()).c_str(), returnValue.get(),
- nullptr);
-
- args.GetReturnValue()->Assign(returnValue.get());
+ info.GetReturnValue().Set(returnValue->DirectGetValue());
}
// static
-void CFXJSE_FormCalcContext::Ref(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Ref(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
- if (args.GetLength() != 1) {
- pContext->ThrowParamCountMismatchException(L"Ref");
+ if (info.Length() != 1) {
+ pContext->ThrowParamCountMismatchException("Ref");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
- if (!argOne->IsArray() && !argOne->IsObject() && !argOne->IsBoolean() &&
- !argOne->IsString() && !argOne->IsNull() && !argOne->IsNumber()) {
+ v8::Local<v8::Value> argOne = info[0];
+ if (fxv8::IsBoolean(argOne) || fxv8::IsString(argOne) ||
+ fxv8::IsNumber(argOne)) {
+ info.GetReturnValue().Set(argOne);
+ return;
+ }
+
+ std::vector<v8::Local<v8::Value>> values(3);
+ int intVal = 3;
+ if (fxv8::IsNull(argOne)) {
+ // TODO(dsinclair): Why is this 4 when the others are all 3?
+ intVal = 4;
+ values[2] = fxv8::NewNullHelper(info.GetIsolate());
+ } else if (fxv8::IsArray(argOne)) {
+ v8::Local<v8::Array> arr = argOne.As<v8::Array>();
+ v8::Local<v8::Value> propertyValue =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 1);
+ v8::Local<v8::Value> jsObjectValue =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 2);
+ if (!fxv8::IsNull(propertyValue) || fxv8::IsNull(jsObjectValue)) {
+ pContext->ThrowArgumentMismatchException();
+ return;
+ }
+ values[2] = jsObjectValue;
+ } else if (fxv8::IsObject(argOne)) {
+ values[2] = argOne;
+ } else {
pContext->ThrowArgumentMismatchException();
return;
}
- if (argOne->IsBoolean() || argOne->IsString() || argOne->IsNumber()) {
- args.GetReturnValue()->Assign(argOne.get());
- return;
- }
-
- std::vector<std::unique_ptr<CFXJSE_Value>> values;
- for (int32_t i = 0; i < 3; i++)
- values.push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
-
- int intVal = 3;
- if (argOne->IsNull()) {
- // TODO(dsinclair): Why is this 4 when the others are all 3?
- intVal = 4;
- values[2]->SetNull();
- } else if (argOne->IsArray()) {
-#ifndef NDEBUG
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argOne->GetObjectProperty("length", lengthValue.get());
- ASSERT(lengthValue->ToInteger() >= 3);
-#endif
-
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argOne->GetObjectPropertyByIdx(1, propertyValue.get());
- argOne->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (!propertyValue->IsNull() || jsObjectValue->IsNull()) {
- pContext->ThrowArgumentMismatchException();
- return;
- }
-
- values[2]->Assign(jsObjectValue.get());
- } else if (argOne->IsObject()) {
- values[2]->Assign(argOne.get());
- }
-
- values[0]->SetInteger(intVal);
- values[1]->SetNull();
- args.GetReturnValue()->SetArray(values);
+ values[0] = fxv8::NewNumberHelper(info.GetIsolate(), intVal);
+ values[1] = fxv8::NewNullHelper(info.GetIsolate());
+ info.GetReturnValue().Set(fxv8::NewArrayHelper(info.GetIsolate(), values));
}
// static
-void CFXJSE_FormCalcContext::UnitType(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"UnitType");
+void CFXJSE_FormCalcContext::UnitType(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("UnitType");
return;
}
- std::unique_ptr<CFXJSE_Value> unitspanValue = GetSimpleValue(pThis, args, 0);
- if (unitspanValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> unitspanValue = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(unitspanValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsUnitspan = ValueToUTF8String(unitspanValue.get());
+ ByteString bsUnitspan = ValueToUTF8String(info.GetIsolate(), unitspanValue);
if (bsUnitspan.IsEmpty()) {
- args.GetReturnValue()->SetString("in");
+ info.GetReturnValue().SetEmptyString();
return;
}
- enum XFA_FM2JS_VALUETYPE_ParserStatus {
+ enum XFA_FormCalc_VALUETYPE_ParserStatus {
VALUETYPE_START,
VALUETYPE_HAVEINVALIDCHAR,
VALUETYPE_HAVEDIGIT,
@@ -3298,7 +3398,7 @@
while (IsWhitespace(pData[u]))
u++;
- XFA_FM2JS_VALUETYPE_ParserStatus eParserStatus = VALUETYPE_START;
+ XFA_FormCalc_VALUETYPE_ParserStatus eParserStatus = VALUETYPE_START;
wchar_t typeChar;
// TODO(dsinclair): Cleanup this parser, figure out what the various checks
// are for.
@@ -3348,43 +3448,43 @@
}
switch (eParserStatus) {
case VALUETYPE_ISCM:
- args.GetReturnValue()->SetString("cm");
+ info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "cm"));
break;
case VALUETYPE_ISMM:
- args.GetReturnValue()->SetString("mm");
+ info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "mm"));
break;
case VALUETYPE_ISPT:
- args.GetReturnValue()->SetString("pt");
+ info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "pt"));
break;
case VALUETYPE_ISMP:
- args.GetReturnValue()->SetString("mp");
+ info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "mp"));
break;
default:
- args.GetReturnValue()->SetString("in");
+ info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "in"));
break;
}
}
// static
-void CFXJSE_FormCalcContext::UnitValue(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::UnitValue(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"UnitValue");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("UnitValue");
return;
}
- std::unique_ptr<CFXJSE_Value> unitspanValue = GetSimpleValue(pThis, args, 0);
- if (unitspanValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> unitspanValue = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(unitspanValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsUnitspan = ValueToUTF8String(unitspanValue.get());
+ ByteString bsUnitspan = ValueToUTF8String(info.GetIsolate(), unitspanValue);
const char* pData = bsUnitspan.c_str();
if (!pData) {
- args.GetReturnValue()->SetInteger(0);
+ info.GetReturnValue().Set(0);
return;
}
@@ -3416,15 +3516,15 @@
ByteString bsUnit;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> unitValue = GetSimpleValue(pThis, args, 1);
- ByteString bsUnitTemp = ValueToUTF8String(unitValue.get());
+ v8::Local<v8::Value> unitValue = GetSimpleValue(info, 1);
+ ByteString bsUnitTemp = ValueToUTF8String(info.GetIsolate(), unitValue);
const char* pChar = bsUnitTemp.c_str();
size_t uVal = 0;
while (IsWhitespace(pChar[uVal]))
++uVal;
while (uVal < bsUnitTemp.GetLength()) {
- if (!std::isdigit(pChar[uVal]) && pChar[uVal] != '.')
+ if (!isdigit(pChar[uVal]) && pChar[uVal] != '.')
break;
++uVal;
}
@@ -3501,99 +3601,102 @@
else
dResult = dFirstNumber / 72000;
}
- args.GetReturnValue()->SetDouble(dResult);
+ info.GetReturnValue().Set(dResult);
}
// static
-void CFXJSE_FormCalcContext::At(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"At");
+void CFXJSE_FormCalcContext::At(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("At");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString stringTwo = ValueToUTF8String(argTwo.get());
+ ByteString stringTwo = ValueToUTF8String(info.GetIsolate(), argTwo);
if (stringTwo.IsEmpty()) {
- args.GetReturnValue()->SetInteger(1);
+ info.GetReturnValue().Set(1);
return;
}
- ByteString stringOne = ValueToUTF8String(argOne.get());
+ ByteString stringOne = ValueToUTF8String(info.GetIsolate(), argOne);
auto pos = stringOne.Find(stringTwo.AsStringView());
- args.GetReturnValue()->SetInteger(pos.has_value() ? pos.value() + 1 : 0);
+ info.GetReturnValue().Set(
+ static_cast<int>(pos.has_value() ? pos.value() + 1 : 0));
}
// static
-void CFXJSE_FormCalcContext::Concat(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Concat(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Concat");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Concat");
return;
}
ByteString bsResult;
bool bAllNull = true;
for (int32_t i = 0; i < argc; i++) {
- std::unique_ptr<CFXJSE_Value> value = GetSimpleValue(pThis, args, i);
- if (ValueIsNull(pThis, value.get()))
+ v8::Local<v8::Value> value = GetSimpleValue(info, i);
+ if (ValueIsNull(info.GetIsolate(), value))
continue;
bAllNull = false;
- bsResult += ValueToUTF8String(value.get());
+ bsResult += ValueToUTF8String(info.GetIsolate(), value);
}
if (bAllNull) {
- args.GetReturnValue()->SetNull();
+ info.GetReturnValue().SetNull();
return;
}
-
- args.GetReturnValue()->SetString(bsResult.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsResult.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Decode(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Decode(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Decode");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Decode");
return;
}
if (argc == 1) {
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, argOne.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- WideString decoded = DecodeURL(
- WideString::FromUTF8(ValueToUTF8String(argOne.get()).AsStringView()));
-
- args.GetReturnValue()->SetString(
- FX_UTF8Encode(decoded.AsStringView()).AsStringView());
+ WideString decoded = DecodeURL(WideString::FromUTF8(
+ ValueToUTF8String(info.GetIsolate(), argOne).AsStringView()));
+ auto result = FX_UTF8Encode(decoded.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsToDecode = ValueToUTF8String(argOne.get());
- ByteString bsIdentify = ValueToUTF8String(argTwo.get());
+ ByteString bsToDecode = ValueToUTF8String(info.GetIsolate(), argOne);
+ ByteString bsIdentify = ValueToUTF8String(info.GetIsolate(), argTwo);
WideString decoded;
WideString wsToDecode = WideString::FromUTF8(bsToDecode.AsStringView());
@@ -3605,42 +3708,45 @@
else
decoded = DecodeURL(wsToDecode);
- args.GetReturnValue()->SetString(
- FX_UTF8Encode(decoded.AsStringView()).AsStringView());
+ auto result = FX_UTF8Encode(decoded.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Encode(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Encode(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Encode");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Encode");
return;
}
if (argc == 1) {
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, argOne.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
-
- WideString encoded = EncodeURL(ValueToUTF8String(argOne.get()));
- args.GetReturnValue()->SetString(
- FX_UTF8Encode(encoded.AsStringView()).AsStringView());
+ WideString encoded =
+ EncodeURL(ValueToUTF8String(info.GetIsolate(), argOne));
+ auto result = FX_UTF8Encode(encoded.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- if (ValueIsNull(pThis, argOne.get()) || ValueIsNull(pThis, argTwo.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ if (ValueIsNull(info.GetIsolate(), argOne) ||
+ ValueIsNull(info.GetIsolate(), argTwo)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsToEncode = ValueToUTF8String(argOne.get());
- ByteString bsIdentify = ValueToUTF8String(argTwo.get());
+ ByteString bsToEncode = ValueToUTF8String(info.GetIsolate(), argOne);
+ ByteString bsIdentify = ValueToUTF8String(info.GetIsolate(), argTwo);
WideString encoded;
if (bsIdentify.EqualNoCase("html"))
encoded = EncodeHTML(bsToEncode);
@@ -3649,42 +3755,43 @@
else
encoded = EncodeURL(bsToEncode);
- args.GetReturnValue()->SetString(
- FX_UTF8Encode(encoded.AsStringView()).AsStringView());
+ auto result = FX_UTF8Encode(encoded.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Format(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Format(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() < 2) {
- pContext->ThrowParamCountMismatchException(L"Format");
+ if (info.Length() < 2) {
+ pContext->ThrowParamCountMismatchException("Format");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- ByteString bsPattern = ValueToUTF8String(argOne.get());
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ ByteString bsPattern = ValueToUTF8String(info.GetIsolate(), argOne);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- ByteString bsValue = ValueToUTF8String(argTwo.get());
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ ByteString bsValue = ValueToUTF8String(info.GetIsolate(), argTwo);
CXFA_Document* pDoc = pContext->GetDocument();
CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
- LocaleIface* pLocale = pThisNode->GetLocale();
+ GCedLocaleIface* pLocale = pThisNode->GetLocale();
WideString wsPattern = WideString::FromUTF8(bsPattern.AsStringView());
WideString wsValue = WideString::FromUTF8(bsValue.AsStringView());
bool bPatternIsString;
- uint32_t dwPatternType;
+ CXFA_LocaleValue::ValueType dwPatternType;
std::tie(bPatternIsString, dwPatternType) =
PatternStringType(bsPattern.AsStringView());
if (!bPatternIsString) {
switch (dwPatternType) {
- case XFA_VT_DATETIME: {
+ case CXFA_LocaleValue::ValueType::kDateTime: {
auto iTChar = wsPattern.Find(L'T');
if (!iTChar.has_value()) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
WideString wsDatePattern(L"date{");
@@ -3695,28 +3802,28 @@
wsPattern.Last(wsPattern.GetLength() - (iTChar.value() + 1)) + L"}";
wsPattern = wsDatePattern + wsTimePattern;
} break;
- case XFA_VT_DATE: {
+ case CXFA_LocaleValue::ValueType::kDate: {
wsPattern = L"date{" + wsPattern + L"}";
} break;
- case XFA_VT_TIME: {
+ case CXFA_LocaleValue::ValueType::kTime: {
wsPattern = L"time{" + wsPattern + L"}";
} break;
- case XFA_VT_TEXT: {
+ case CXFA_LocaleValue::ValueType::kText: {
wsPattern = L"text{" + wsPattern + L"}";
} break;
- case XFA_VT_FLOAT: {
+ case CXFA_LocaleValue::ValueType::kFloat: {
wsPattern = L"num{" + wsPattern + L"}";
} break;
default: {
WideString wsTestPattern = L"num{" + wsPattern + L"}";
- CXFA_LocaleValue tempLocaleValue(XFA_VT_FLOAT, wsValue, wsTestPattern,
- pLocale, pMgr);
+ CXFA_LocaleValue tempLocaleValue(CXFA_LocaleValue::ValueType::kFloat,
+ wsValue, wsTestPattern, pLocale, pMgr);
if (tempLocaleValue.IsValid()) {
wsPattern = std::move(wsTestPattern);
- dwPatternType = XFA_VT_FLOAT;
+ dwPatternType = CXFA_LocaleValue::ValueType::kFloat;
} else {
wsPattern = L"text{" + wsPattern + L"}";
- dwPatternType = XFA_VT_TEXT;
+ dwPatternType = CXFA_LocaleValue::ValueType::kText;
}
} break;
}
@@ -3725,73 +3832,74 @@
pMgr);
WideString wsRet;
if (!localeValue.FormatPatterns(wsRet, wsPattern, pLocale,
- XFA_VALUEPICTURE_Display)) {
- args.GetReturnValue()->SetString("");
+ XFA_ValuePicture::kDisplay)) {
+ info.GetReturnValue().SetEmptyString();
return;
}
-
- args.GetReturnValue()->SetString(wsRet.ToUTF8().AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), wsRet.ToUTF8().AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Left(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Left");
+void CFXJSE_FormCalcContext::Left(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Left");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- if ((ValueIsNull(pThis, argOne.get())) ||
- (ValueIsNull(pThis, argTwo.get()))) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ if ((ValueIsNull(info.GetIsolate(), argOne)) ||
+ (ValueIsNull(info.GetIsolate(), argTwo))) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsSource = ValueToUTF8String(argOne.get());
- int32_t count = std::max(0, ValueToInteger(pThis, argTwo.get()));
- args.GetReturnValue()->SetString(bsSource.First(count).AsStringView());
+ ByteString bsSource = ValueToUTF8String(info.GetIsolate(), argOne);
+ int32_t count = std::max(0, ValueToInteger(info.GetIsolate(), argTwo));
+ info.GetReturnValue().Set(fxv8::NewStringHelper(
+ info.GetIsolate(), bsSource.First(count).AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Len(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Len");
+void CFXJSE_FormCalcContext::Len(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Len");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, argOne.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsSource = ValueToUTF8String(argOne.get());
- args.GetReturnValue()->SetInteger(bsSource.GetLength());
+ ByteString bsSource = ValueToUTF8String(info.GetIsolate(), argOne);
+ info.GetReturnValue().Set(static_cast<int>(bsSource.GetLength()));
}
// static
-void CFXJSE_FormCalcContext::Lower(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Lower(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Lower");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Lower");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, argOne.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- CFX_WideTextBuf szLowBuf;
- ByteString bsArg = ValueToUTF8String(argOne.get());
+ WideTextBuffer szLowBuf;
+ ByteString bsArg = ValueToUTF8String(info.GetIsolate(), argOne);
WideString wsArg = WideString::FromUTF8(bsArg.AsStringView());
for (wchar_t ch : wsArg) {
if ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0xC0 && ch <= 0xDE))
@@ -3800,78 +3908,79 @@
ch += 1;
szLowBuf.AppendChar(ch);
}
- szLowBuf.AppendChar(0);
-
- args.GetReturnValue()->SetString(
- FX_UTF8Encode(szLowBuf.AsStringView()).AsStringView());
+ auto result = FX_UTF8Encode(szLowBuf.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Ltrim(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Ltrim");
+void CFXJSE_FormCalcContext::Ltrim(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Ltrim");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, argOne.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsSource = ValueToUTF8String(argOne.get());
+ ByteString bsSource = ValueToUTF8String(info.GetIsolate(), argOne);
bsSource.TrimLeft();
- args.GetReturnValue()->SetString(bsSource.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsSource.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Parse(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Parse(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 2) {
- pContext->ThrowParamCountMismatchException(L"Parse");
+ if (info.Length() != 2) {
+ pContext->ThrowParamCountMismatchException("Parse");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- if (ValueIsNull(pThis, argTwo.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ if (ValueIsNull(info.GetIsolate(), argTwo)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsPattern = ValueToUTF8String(argOne.get());
- ByteString bsValue = ValueToUTF8String(argTwo.get());
+ ByteString bsPattern = ValueToUTF8String(info.GetIsolate(), argOne);
+ ByteString bsValue = ValueToUTF8String(info.GetIsolate(), argTwo);
CXFA_Document* pDoc = pContext->GetDocument();
CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
- LocaleIface* pLocale = pThisNode->GetLocale();
+ GCedLocaleIface* pLocale = pThisNode->GetLocale();
WideString wsPattern = WideString::FromUTF8(bsPattern.AsStringView());
WideString wsValue = WideString::FromUTF8(bsValue.AsStringView());
bool bPatternIsString;
- uint32_t dwPatternType;
+ CXFA_LocaleValue::ValueType dwPatternType;
std::tie(bPatternIsString, dwPatternType) =
PatternStringType(bsPattern.AsStringView());
if (bPatternIsString) {
CXFA_LocaleValue localeValue(dwPatternType, wsValue, wsPattern, pLocale,
pMgr);
if (!localeValue.IsValid()) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
- args.GetReturnValue()->SetString(
- localeValue.GetValue().ToUTF8().AsStringView());
+ auto result = localeValue.GetValue().ToUTF8();
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
return;
}
switch (dwPatternType) {
- case XFA_VT_DATETIME: {
+ case CXFA_LocaleValue::ValueType::kDateTime: {
auto iTChar = wsPattern.Find(L'T');
if (!iTChar.has_value()) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
WideString wsDatePattern(L"date{" + wsPattern.First(iTChar.value()) +
@@ -3883,243 +3992,228 @@
CXFA_LocaleValue localeValue(dwPatternType, wsValue, wsPattern, pLocale,
pMgr);
if (!localeValue.IsValid()) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
- args.GetReturnValue()->SetString(
- localeValue.GetValue().ToUTF8().AsStringView());
+ auto result = localeValue.GetValue().ToUTF8();
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
return;
}
- case XFA_VT_DATE: {
+ case CXFA_LocaleValue::ValueType::kDate: {
wsPattern = L"date{" + wsPattern + L"}";
CXFA_LocaleValue localeValue(dwPatternType, wsValue, wsPattern, pLocale,
pMgr);
if (!localeValue.IsValid()) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
- args.GetReturnValue()->SetString(
- localeValue.GetValue().ToUTF8().AsStringView());
+ auto result = localeValue.GetValue().ToUTF8();
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
return;
}
- case XFA_VT_TIME: {
+ case CXFA_LocaleValue::ValueType::kTime: {
wsPattern = L"time{" + wsPattern + L"}";
CXFA_LocaleValue localeValue(dwPatternType, wsValue, wsPattern, pLocale,
pMgr);
if (!localeValue.IsValid()) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
- args.GetReturnValue()->SetString(
- localeValue.GetValue().ToUTF8().AsStringView());
+ auto result = localeValue.GetValue().ToUTF8();
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
return;
}
- case XFA_VT_TEXT: {
+ case CXFA_LocaleValue::ValueType::kText: {
wsPattern = L"text{" + wsPattern + L"}";
- CXFA_LocaleValue localeValue(XFA_VT_TEXT, wsValue, wsPattern, pLocale,
- pMgr);
+ CXFA_LocaleValue localeValue(CXFA_LocaleValue::ValueType::kText, wsValue,
+ wsPattern, pLocale, pMgr);
if (!localeValue.IsValid()) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
- args.GetReturnValue()->SetString(
- localeValue.GetValue().ToUTF8().AsStringView());
+ auto result = localeValue.GetValue().ToUTF8();
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
return;
}
- case XFA_VT_FLOAT: {
+ case CXFA_LocaleValue::ValueType::kFloat: {
wsPattern = L"num{" + wsPattern + L"}";
- CXFA_LocaleValue localeValue(XFA_VT_FLOAT, wsValue, wsPattern, pLocale,
- pMgr);
+ CXFA_LocaleValue localeValue(CXFA_LocaleValue::ValueType::kFloat, wsValue,
+ wsPattern, pLocale, pMgr);
if (!localeValue.IsValid()) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
- args.GetReturnValue()->SetDouble(localeValue.GetDoubleNum());
+ info.GetReturnValue().Set(localeValue.GetDoubleNum());
return;
}
default: {
{
WideString wsTestPattern = L"num{" + wsPattern + L"}";
- CXFA_LocaleValue localeValue(XFA_VT_FLOAT, wsValue, wsTestPattern,
- pLocale, pMgr);
+ CXFA_LocaleValue localeValue(CXFA_LocaleValue::ValueType::kFloat,
+ wsValue, wsTestPattern, pLocale, pMgr);
if (localeValue.IsValid()) {
- args.GetReturnValue()->SetDouble(localeValue.GetDoubleNum());
+ info.GetReturnValue().Set(localeValue.GetDoubleNum());
return;
}
}
{
WideString wsTestPattern = L"text{" + wsPattern + L"}";
- CXFA_LocaleValue localeValue(XFA_VT_TEXT, wsValue, wsTestPattern,
- pLocale, pMgr);
+ CXFA_LocaleValue localeValue(CXFA_LocaleValue::ValueType::kText,
+ wsValue, wsTestPattern, pLocale, pMgr);
if (localeValue.IsValid()) {
- args.GetReturnValue()->SetString(
- localeValue.GetValue().ToUTF8().AsStringView());
+ auto result = localeValue.GetValue().ToUTF8();
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
return;
}
}
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
}
}
// static
-void CFXJSE_FormCalcContext::Replace(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Replace(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 2 || argc > 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Replace");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Replace");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
ByteString bsOne;
ByteString bsTwo;
- if (!ValueIsNull(pThis, argOne.get()) && !ValueIsNull(pThis, argTwo.get())) {
- bsOne = ValueToUTF8String(argOne.get());
- bsTwo = ValueToUTF8String(argTwo.get());
+ if (!ValueIsNull(info.GetIsolate(), argOne) &&
+ !ValueIsNull(info.GetIsolate(), argTwo)) {
+ bsOne = ValueToUTF8String(info.GetIsolate(), argOne);
+ bsTwo = ValueToUTF8String(info.GetIsolate(), argTwo);
}
ByteString bsThree;
if (argc > 2) {
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- bsThree = ValueToUTF8String(argThree.get());
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ bsThree = ValueToUTF8String(info.GetIsolate(), argThree);
}
- size_t iFindLen = bsTwo.GetLength();
- std::ostringstream szResult;
- size_t iFindIndex = 0;
- for (size_t u = 0; u < bsOne.GetLength(); ++u) {
- char ch = static_cast<char>(bsOne[u]);
- if (ch != static_cast<char>(bsTwo[iFindIndex])) {
- szResult << ch;
- continue;
- }
-
- size_t iTemp = u + 1;
- ++iFindIndex;
- while (iFindIndex < iFindLen) {
- uint8_t chTemp = bsOne[iTemp];
- if (chTemp != bsTwo[iFindIndex]) {
- iFindIndex = 0;
- break;
- }
-
- ++iTemp;
- ++iFindIndex;
- }
- if (iFindIndex == iFindLen) {
- szResult << bsThree;
- u += iFindLen - 1;
- iFindIndex = 0;
- } else {
- szResult << ch;
- }
- }
- szResult << '\0';
- args.GetReturnValue()->SetString(ByteStringView(szResult.str().c_str()));
+ bsOne.Replace(bsTwo.AsStringView(), bsThree.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsOne.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Right(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Right");
+void CFXJSE_FormCalcContext::Right(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Right");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- if ((ValueIsNull(pThis, argOne.get())) ||
- (ValueIsNull(pThis, argTwo.get()))) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ if ((ValueIsNull(info.GetIsolate(), argOne)) ||
+ (ValueIsNull(info.GetIsolate(), argTwo))) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsSource = ValueToUTF8String(argOne.get());
- int32_t count = std::max(0, ValueToInteger(pThis, argTwo.get()));
- args.GetReturnValue()->SetString(bsSource.Last(count).AsStringView());
+ ByteString bsSource = ValueToUTF8String(info.GetIsolate(), argOne);
+ int32_t count = std::max(0, ValueToInteger(info.GetIsolate(), argTwo));
+ info.GetReturnValue().Set(fxv8::NewStringHelper(
+ info.GetIsolate(), bsSource.Last(count).AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Rtrim(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Rtrim");
+void CFXJSE_FormCalcContext::Rtrim(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Rtrim");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, argOne.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsSource = ValueToUTF8String(argOne.get());
+ ByteString bsSource = ValueToUTF8String(info.GetIsolate(), argOne);
bsSource.TrimRight();
- args.GetReturnValue()->SetString(bsSource.AsStringView());
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsSource.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Space(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Space");
+void CFXJSE_FormCalcContext::Space(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Space");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (argOne->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- int32_t count = std::max(0, ValueToInteger(pThis, argOne.get()));
- std::ostringstream spaceString;
- int32_t index = 0;
- while (index < count) {
- spaceString << ' ';
- index++;
+ int count = std::max(0, ValueToInteger(info.GetIsolate(), argOne));
+ if (count > kMaxCharCount) {
+ ToFormCalcContext(pThis)->ThrowException("String too long.");
+ return;
}
- spaceString << '\0';
- args.GetReturnValue()->SetString(ByteStringView(spaceString.str().c_str()));
+ DataVector<char> space_string(count, ' ');
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), ByteStringView(space_string)));
}
// static
-void CFXJSE_FormCalcContext::Str(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Str(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Str");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Str");
return;
}
- std::unique_ptr<CFXJSE_Value> numberValue = GetSimpleValue(pThis, args, 0);
- if (numberValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> numberValue = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(numberValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- float fNumber = ValueToFloat(pThis, numberValue.get());
+ float fNumber = ValueToFloat(info.GetIsolate(), numberValue);
- int32_t iWidth = 10;
+ constexpr int32_t kDefaultWidth = 10;
+ int32_t iWidth = kDefaultWidth;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> widthValue = GetSimpleValue(pThis, args, 1);
- iWidth = static_cast<int32_t>(ValueToFloat(pThis, widthValue.get()));
+ v8::Local<v8::Value> widthValue = GetSimpleValue(info, 1);
+ iWidth = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), widthValue));
+ if (iWidth > kMaxCharCount) {
+ ToFormCalcContext(pThis)->ThrowException("String too long.");
+ return;
+ }
}
- int32_t iPrecision = 0;
+ constexpr int32_t kDefaultPrecision = 0;
+ int32_t iPrecision = kDefaultPrecision;
if (argc > 2) {
- std::unique_ptr<CFXJSE_Value> precisionValue =
- GetSimpleValue(pThis, args, 2);
- iPrecision = std::max(
- 0, static_cast<int32_t>(ValueToFloat(pThis, precisionValue.get())));
+ constexpr int32_t kMaxPrecision = 15;
+ v8::Local<v8::Value> precision_value = GetSimpleValue(info, 2);
+ iPrecision = std::max(0, static_cast<int32_t>(ValueToFloat(
+ info.GetIsolate(), precision_value)));
+ iPrecision = std::min(iPrecision, kMaxPrecision);
}
ByteString bsFormat = "%";
@@ -4140,34 +4234,31 @@
++u;
}
- std::ostringstream resultBuf;
if (u > iWidth || (iPrecision + u) >= iWidth) {
- int32_t i = 0;
- while (i < iWidth) {
- resultBuf << '*';
- ++i;
- }
- resultBuf << '\0';
- args.GetReturnValue()->SetString(ByteStringView(resultBuf.str().c_str()));
+ DataVector<char> stars(std::max(iWidth, 0), '*');
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), ByteStringView(stars)));
return;
}
+ ByteString resultBuf;
if (u == iLength) {
if (iLength > iWidth) {
int32_t i = 0;
while (i < iWidth) {
- resultBuf << '*';
+ resultBuf += '*';
++i;
}
} else {
int32_t i = 0;
while (i < iWidth - iLength) {
- resultBuf << ' ';
+ resultBuf += ' ';
++i;
}
- resultBuf << pData;
+ resultBuf += pData;
}
- args.GetReturnValue()->SetString(ByteStringView(resultBuf.str().c_str()));
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), resultBuf.AsStringView()));
return;
}
@@ -4177,16 +4268,16 @@
int32_t i = 0;
while (i < iLeavingSpace) {
- resultBuf << ' ';
+ resultBuf += ' ';
++i;
}
i = 0;
while (i < u) {
- resultBuf << pData[i];
+ resultBuf += pData[i];
++i;
}
if (iPrecision != 0)
- resultBuf << '.';
+ resultBuf += '.';
u++;
i = 0;
@@ -4194,221 +4285,213 @@
if (i >= iPrecision)
break;
- resultBuf << pData[u];
+ resultBuf += pData[u];
++i;
++u;
}
while (i < iPrecision) {
- resultBuf << '0';
+ resultBuf += '0';
++i;
}
- resultBuf << '\0';
- args.GetReturnValue()->SetString(ByteStringView(resultBuf.str().c_str()));
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), resultBuf.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Stuff(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Stuff(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 3 || argc > 4) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Stuff");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Stuff");
return;
}
- ByteString bsSource;
- ByteString bsInsert;
- int32_t iLength = 0;
- int32_t iStart = 0;
+ v8::Local<v8::Value> sourceValue = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> startValue = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> deleteValue = GetSimpleValue(info, 2);
+ if (fxv8::IsNull(sourceValue) || fxv8::IsNull(startValue) ||
+ fxv8::IsNull(deleteValue)) {
+ info.GetReturnValue().SetNull();
+ return;
+ }
+
+ int32_t iStart = 1; // one-based character indexing.
int32_t iDelete = 0;
- std::unique_ptr<CFXJSE_Value> sourceValue = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> startValue = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> deleteValue = GetSimpleValue(pThis, args, 2);
- if (!sourceValue->IsNull() && !startValue->IsNull() &&
- !deleteValue->IsNull()) {
- bsSource = ValueToUTF8String(sourceValue.get());
- iLength = bsSource.GetLength();
+ ByteString bsSource = ValueToUTF8String(info.GetIsolate(), sourceValue);
+ int32_t iLength = pdfium::base::checked_cast<int32_t>(bsSource.GetLength());
+ if (iLength) {
iStart = pdfium::clamp(
- static_cast<int32_t>(ValueToFloat(pThis, startValue.get())), 1,
+ static_cast<int32_t>(ValueToFloat(info.GetIsolate(), startValue)), 1,
iLength);
- iDelete = std::max(
- 0, static_cast<int32_t>(ValueToFloat(pThis, deleteValue.get())));
+ iDelete = pdfium::clamp(
+ static_cast<int32_t>(ValueToFloat(info.GetIsolate(), deleteValue)), 0,
+ iLength - iStart + 1);
}
+ ByteString bsInsert;
if (argc > 3) {
- std::unique_ptr<CFXJSE_Value> insertValue = GetSimpleValue(pThis, args, 3);
- bsInsert = ValueToUTF8String(insertValue.get());
+ v8::Local<v8::Value> insertValue = GetSimpleValue(info, 3);
+ bsInsert = ValueToUTF8String(info.GetIsolate(), insertValue);
}
- --iStart;
- std::ostringstream szResult;
- int32_t i = 0;
- while (i < iStart) {
- szResult << static_cast<char>(bsSource[i]);
- ++i;
- }
- szResult << bsInsert.AsStringView();
- i = iStart + iDelete;
- while (i < iLength) {
- szResult << static_cast<char>(bsSource[i]);
- ++i;
- }
- szResult << '\0';
- args.GetReturnValue()->SetString(ByteStringView(szResult.str().c_str()));
+ --iStart; // now zero-based.
+ ByteString bsResult = {bsSource.AsStringView().First(iStart),
+ bsInsert.AsStringView(),
+ bsSource.AsStringView().Substr(iStart + iDelete)};
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsResult.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Substr(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Substr");
+void CFXJSE_FormCalcContext::Substr(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 3) {
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Substr");
return;
}
- std::unique_ptr<CFXJSE_Value> string_value = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> start_value = GetSimpleValue(pThis, args, 1);
- std::unique_ptr<CFXJSE_Value> end_value = GetSimpleValue(pThis, args, 2);
- if (ValueIsNull(pThis, string_value.get()) ||
- ValueIsNull(pThis, start_value.get()) ||
- ValueIsNull(pThis, end_value.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> string_value = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> start_value = GetSimpleValue(info, 1);
+ v8::Local<v8::Value> end_value = GetSimpleValue(info, 2);
+ if (ValueIsNull(info.GetIsolate(), string_value) ||
+ ValueIsNull(info.GetIsolate(), start_value) ||
+ ValueIsNull(info.GetIsolate(), end_value)) {
+ info.GetReturnValue().SetNull();
return;
}
- ByteString bsSource = ValueToUTF8String(string_value.get());
+ ByteString bsSource = ValueToUTF8String(info.GetIsolate(), string_value);
size_t iLength = bsSource.GetLength();
if (iLength == 0) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
// |start_value| is 1-based. Assume first character if |start_value| is less
// than 1, per spec. Subtract 1 since |iStart| is 0-based.
- size_t iStart = std::max(ValueToInteger(pThis, start_value.get()), 1) - 1;
+ size_t iStart =
+ std::max(ValueToInteger(info.GetIsolate(), start_value), 1) - 1;
if (iStart >= iLength) {
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
return;
}
// Negative values are treated as 0. Can't clamp() due to sign mismatches.
- size_t iCount = std::max(ValueToInteger(pThis, end_value.get()), 0);
+ size_t iCount = std::max(ValueToInteger(info.GetIsolate(), end_value), 0);
iCount = std::min(iCount, iLength - iStart);
- args.GetReturnValue()->SetString(
- bsSource.Substr(iStart, iCount).AsStringView());
+ info.GetReturnValue().Set(fxv8::NewStringHelper(
+ info.GetIsolate(), bsSource.Substr(iStart, iCount).AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Uuid(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Uuid(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 0 || argc > 1) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Uuid");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Uuid");
return;
}
int32_t iNum = 0;
if (argc > 0) {
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- iNum = static_cast<int32_t>(ValueToFloat(pThis, argOne.get()));
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ iNum = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), argOne));
}
- args.GetReturnValue()->SetString(GUIDString(!!iNum).AsStringView());
+ info.GetReturnValue().Set(fxv8::NewStringHelper(
+ info.GetIsolate(), GUIDString(!!iNum).AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Upper(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::Upper(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 2) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"Upper");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Upper");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (ValueIsNull(pThis, argOne.get())) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (ValueIsNull(info.GetIsolate(), argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- CFX_WideTextBuf upperStringBuf;
- ByteString bsArg = ValueToUTF8String(argOne.get());
+ ByteString bsArg = ValueToUTF8String(info.GetIsolate(), argOne);
WideString wsArg = WideString::FromUTF8(bsArg.AsStringView());
- const wchar_t* pData = wsArg.c_str();
- size_t i = 0;
- while (i < wsArg.GetLength()) {
- int32_t ch = pData[i];
+ WideString upperStringBuf;
+ upperStringBuf.Reserve(wsArg.GetLength());
+ for (wchar_t ch : wsArg) {
if ((ch >= 0x61 && ch <= 0x7A) || (ch >= 0xE0 && ch <= 0xFE))
ch -= 32;
else if (ch == 0x101 || ch == 0x103 || ch == 0x105)
ch -= 1;
- upperStringBuf.AppendChar(ch);
- ++i;
+ upperStringBuf += ch;
}
- upperStringBuf.AppendChar(0);
-
- args.GetReturnValue()->SetString(
- FX_UTF8Encode(upperStringBuf.AsStringView()).AsStringView());
+ info.GetReturnValue().Set(fxv8::NewStringHelper(
+ info.GetIsolate(),
+ FX_UTF8Encode(upperStringBuf.AsStringView()).AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::WordNum(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- int32_t argc = args.GetLength();
+void CFXJSE_FormCalcContext::WordNum(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int32_t argc = info.Length();
if (argc < 1 || argc > 3) {
- ToFormCalcContext(pThis)->ThrowParamCountMismatchException(L"WordNum");
+ ToFormCalcContext(pThis)->ThrowParamCountMismatchException("WordNum");
return;
}
- std::unique_ptr<CFXJSE_Value> numberValue = GetSimpleValue(pThis, args, 0);
- if (numberValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> numberValue = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(numberValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- float fNumber = ValueToFloat(pThis, numberValue.get());
+ float fNumber = ValueToFloat(info.GetIsolate(), numberValue);
int32_t iIdentifier = 0;
if (argc > 1) {
- std::unique_ptr<CFXJSE_Value> identifierValue =
- GetSimpleValue(pThis, args, 1);
- if (identifierValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> identifierValue = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(identifierValue)) {
+ info.GetReturnValue().SetNull();
return;
}
iIdentifier =
- static_cast<int32_t>(ValueToFloat(pThis, identifierValue.get()));
+ static_cast<int32_t>(ValueToFloat(info.GetIsolate(), identifierValue));
}
ByteString bsLocale;
if (argc > 2) {
- std::unique_ptr<CFXJSE_Value> localeValue = GetSimpleValue(pThis, args, 2);
- if (localeValue->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
+ if (fxv8::IsNull(localeValue)) {
+ info.GetReturnValue().SetNull();
return;
}
- bsLocale = ValueToUTF8String(localeValue.get());
+ bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
}
- if (std::isnan(fNumber) || fNumber < 0.0f ||
- fNumber > 922337203685477550.0f) {
- args.GetReturnValue()->SetString("*");
+ if (isnan(fNumber) || fNumber < 0.0f || fNumber > 922337203685477550.0f) {
+ info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "*"));
return;
}
-
- args.GetReturnValue()->SetString(
- WordUS(ByteString::Format("%.2f", fNumber), iIdentifier).AsStringView());
+ ByteString bsFormatted = ByteString::Format("%.2f", fNumber);
+ ByteString bsWorded = WordUS(bsFormatted.AsStringView(), iIdentifier);
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), bsWorded.AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Get(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Get(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 1) {
- pContext->ThrowParamCountMismatchException(L"Get");
+ if (info.Length() != 1) {
+ pContext->ThrowParamCountMismatchException("Get");
return;
}
@@ -4416,31 +4499,34 @@
if (!pDoc)
return;
- IXFA_AppProvider* pAppProvider = pDoc->GetNotify()->GetAppProvider();
+ CXFA_FFApp::CallbackIface* pAppProvider = pDoc->GetNotify()->GetAppProvider();
if (!pAppProvider)
return;
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- ByteString bsUrl = ValueToUTF8String(argOne.get());
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ ByteString bsUrl = ValueToUTF8String(info.GetIsolate(), argOne);
RetainPtr<IFX_SeekableReadStream> pFile =
pAppProvider->DownloadURL(WideString::FromUTF8(bsUrl.AsStringView()));
if (!pFile)
return;
- int32_t size = pFile->GetSize();
- std::vector<uint8_t> dataBuf(size);
- pFile->ReadBlock(dataBuf.data(), size);
- args.GetReturnValue()->SetString(ByteStringView(dataBuf));
+ FX_FILESIZE size = pFile->GetSize();
+ DataVector<uint8_t> dataBuf(size);
+
+ // TODO(tsepez): check return value?
+ (void)pFile->ReadBlock(dataBuf);
+ info.GetReturnValue().Set(
+ fxv8::NewStringHelper(info.GetIsolate(), ByteStringView(dataBuf)));
}
// static
-void CFXJSE_FormCalcContext::Post(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Post(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- int32_t argc = args.GetLength();
+ int32_t argc = info.Length();
if (argc < 2 || argc > 5) {
- pContext->ThrowParamCountMismatchException(L"Post");
+ pContext->ThrowParamCountMismatchException("Post");
return;
}
@@ -4448,32 +4534,32 @@
if (!pDoc)
return;
- IXFA_AppProvider* pAppProvider = pDoc->GetNotify()->GetAppProvider();
+ CXFA_FFApp::CallbackIface* pAppProvider = pDoc->GetNotify()->GetAppProvider();
if (!pAppProvider)
return;
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- ByteString bsURL = ValueToUTF8String(argOne.get());
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ ByteString bsURL = ValueToUTF8String(info.GetIsolate(), argOne);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- ByteString bsData = ValueToUTF8String(argTwo.get());
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ ByteString bsData = ValueToUTF8String(info.GetIsolate(), argTwo);
ByteString bsContentType;
if (argc > 2) {
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- bsContentType = ValueToUTF8String(argThree.get());
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ bsContentType = ValueToUTF8String(info.GetIsolate(), argThree);
}
ByteString bsEncode;
if (argc > 3) {
- std::unique_ptr<CFXJSE_Value> argFour = GetSimpleValue(pThis, args, 3);
- bsEncode = ValueToUTF8String(argFour.get());
+ v8::Local<v8::Value> argFour = GetSimpleValue(info, 3);
+ bsEncode = ValueToUTF8String(info.GetIsolate(), argFour);
}
ByteString bsHeader;
if (argc > 4) {
- std::unique_ptr<CFXJSE_Value> argFive = GetSimpleValue(pThis, args, 4);
- bsHeader = ValueToUTF8String(argFive.get());
+ v8::Local<v8::Value> argFive = GetSimpleValue(info, 4);
+ bsHeader = ValueToUTF8String(info.GetIsolate(), argFive);
}
WideString decodedResponse;
@@ -4486,17 +4572,18 @@
pContext->ThrowServerDeniedException();
return;
}
- args.GetReturnValue()->SetString(decodedResponse.ToUTF8().AsStringView());
+ info.GetReturnValue().Set(fxv8::NewStringHelper(
+ info.GetIsolate(), decodedResponse.ToUTF8().AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::Put(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::Put(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- int32_t argc = args.GetLength();
+ int32_t argc = info.Length();
if (argc < 2 || argc > 3) {
- pContext->ThrowParamCountMismatchException(L"Put");
+ pContext->ThrowParamCountMismatchException("Put");
return;
}
@@ -4504,22 +4591,21 @@
if (!pDoc)
return;
- IXFA_AppProvider* pAppProvider = pDoc->GetNotify()->GetAppProvider();
+ CXFA_FFApp::CallbackIface* pAppProvider = pDoc->GetNotify()->GetAppProvider();
if (!pAppProvider)
return;
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- ByteString bsURL = ValueToUTF8String(argOne.get());
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ ByteString bsURL = ValueToUTF8String(info.GetIsolate(), argOne);
- std::unique_ptr<CFXJSE_Value> argTwo = GetSimpleValue(pThis, args, 1);
- ByteString bsData = ValueToUTF8String(argTwo.get());
+ v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
+ ByteString bsData = ValueToUTF8String(info.GetIsolate(), argTwo);
ByteString bsEncode;
if (argc > 2) {
- std::unique_ptr<CFXJSE_Value> argThree = GetSimpleValue(pThis, args, 2);
- bsEncode = ValueToUTF8String(argThree.get());
+ v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
+ bsEncode = ValueToUTF8String(info.GetIsolate(), argThree);
}
-
if (!pAppProvider->PutRequestURL(
WideString::FromUTF8(bsURL.AsStringView()),
WideString::FromUTF8(bsData.AsStringView()),
@@ -4527,869 +4613,641 @@
pContext->ThrowServerDeniedException();
return;
}
-
- args.GetReturnValue()->SetString("");
+ info.GetReturnValue().SetEmptyString();
}
// static
-void CFXJSE_FormCalcContext::assign_value_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::assign_value_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* pIsolate = info.GetIsolate();
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 2) {
+ if (info.Length() != 2) {
pContext->ThrowCompilerErrorException();
return;
}
-
- std::unique_ptr<CFXJSE_Value> lValue = args.GetValue(0);
- std::unique_ptr<CFXJSE_Value> rValue = GetSimpleValue(pThis, args, 1);
- if (lValue->IsArray()) {
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
- auto leftLengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- lValue->GetObjectProperty("length", leftLengthValue.get());
- int32_t iLeftLength = leftLengthValue->ToInteger();
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- lValue->GetObjectPropertyByIdx(1, propertyValue.get());
- if (propertyValue->IsNull()) {
- for (int32_t i = 2; i < iLeftLength; i++) {
- lValue->GetObjectPropertyByIdx(i, jsObjectValue.get());
- if (!SetObjectDefaultValue(jsObjectValue.get(), rValue.get())) {
+ ByteStringView bsFuncName("asgn_val_op");
+ v8::Local<v8::Value> lValue = info[0];
+ v8::Local<v8::Value> rValue = GetSimpleValue(info, 1);
+ if (fxv8::IsArray(lValue)) {
+ v8::Local<v8::Array> arr = lValue.As<v8::Array>();
+ uint32_t iLeftLength = fxv8::GetArrayLengthHelper(arr);
+ v8::Local<v8::Value> propertyValue =
+ fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 1);
+ for (uint32_t i = 2; i < iLeftLength; i++) {
+ v8::Local<v8::Value> jsValue =
+ fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, i);
+ if (!fxv8::IsObject(jsValue)) {
+ pContext->ThrowNoDefaultPropertyException(bsFuncName);
+ return;
+ }
+ v8::Local<v8::Object> jsObjectValue = jsValue.As<v8::Object>();
+ if (fxv8::IsNull(propertyValue)) {
+ if (!SetObjectDefaultValue(pIsolate, jsObjectValue, rValue)) {
pContext->ThrowNoDefaultPropertyException(bsFuncName);
return;
}
- }
- } else {
- for (int32_t i = 2; i < iLeftLength; i++) {
- lValue->GetObjectPropertyByIdx(i, jsObjectValue.get());
- jsObjectValue->SetObjectProperty(
- propertyValue->ToString().AsStringView(), rValue.get());
+ } else {
+ fxv8::ReentrantPutObjectPropertyHelper(
+ pIsolate, jsObjectValue,
+ fxv8::ReentrantToByteStringHelper(pIsolate, propertyValue)
+ .AsStringView(),
+ rValue);
}
}
- } else if (lValue->IsObject()) {
- if (!SetObjectDefaultValue(lValue.get(), rValue.get())) {
+ } else if (fxv8::IsObject(lValue)) {
+ if (!SetObjectDefaultValue(pIsolate, lValue.As<v8::Object>(), rValue)) {
pContext->ThrowNoDefaultPropertyException(bsFuncName);
return;
}
}
- args.GetReturnValue()->Assign(rValue.get());
+ info.GetReturnValue().Set(rValue);
}
// static
-void CFXJSE_FormCalcContext::logical_or_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::logical_or_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() && argSecond->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().SetNull();
return;
}
- float first = ValueToFloat(pThis, argFirst.get());
- float second = ValueToFloat(pThis, argSecond.get());
- args.GetReturnValue()->SetInteger((first || second) ? 1 : 0);
+ float first = ValueToFloat(info.GetIsolate(), argFirst);
+ float second = ValueToFloat(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(static_cast<int>(first || second));
}
// static
-void CFXJSE_FormCalcContext::logical_and_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::logical_and_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() && argSecond->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().SetNull();
return;
}
- float first = ValueToFloat(pThis, argFirst.get());
- float second = ValueToFloat(pThis, argSecond.get());
- args.GetReturnValue()->SetInteger((first && second) ? 1 : 0);
+ float first = ValueToFloat(info.GetIsolate(), argFirst);
+ float second = ValueToFloat(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(static_cast<int>(first && second));
}
// static
-void CFXJSE_FormCalcContext::equality_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::equality_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- if (fm_ref_equal(pThis, args)) {
- args.GetReturnValue()->SetInteger(1);
+ if (fm_ref_equal(pThis, info)) {
+ info.GetReturnValue().Set(1);
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() || argSecond->IsNull()) {
- args.GetReturnValue()->SetInteger(
- (argFirst->IsNull() && argSecond->IsNull()) ? 1 : 0);
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().Set(
+ static_cast<int>(fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)));
return;
}
- if (argFirst->IsString() && argSecond->IsString()) {
- args.GetReturnValue()->SetInteger(argFirst->ToString() ==
- argSecond->ToString());
+ if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
+ info.GetReturnValue().Set(static_cast<int>(
+ fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst) ==
+ fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond)));
return;
}
- double first = ValueToDouble(pThis, argFirst.get());
- double second = ValueToDouble(pThis, argSecond.get());
- args.GetReturnValue()->SetInteger((first == second) ? 1 : 0);
+ double first = ValueToDouble(info.GetIsolate(), argFirst);
+ double second = ValueToDouble(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(static_cast<int>(first == second));
}
// static
-void CFXJSE_FormCalcContext::notequality_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::notequality_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- if (fm_ref_equal(pThis, args)) {
- args.GetReturnValue()->SetInteger(0);
+ if (fm_ref_equal(pThis, info)) {
+ info.GetReturnValue().Set(0);
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() || argSecond->IsNull()) {
- args.GetReturnValue()->SetInteger(
- (argFirst->IsNull() && argSecond->IsNull()) ? 0 : 1);
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().Set(
+ static_cast<int>(!fxv8::IsNull(argFirst) || !fxv8::IsNull(argSecond)));
return;
}
- if (argFirst->IsString() && argSecond->IsString()) {
- args.GetReturnValue()->SetInteger(argFirst->ToString() !=
- argSecond->ToString());
+ if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
+ info.GetReturnValue().Set(static_cast<int>(
+ fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst) !=
+ fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond)));
return;
}
- double first = ValueToDouble(pThis, argFirst.get());
- double second = ValueToDouble(pThis, argSecond.get());
- args.GetReturnValue()->SetInteger(first != second);
+ double first = ValueToDouble(info.GetIsolate(), argFirst);
+ double second = ValueToDouble(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(static_cast<int>(first != second));
}
// static
-bool CFXJSE_FormCalcContext::fm_ref_equal(CFXJSE_Value* pThis,
- CFXJSE_Arguments& args) {
- std::unique_ptr<CFXJSE_Value> argFirst = args.GetValue(0);
- std::unique_ptr<CFXJSE_Value> argSecond = args.GetValue(1);
- if (!argFirst->IsArray() || !argSecond->IsArray())
+bool CFXJSE_FormCalcContext::fm_ref_equal(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Local<v8::Value> argFirst = info[0];
+ v8::Local<v8::Value> argSecond = info[1];
+ if (!fxv8::IsArray(argFirst) || !fxv8::IsArray(argSecond))
return false;
- v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
- auto firstFlagValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto secondFlagValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argFirst->GetObjectPropertyByIdx(0, firstFlagValue.get());
- argSecond->GetObjectPropertyByIdx(0, secondFlagValue.get());
- if (firstFlagValue->ToInteger() != 3 || secondFlagValue->ToInteger() != 3)
+ v8::Local<v8::Array> firstArr = argFirst.As<v8::Array>();
+ v8::Local<v8::Array> secondArr = argSecond.As<v8::Array>();
+ v8::Local<v8::Value> firstFlag =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), firstArr, 0);
+ v8::Local<v8::Value> secondFlag =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), secondArr, 0);
+ if (fxv8::ReentrantToInt32Helper(info.GetIsolate(), firstFlag) != 3 ||
+ fxv8::ReentrantToInt32Helper(info.GetIsolate(), secondFlag) != 3) {
+ return false;
+ }
+
+ v8::Local<v8::Value> firstValue =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), firstArr, 2);
+ v8::Local<v8::Value> secondValue =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), secondArr, 2);
+
+ if (fxv8::IsNull(firstValue) || fxv8::IsNull(secondValue))
return false;
- auto firstJSObject = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto secondJSObject = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argFirst->GetObjectPropertyByIdx(2, firstJSObject.get());
- argSecond->GetObjectPropertyByIdx(2, secondJSObject.get());
- if (firstJSObject->IsNull() || secondJSObject->IsNull())
- return false;
-
- return firstJSObject->ToHostObject() == secondJSObject->ToHostObject();
+ return FXJSE_RetrieveObjectBinding(firstValue) ==
+ FXJSE_RetrieveObjectBinding(secondValue);
}
// static
-void CFXJSE_FormCalcContext::less_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::less_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() || argSecond->IsNull()) {
- args.GetReturnValue()->SetInteger(0);
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().Set(0);
return;
}
- if (argFirst->IsString() && argSecond->IsString()) {
- int result =
- argFirst->ToString().Compare(argSecond->ToString().AsStringView()) < 0;
- args.GetReturnValue()->SetInteger(result);
+ if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
+ ByteString bs1 =
+ fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst);
+ ByteString bs2 =
+ fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(bs1.Compare(bs2.AsStringView()) < 0);
return;
}
- double first = ValueToDouble(pThis, argFirst.get());
- double second = ValueToDouble(pThis, argSecond.get());
- args.GetReturnValue()->SetInteger((first < second) ? 1 : 0);
+ double first = ValueToDouble(info.GetIsolate(), argFirst);
+ double second = ValueToDouble(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(static_cast<int>(first < second));
}
// static
-void CFXJSE_FormCalcContext::lessequal_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::lessequal_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() || argSecond->IsNull()) {
- args.GetReturnValue()->SetInteger(
- (argFirst->IsNull() && argSecond->IsNull()) ? 1 : 0);
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().Set(
+ static_cast<int>(fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)));
return;
}
- if (argFirst->IsString() && argSecond->IsString()) {
- int result =
- argFirst->ToString().Compare(argSecond->ToString().AsStringView()) <= 0;
- args.GetReturnValue()->SetInteger(result);
+ if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
+ auto bs1 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst);
+ auto bs2 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(bs1.Compare(bs2.AsStringView()) <= 0);
return;
}
- double first = ValueToDouble(pThis, argFirst.get());
- double second = ValueToDouble(pThis, argSecond.get());
- args.GetReturnValue()->SetInteger((first <= second) ? 1 : 0);
+ double first = ValueToDouble(info.GetIsolate(), argFirst);
+ double second = ValueToDouble(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(static_cast<int>(first <= second));
}
// static
-void CFXJSE_FormCalcContext::greater_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::greater_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() || argSecond->IsNull()) {
- args.GetReturnValue()->SetInteger(0);
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().Set(0);
return;
}
- if (argFirst->IsString() && argSecond->IsString()) {
- int result =
- argFirst->ToString().Compare(argSecond->ToString().AsStringView()) > 0;
- args.GetReturnValue()->SetInteger(result);
+ if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
+ auto bs1 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst);
+ auto bs2 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(bs1.Compare(bs2.AsStringView()) > 0);
return;
}
- double first = ValueToDouble(pThis, argFirst.get());
- double second = ValueToDouble(pThis, argSecond.get());
- args.GetReturnValue()->SetInteger((first > second) ? 1 : 0);
+ double first = ValueToDouble(info.GetIsolate(), argFirst);
+ double second = ValueToDouble(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(static_cast<int>(first > second));
}
// static
-void CFXJSE_FormCalcContext::greaterequal_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::greaterequal_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() || argSecond->IsNull()) {
- args.GetReturnValue()->SetInteger(
- (argFirst->IsNull() && argSecond->IsNull()) ? 1 : 0);
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().Set(
+ static_cast<int>(fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)));
return;
}
- if (argFirst->IsString() && argSecond->IsString()) {
- int result =
- argFirst->ToString().Compare(argSecond->ToString().AsStringView()) >= 0;
- args.GetReturnValue()->SetInteger(result);
+ if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
+ auto bs1 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst);
+ auto bs2 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(bs1.Compare(bs2.AsStringView()) >= 0);
return;
}
- double first = ValueToDouble(pThis, argFirst.get());
- double second = ValueToDouble(pThis, argSecond.get());
- args.GetReturnValue()->SetInteger((first >= second) ? 1 : 0);
+ double first = ValueToDouble(info.GetIsolate(), argFirst);
+ double second = ValueToDouble(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(static_cast<int>(first >= second));
}
// static
-void CFXJSE_FormCalcContext::plus_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::plus_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = args.GetValue(0);
- std::unique_ptr<CFXJSE_Value> argSecond = args.GetValue(1);
- if (ValueIsNull(pThis, argFirst.get()) &&
- ValueIsNull(pThis, argSecond.get())) {
- args.GetReturnValue()->SetNull();
+ if (ValueIsNull(info.GetIsolate(), info[0]) &&
+ ValueIsNull(info.GetIsolate(), info[1])) {
+ info.GetReturnValue().SetNull();
return;
}
- double first = ValueToDouble(pThis, argFirst.get());
- double second = ValueToDouble(pThis, argSecond.get());
- args.GetReturnValue()->SetDouble(first + second);
+ const double first = ValueToDouble(info.GetIsolate(), info[0]);
+ const double second = ValueToDouble(info.GetIsolate(), info[1]);
+ info.GetReturnValue().Set(first + second);
}
// static
-void CFXJSE_FormCalcContext::minus_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::minus_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() && argSecond->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().SetNull();
return;
}
- double first = ValueToDouble(pThis, argFirst.get());
- double second = ValueToDouble(pThis, argSecond.get());
- args.GetReturnValue()->SetDouble(first - second);
+ double first = ValueToDouble(info.GetIsolate(), argFirst);
+ double second = ValueToDouble(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(first - second);
}
// static
-void CFXJSE_FormCalcContext::multiple_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 2) {
+void CFXJSE_FormCalcContext::multiple_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 2) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() && argSecond->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().SetNull();
return;
}
- double first = ValueToDouble(pThis, argFirst.get());
- double second = ValueToDouble(pThis, argSecond.get());
- args.GetReturnValue()->SetDouble(first * second);
+ double first = ValueToDouble(info.GetIsolate(), argFirst);
+ double second = ValueToDouble(info.GetIsolate(), argSecond);
+ info.GetReturnValue().Set(first * second);
}
// static
-void CFXJSE_FormCalcContext::divide_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::divide_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 2) {
+ if (info.Length() != 2) {
pContext->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argFirst = GetSimpleValue(pThis, args, 0);
- std::unique_ptr<CFXJSE_Value> argSecond = GetSimpleValue(pThis, args, 1);
- if (argFirst->IsNull() && argSecond->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
+ v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
+ if (fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)) {
+ info.GetReturnValue().SetNull();
return;
}
- double second = ValueToDouble(pThis, argSecond.get());
+ double second = ValueToDouble(info.GetIsolate(), argSecond);
if (second == 0.0) {
pContext->ThrowDivideByZeroException();
return;
}
- double first = ValueToDouble(pThis, argFirst.get());
- args.GetReturnValue()->SetDouble(first / second);
+ double first = ValueToDouble(info.GetIsolate(), argFirst);
+ info.GetReturnValue().Set(first / second);
}
// static
-void CFXJSE_FormCalcContext::positive_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
+void CFXJSE_FormCalcContext::positive_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (argOne->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- args.GetReturnValue()->SetDouble(0.0 + ValueToDouble(pThis, argOne.get()));
+ info.GetReturnValue().Set(0.0 + ValueToDouble(info.GetIsolate(), argOne));
}
// static
-void CFXJSE_FormCalcContext::negative_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
+void CFXJSE_FormCalcContext::negative_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (argOne->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- args.GetReturnValue()->SetDouble(0.0 - ValueToDouble(pThis, argOne.get()));
+ info.GetReturnValue().Set(0.0 - ValueToDouble(info.GetIsolate(), argOne));
}
// static
-void CFXJSE_FormCalcContext::logical_not_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
+void CFXJSE_FormCalcContext::logical_not_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- if (argOne->IsNull()) {
- args.GetReturnValue()->SetNull();
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ if (fxv8::IsNull(argOne)) {
+ info.GetReturnValue().SetNull();
return;
}
- double first = ValueToDouble(pThis, argOne.get());
- args.GetReturnValue()->SetInteger((first == 0.0) ? 1 : 0);
+ double first = ValueToDouble(info.GetIsolate(), argOne);
+ info.GetReturnValue().Set((first == 0.0) ? 1 : 0);
}
// static
-void CFXJSE_FormCalcContext::dot_accessor(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- DotAccessorCommon(pThis, bsFuncName, args, /*bDotAccessor=*/true);
+void CFXJSE_FormCalcContext::dot_accessor(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ DotAccessorCommon(pThis, info, /*bDotAccessor=*/true);
}
// static
-void CFXJSE_FormCalcContext::dotdot_accessor(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- DotAccessorCommon(pThis, bsFuncName, args, /*bDotAccessor=*/false);
+void CFXJSE_FormCalcContext::dotdot_accessor(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ DotAccessorCommon(pThis, info, /*bDotAccessor=*/false);
}
// static
-void CFXJSE_FormCalcContext::eval_translation(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::eval_translation(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 1) {
- pContext->ThrowParamCountMismatchException(L"Eval");
+ if (info.Length() != 1) {
+ pContext->ThrowParamCountMismatchException("Eval");
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
- ByteString bsArg = ValueToUTF8String(argOne.get());
+ v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
+ ByteString bsArg = ValueToUTF8String(info.GetIsolate(), argOne);
if (bsArg.IsEmpty()) {
pContext->ThrowArgumentMismatchException();
return;
}
- WideString wsScript = WideString::FromUTF8(bsArg.AsStringView());
- CFX_WideTextBuf wsJavaScriptBuf;
- if (!CFXJSE_FormCalcContext::Translate(wsScript.AsStringView(),
- &wsJavaScriptBuf)) {
+ WideString wsCalcScript = WideString::FromUTF8(bsArg.AsStringView());
+ absl::optional<WideTextBuffer> wsJavaScriptBuf =
+ CFXJSE_FormCalcContext::Translate(pContext->GetDocument()->GetHeap(),
+ wsCalcScript.AsStringView());
+ if (!wsJavaScriptBuf.has_value()) {
pContext->ThrowCompilerErrorException();
return;
}
-
- args.GetReturnValue()->SetString(
- FX_UTF8Encode(wsJavaScriptBuf.AsStringView()).AsStringView());
+ info.GetReturnValue().Set(fxv8::NewStringHelper(
+ info.GetIsolate(),
+ FX_UTF8Encode(wsJavaScriptBuf.value().AsStringView()).AsStringView()));
}
// static
-void CFXJSE_FormCalcContext::is_fm_object(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- args.GetReturnValue()->SetBoolean(false);
- return;
- }
-
- std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
- args.GetReturnValue()->SetBoolean(argOne->IsObject());
+void CFXJSE_FormCalcContext::is_fm_object(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ const bool result = info.Length() == 1 && fxv8::IsObject(info[0]);
+ info.GetReturnValue().Set(result);
}
// static
-void CFXJSE_FormCalcContext::is_fm_array(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
- args.GetReturnValue()->SetBoolean(false);
- return;
- }
-
- std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
- args.GetReturnValue()->SetBoolean(argOne->IsArray());
+void CFXJSE_FormCalcContext::is_fm_array(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ const bool result = info.Length() == 1 && fxv8::IsArray(info[0]);
+ info.GetReturnValue().Set(result);
}
// static
-void CFXJSE_FormCalcContext::get_fm_value(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::get_fm_value(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 1) {
+ if (info.Length() != 1) {
pContext->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
- if (argOne->IsArray()) {
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argOne->GetObjectPropertyByIdx(1, propertyValue.get());
- argOne->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (propertyValue->IsNull()) {
- GetObjectDefaultValue(jsObjectValue.get(), args.GetReturnValue());
+ v8::Local<v8::Value> argOne = info[0];
+ if (fxv8::IsArray(argOne)) {
+ v8::Local<v8::Array> arr = argOne.As<v8::Array>();
+ v8::Local<v8::Value> propertyValue =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 1);
+ v8::Local<v8::Value> jsValue =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 2);
+ if (!fxv8::IsObject(jsValue)) {
+ info.GetReturnValue().Set(fxv8::NewUndefinedHelper(info.GetIsolate()));
return;
}
-
- jsObjectValue->GetObjectProperty(propertyValue->ToString().AsStringView(),
- args.GetReturnValue());
+ v8::Local<v8::Object> jsObjectValue = jsValue.As<v8::Object>();
+ if (fxv8::IsNull(propertyValue)) {
+ info.GetReturnValue().Set(
+ GetObjectDefaultValue(info.GetIsolate(), jsObjectValue));
+ return;
+ }
+ ByteString bsName =
+ fxv8::ReentrantToByteStringHelper(info.GetIsolate(), propertyValue);
+ info.GetReturnValue().Set(fxv8::ReentrantGetObjectPropertyHelper(
+ info.GetIsolate(), jsObjectValue, bsName.AsStringView()));
return;
}
- if (argOne->IsObject()) {
- GetObjectDefaultValue(argOne.get(), args.GetReturnValue());
+ if (fxv8::IsObject(argOne)) {
+ v8::Local<v8::Object> obj = argOne.As<v8::Object>();
+ info.GetReturnValue().Set(GetObjectDefaultValue(info.GetIsolate(), obj));
return;
}
- args.GetReturnValue()->Assign(argOne.get());
+ info.GetReturnValue().Set(argOne);
}
// static
-void CFXJSE_FormCalcContext::get_fm_jsobj(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- if (args.GetLength() != 1) {
+void CFXJSE_FormCalcContext::get_fm_jsobj(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ if (info.Length() != 1) {
ToFormCalcContext(pThis)->ThrowCompilerErrorException();
return;
}
- std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
- if (!argOne->IsArray()) {
- args.GetReturnValue()->Assign(argOne.get());
+ v8::Local<v8::Value> argOne = info[0];
+ if (!fxv8::IsArray(argOne)) {
+ info.GetReturnValue().Set(argOne);
return;
}
-#ifndef NDEBUG
- CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argOne->GetObjectProperty("length", lengthValue.get());
- ASSERT(lengthValue->ToInteger() >= 3);
-#endif
-
- argOne->GetObjectPropertyByIdx(2, args.GetReturnValue());
+ v8::Local<v8::Array> arr = argOne.As<v8::Array>();
+ info.GetReturnValue().Set(
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 2));
}
// static
-void CFXJSE_FormCalcContext::fm_var_filter(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
+void CFXJSE_FormCalcContext::fm_var_filter(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- if (args.GetLength() != 1) {
+ if (info.Length() != 1) {
pContext->ThrowCompilerErrorException();
return;
}
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
- std::unique_ptr<CFXJSE_Value> argOne = args.GetValue(0);
- if (!argOne->IsArray()) {
- std::unique_ptr<CFXJSE_Value> simpleValue = GetSimpleValue(pThis, args, 0);
- args.GetReturnValue()->Assign(simpleValue.get());
+ v8::Local<v8::Value> argOne = info[0];
+ if (!fxv8::IsArray(argOne)) {
+ info.GetReturnValue().Set(GetSimpleValue(info, 0));
return;
}
-#ifndef NDEBUG
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argOne->GetObjectProperty("length", lengthValue.get());
- ASSERT(lengthValue->ToInteger() >= 3);
-#endif
-
- auto flagsValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argOne->GetObjectPropertyByIdx(0, flagsValue.get());
- int32_t iFlags = flagsValue->ToInteger();
+ v8::Local<v8::Array> arr = argOne.As<v8::Array>();
+ v8::Local<v8::Value> flagsValue =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 0);
+ int32_t iFlags = fxv8::ReentrantToInt32Helper(info.GetIsolate(), flagsValue);
if (iFlags != 3 && iFlags != 4) {
- std::unique_ptr<CFXJSE_Value> simpleValue = GetSimpleValue(pThis, args, 0);
- args.GetReturnValue()->Assign(simpleValue.get());
+ info.GetReturnValue().Set(GetSimpleValue(info, 0));
return;
}
if (iFlags == 4) {
- std::vector<std::unique_ptr<CFXJSE_Value>> values;
- for (int32_t i = 0; i < 3; i++)
- values.push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
-
- values[0]->SetInteger(3);
- values[1]->SetNull();
- values[2]->SetNull();
- args.GetReturnValue()->SetArray(values);
+ std::vector<v8::Local<v8::Value>> values(3);
+ values[0] = fxv8::NewNumberHelper(info.GetIsolate(), 3);
+ values[1] = fxv8::NewNullHelper(info.GetIsolate());
+ values[2] = fxv8::NewNullHelper(info.GetIsolate());
+ info.GetReturnValue().Set(fxv8::NewArrayHelper(info.GetIsolate(), values));
return;
}
- auto objectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argOne->GetObjectPropertyByIdx(2, objectValue.get());
- if (objectValue->IsNull()) {
+ v8::Local<v8::Value> objectValue =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 2);
+ if (fxv8::IsNull(objectValue)) {
pContext->ThrowCompilerErrorException();
return;
}
- args.GetReturnValue()->Assign(argOne.get());
+ info.GetReturnValue().Set(argOne);
}
// static
-void CFXJSE_FormCalcContext::concat_fm_object(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args) {
- v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
- uint32_t iLength = 0;
- int32_t argc = args.GetLength();
- std::vector<std::unique_ptr<CFXJSE_Value>> argValues;
- for (int32_t i = 0; i < argc; i++) {
- argValues.push_back(args.GetValue(i));
- if (argValues[i]->IsArray()) {
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValues[i]->GetObjectProperty("length", lengthValue.get());
- int32_t length = lengthValue->ToInteger();
- iLength = iLength + ((length > 2) ? (length - 2) : 0);
- }
- ++iLength;
- }
-
- std::vector<std::unique_ptr<CFXJSE_Value>> returnValues;
- for (int32_t i = 0; i < (int32_t)iLength; i++)
- returnValues.push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
-
- int32_t index = 0;
- for (int32_t i = 0; i < argc; i++) {
- if (argValues[i]->IsArray()) {
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argValues[i]->GetObjectProperty("length", lengthValue.get());
-
- int32_t length = lengthValue->ToInteger();
- for (int32_t j = 2; j < length; j++) {
- argValues[i]->GetObjectPropertyByIdx(j, returnValues[index].get());
- index++;
+void CFXJSE_FormCalcContext::concat_fm_object(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetIsolate();
+ std::vector<v8::Local<v8::Value>> returnValues;
+ for (int i = 0; i < info.Length(); ++i) {
+ if (fxv8::IsArray(info[i])) {
+ v8::Local<v8::Array> arr = info[i].As<v8::Array>();
+ uint32_t length = fxv8::GetArrayLengthHelper(arr);
+ for (uint32_t j = 2; j < length; j++) {
+ returnValues.push_back(
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, j));
}
}
- returnValues[index]->Assign(argValues[i].get());
- index++;
+ returnValues.push_back(info[i]);
}
- args.GetReturnValue()->SetArray(returnValues);
-}
-
-// static
-std::unique_ptr<CFXJSE_Value> CFXJSE_FormCalcContext::GetSimpleValue(
- CFXJSE_Value* pThis,
- CFXJSE_Arguments& args,
- uint32_t index) {
- v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
- ASSERT(index < (uint32_t)args.GetLength());
-
- std::unique_ptr<CFXJSE_Value> argIndex = args.GetValue(index);
- if (!argIndex->IsArray() && !argIndex->IsObject())
- return argIndex;
-
- if (argIndex->IsArray()) {
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argIndex->GetObjectProperty("length", lengthValue.get());
- int32_t iLength = lengthValue->ToInteger();
- auto simpleValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- if (iLength < 3) {
- simpleValue.get()->SetUndefined();
- return simpleValue;
- }
-
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argIndex->GetObjectPropertyByIdx(1, propertyValue.get());
- argIndex->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (propertyValue->IsNull()) {
- GetObjectDefaultValue(jsObjectValue.get(), simpleValue.get());
- return simpleValue;
- }
-
- jsObjectValue->GetObjectProperty(propertyValue->ToString().AsStringView(),
- simpleValue.get());
- return simpleValue;
- }
-
- auto defaultValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(argIndex.get(), defaultValue.get());
- return defaultValue;
-}
-
-// static
-bool CFXJSE_FormCalcContext::ValueIsNull(CFXJSE_Value* pThis,
- CFXJSE_Value* arg) {
- if (!arg || arg->IsNull())
- return true;
-
- if (!arg->IsArray() && !arg->IsObject())
- return false;
-
- v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
- if (arg->IsArray()) {
- int32_t iLength = hvalue_get_array_length(pThis, arg);
- if (iLength < 3)
- return true;
-
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- arg->GetObjectPropertyByIdx(1, propertyValue.get());
- arg->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (propertyValue->IsNull()) {
- auto defaultValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(jsObjectValue.get(), defaultValue.get());
- return defaultValue->IsNull();
- }
-
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- jsObjectValue->GetObjectProperty(propertyValue->ToString().AsStringView(),
- newPropertyValue.get());
- return newPropertyValue->IsNull();
- }
-
- auto defaultValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(arg, defaultValue.get());
- return defaultValue->IsNull();
-}
-
-// static
-int32_t CFXJSE_FormCalcContext::hvalue_get_array_length(CFXJSE_Value* pThis,
- CFXJSE_Value* arg) {
- if (!arg || !arg->IsArray())
- return 0;
-
- v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- arg->GetObjectProperty("length", lengthValue.get());
- return lengthValue->ToInteger();
-}
-
-// static
-bool CFXJSE_FormCalcContext::simpleValueCompare(CFXJSE_Value* pThis,
- CFXJSE_Value* firstValue,
- CFXJSE_Value* secondValue) {
- if (!firstValue)
- return false;
-
- if (firstValue->IsString()) {
- ByteString bsFirst = ValueToUTF8String(firstValue);
- ByteString bsSecond = ValueToUTF8String(secondValue);
- return bsFirst == bsSecond;
- }
- if (firstValue->IsNumber()) {
- float first = ValueToFloat(pThis, firstValue);
- float second = ValueToFloat(pThis, secondValue);
- return first == second;
- }
- if (firstValue->IsBoolean())
- return firstValue->ToBoolean() == secondValue->ToBoolean();
-
- return firstValue->IsNull() && secondValue && secondValue->IsNull();
-}
-
-// static
-std::vector<std::unique_ptr<CFXJSE_Value>> CFXJSE_FormCalcContext::unfoldArgs(
- 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()) {
- 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());
- 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());
- jsObjectValue->GetObjectProperty(
- propertyValue->ToString().AsStringView(), results[index].get());
- index++;
- }
- }
- } else if (argsValue[i]->IsObject()) {
- GetObjectDefaultValue(argsValue[i].get(), results[index].get());
- index++;
- } else {
- results[index]->Assign(argsValue[i].get());
- index++;
- }
- }
- return results;
-}
-
-// static
-void CFXJSE_FormCalcContext::GetObjectDefaultValue(
- CFXJSE_Value* pValue,
- CFXJSE_Value* pDefaultValue) {
- CXFA_Node* pNode = ToNode(CFXJSE_Engine::ToObject(pValue));
- if (!pNode) {
- pDefaultValue->SetNull();
- return;
- }
- pNode->JSObject()->ScriptSomDefaultValue(pDefaultValue, false,
- XFA_Attribute::Unknown);
-}
-
-// static
-bool CFXJSE_FormCalcContext::SetObjectDefaultValue(CFXJSE_Value* pValue,
- CFXJSE_Value* hNewValue) {
- CXFA_Node* pNode = ToNode(CFXJSE_Engine::ToObject(pValue));
- if (!pNode)
- return false;
-
- pNode->JSObject()->ScriptSomDefaultValue(hNewValue, true,
- XFA_Attribute::Unknown);
- return true;
+ info.GetReturnValue().Set(fxv8::NewArrayHelper(pIsolate, returnValues));
}
// static
@@ -5400,6 +5258,8 @@
if (bIsStar)
return ByteString(bsName, "[*]");
+ // `iIndexFlags` values are the same as enum class
+ // `CXFA_FMIndexExpression::AccessorIndex` values.
if (iIndexFlags == 0)
return ByteString(bsName);
@@ -5410,311 +5270,53 @@
const bool bNegative = iIndexValue < 0;
ByteString bsSomExp(bsName);
- if (iIndexFlags == 2)
+ if (iIndexFlags == 2) {
bsSomExp += bNegative ? "[-" : "[+";
- else
+ } else {
+ DCHECK_EQ(iIndexFlags, 3);
bsSomExp += bNegative ? "[" : "[-";
- iIndexValue = bNegative ? 0 - iIndexValue : iIndexValue;
- bsSomExp += ByteString::FormatInteger(iIndexValue);
+ }
+
+ FX_SAFE_INT32 safe_index = iIndexValue;
+ if (bNegative)
+ safe_index = -safe_index;
+ bsSomExp += ByteString::FormatInteger(safe_index.ValueOrDefault(0));
bsSomExp += "]";
return bsSomExp;
}
-// static
-bool CFXJSE_FormCalcContext::GetObjectForName(CFXJSE_Value* pThis,
- CFXJSE_Value* accessorValue,
- ByteStringView bsAccessorName) {
- CXFA_Document* pDoc = ToFormCalcContext(pThis)->GetDocument();
- if (!pDoc)
- return false;
+absl::optional<WideTextBuffer> CFXJSE_FormCalcContext::Translate(
+ cppgc::Heap* pHeap,
+ WideStringView wsFormcalc) {
+ if (wsFormcalc.IsEmpty())
+ return WideTextBuffer();
- CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
- XFA_RESOLVENODE_RS resolveNodeRS;
- uint32_t dwFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
- XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
- bool bRet = pScriptContext->ResolveObjects(
- pScriptContext->GetThisObject(),
- WideString::FromUTF8(bsAccessorName).AsStringView(), &resolveNodeRS,
- dwFlags, nullptr);
- if (bRet && resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) {
- accessorValue->Assign(pScriptContext->GetOrCreateJSBindingFromMap(
- resolveNodeRS.objects.front().Get()));
- return true;
- }
- return false;
-}
-
-// static
-bool CFXJSE_FormCalcContext::ResolveObjects(CFXJSE_Value* pThis,
- CFXJSE_Value* pRefValue,
- ByteStringView bsSomExp,
- XFA_RESOLVENODE_RS* resolveNodeRS,
- bool bDotAccessor,
- bool bHasNoResolveName) {
- CXFA_Document* pDoc = ToFormCalcContext(pThis)->GetDocument();
- if (!pDoc)
- return false;
-
- WideString wsSomExpression = WideString::FromUTF8(bsSomExp);
- CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
- CXFA_Object* pNode = nullptr;
- uint32_t dFlags = 0UL;
- if (bDotAccessor) {
- if (pRefValue && pRefValue->IsNull()) {
- pNode = pScriptContext->GetThisObject();
- dFlags = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
- } else {
- pNode = CFXJSE_Engine::ToObject(pRefValue);
- if (!pNode)
- return false;
-
- if (bHasNoResolveName) {
- WideString wsName;
- if (CXFA_Node* pXFANode = pNode->AsNode()) {
- Optional<WideString> ret =
- pXFANode->JSObject()->TryAttribute(XFA_Attribute::Name, false);
- if (ret)
- wsName = *ret;
- }
- if (wsName.IsEmpty())
- wsName = L"#" + WideString::FromASCII(pNode->GetClassName());
-
- wsSomExpression = wsName + wsSomExpression;
- dFlags = XFA_RESOLVENODE_Siblings;
- } else {
- dFlags = (bsSomExp == "*")
- ? (XFA_RESOLVENODE_Children)
- : (XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
- XFA_RESOLVENODE_Properties);
- }
- }
- } else {
- pNode = CFXJSE_Engine::ToObject(pRefValue);
- dFlags = XFA_RESOLVENODE_AnyChild;
- }
- return pScriptContext->ResolveObjects(pNode, wsSomExpression.AsStringView(),
- resolveNodeRS, dFlags, nullptr);
-}
-
-// static
-void CFXJSE_FormCalcContext::ParseResolveResult(
- CFXJSE_Value* pThis,
- const XFA_RESOLVENODE_RS& resolveNodeRS,
- CFXJSE_Value* pParentValue,
- std::vector<std::unique_ptr<CFXJSE_Value>>* resultValues,
- bool* bAttribute) {
- ASSERT(bAttribute);
-
- resultValues->clear();
-
- CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
-
- if (resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) {
- *bAttribute = false;
- CFXJSE_Engine* pScriptContext = pContext->GetDocument()->GetScriptContext();
- for (auto& pObject : resolveNodeRS.objects) {
- resultValues->push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
- resultValues->back()->Assign(
- pScriptContext->GetOrCreateJSBindingFromMap(pObject.Get()));
- }
- return;
- }
-
- *bAttribute = true;
- if (resolveNodeRS.script_attribute.callback &&
- resolveNodeRS.script_attribute.eValueType == XFA_ScriptType::Object) {
- for (auto& pObject : resolveNodeRS.objects) {
- auto pValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- CJX_Object* jsObject = pObject->JSObject();
- (*resolveNodeRS.script_attribute.callback)(
- jsObject, pValue.get(), false,
- resolveNodeRS.script_attribute.attribute);
- resultValues->push_back(std::move(pValue));
- *bAttribute = false;
- }
- }
- if (!*bAttribute)
- return;
- if (!pParentValue || !pParentValue->IsObject())
- return;
-
- resultValues->push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
- resultValues->back()->Assign(pParentValue);
-}
-
-// static
-int32_t CFXJSE_FormCalcContext::ValueToInteger(CFXJSE_Value* pThis,
- CFXJSE_Value* pValue) {
- if (!pValue || pValue->IsEmpty())
- return 0;
-
- v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
- if (pValue->IsArray()) {
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- pValue->GetObjectPropertyByIdx(1, propertyValue.get());
- pValue->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (propertyValue->IsNull()) {
- GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
- return ValueToInteger(pThis, newPropertyValue.get());
- }
-
- jsObjectValue->GetObjectProperty(propertyValue->ToString().AsStringView(),
- newPropertyValue.get());
- return ValueToInteger(pThis, newPropertyValue.get());
- }
- if (pValue->IsObject()) {
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(pValue, newPropertyValue.get());
- return ValueToInteger(pThis, newPropertyValue.get());
- }
- if (pValue->IsString())
- return FXSYS_atoi(pValue->ToString().c_str());
- return pValue->ToInteger();
-}
-
-// static
-float CFXJSE_FormCalcContext::ValueToFloat(CFXJSE_Value* pThis,
- CFXJSE_Value* arg) {
- if (!arg)
- return 0.0f;
-
- v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
- if (arg->IsArray()) {
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- arg->GetObjectPropertyByIdx(1, propertyValue.get());
- arg->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (propertyValue->IsNull()) {
- GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
- return ValueToFloat(pThis, newPropertyValue.get());
- }
- jsObjectValue->GetObjectProperty(propertyValue->ToString().AsStringView(),
- newPropertyValue.get());
- return ValueToFloat(pThis, newPropertyValue.get());
- }
- if (arg->IsObject()) {
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(arg, newPropertyValue.get());
- return ValueToFloat(pThis, newPropertyValue.get());
- }
- if (arg->IsString())
- return strtof(arg->ToString().c_str(), nullptr);
- if (arg->IsUndefined() || arg->IsEmpty())
- return 0.0f;
- return arg->ToFloat();
-}
-
-// static
-double CFXJSE_FormCalcContext::ValueToDouble(CFXJSE_Value* pThis,
- CFXJSE_Value* arg) {
- if (!arg)
- return 0;
-
- v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
- if (arg->IsArray()) {
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- arg->GetObjectPropertyByIdx(1, propertyValue.get());
- arg->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (propertyValue->IsNull()) {
- GetObjectDefaultValue(jsObjectValue.get(), newPropertyValue.get());
- return ValueToDouble(pThis, newPropertyValue.get());
- }
- jsObjectValue->GetObjectProperty(propertyValue->ToString().AsStringView(),
- newPropertyValue.get());
- return ValueToDouble(pThis, newPropertyValue.get());
- }
- if (arg->IsObject()) {
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- GetObjectDefaultValue(arg, newPropertyValue.get());
- return ValueToDouble(pThis, newPropertyValue.get());
- }
- if (arg->IsString())
- return strtod(arg->ToString().c_str(), nullptr);
- if (arg->IsUndefined() || arg->IsEmpty())
- return 0;
- return arg->ToDouble();
-}
-
-// static.
-double CFXJSE_FormCalcContext::ExtractDouble(CFXJSE_Value* pThis,
- CFXJSE_Value* src,
- bool* ret) {
- ASSERT(ret);
- *ret = true;
-
- if (!src)
- return 0;
-
- if (!src->IsArray())
- return ValueToDouble(pThis, src);
-
- v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetScriptRuntime();
- auto lengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- src->GetObjectProperty("length", lengthValue.get());
- int32_t iLength = lengthValue->ToInteger();
- if (iLength <= 2) {
- *ret = false;
- return 0.0;
- }
-
- auto propertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- auto jsObjectValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- src->GetObjectPropertyByIdx(1, propertyValue.get());
- src->GetObjectPropertyByIdx(2, jsObjectValue.get());
- if (propertyValue->IsNull())
- return ValueToDouble(pThis, jsObjectValue.get());
-
- auto newPropertyValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- jsObjectValue->GetObjectProperty(propertyValue->ToString().AsStringView(),
- newPropertyValue.get());
- return ValueToDouble(pThis, newPropertyValue.get());
-}
-
-// static
-ByteString CFXJSE_FormCalcContext::ValueToUTF8String(CFXJSE_Value* arg) {
- if (!arg || arg->IsNull() || arg->IsUndefined() || arg->IsEmpty())
- return ByteString();
- if (arg->IsBoolean())
- return arg->ToBoolean() ? "1" : "0";
- return arg->ToString();
-}
-
-// static.
-bool CFXJSE_FormCalcContext::Translate(WideStringView wsFormcalc,
- CFX_WideTextBuf* wsJavascript) {
- if (wsFormcalc.IsEmpty()) {
- wsJavascript->Clear();
- return true;
- }
-
- CXFA_FMParser parser(wsFormcalc);
- std::unique_ptr<CXFA_FMAST> ast = parser.Parse();
+ CXFA_FMLexer lexer(wsFormcalc);
+ CXFA_FMParser parser(pHeap, &lexer);
+ CXFA_FMAST* ast = parser.Parse();
if (!ast || parser.HasError())
- return false;
+ return absl::nullopt;
CXFA_FMToJavaScriptDepth::Reset();
- if (!ast->ToJavaScript(wsJavascript))
- return false;
+ absl::optional<WideTextBuffer> wsJavaScript = ast->ToJavaScript();
+ if (!wsJavaScript.has_value())
+ return absl::nullopt;
- wsJavascript->AppendChar(0);
- return !CXFA_IsTooBig(wsJavascript);
+ if (CXFA_IsTooBig(wsJavaScript.value()))
+ return absl::nullopt;
+
+ return wsJavaScript;
}
-CFXJSE_FormCalcContext::CFXJSE_FormCalcContext(v8::Isolate* pScriptIsolate,
+CFXJSE_FormCalcContext::CFXJSE_FormCalcContext(v8::Isolate* pIsolate,
CFXJSE_Context* pScriptContext,
CXFA_Document* pDoc)
- : m_pIsolate(pScriptIsolate),
- m_pValue(pdfium::MakeUnique<CFXJSE_Value>(pScriptIsolate)),
- m_pDocument(pDoc) {
- m_pValue->SetHostObject(
- this,
- CFXJSE_Class::Create(pScriptContext, &kFormCalcFM2JSDescriptor, false));
+ : m_pIsolate(pIsolate), m_pDocument(pDoc) {
+ m_Value.Reset(m_pIsolate,
+ NewBoundV8Object(
+ m_pIsolate, CFXJSE_Class::Create(
+ pScriptContext, &kFormCalcDescriptor, false)
+ ->GetTemplate(m_pIsolate)));
}
CFXJSE_FormCalcContext::~CFXJSE_FormCalcContext() = default;
@@ -5723,18 +5325,18 @@
return this;
}
-void CFXJSE_FormCalcContext::GlobalPropertyGetter(CFXJSE_Value* pValue) {
- pValue->Assign(m_pValue.get());
+v8::Local<v8::Value> CFXJSE_FormCalcContext::GlobalPropertyGetter() {
+ return v8::Local<v8::Value>::New(m_pIsolate, m_Value);
}
// static
-void CFXJSE_FormCalcContext::DotAccessorCommon(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args,
- bool bDotAccessor) {
+void CFXJSE_FormCalcContext::DotAccessorCommon(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info,
+ bool bDotAccessor) {
CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
- v8::Isolate* pIsolate = pContext->GetScriptRuntime();
- int32_t argc = args.GetLength();
+ v8::Isolate* pIsolate = pContext->GetIsolate();
+ int32_t argc = info.Length();
if (argc < 4 || argc > 5) {
pContext->ThrowCompilerErrorException();
return;
@@ -5744,148 +5346,207 @@
int32_t iIndexValue = 0;
if (argc > 4) {
bIsStar = false;
- iIndexValue = ValueToInteger(pThis, args.GetValue(4).get());
+ iIndexValue = ValueToInteger(info.GetIsolate(), info[4]);
}
- const ByteString bsName = args.GetUTF8String(2);
+ const ByteString bsName =
+ fxv8::ReentrantToByteStringHelper(info.GetIsolate(), info[2]);
const bool bHasNoResolveName = bDotAccessor && bsName.IsEmpty();
ByteString bsSomExp = GenerateSomExpression(
- bsName.AsStringView(), args.GetInt32(3), iIndexValue, bIsStar);
+ bsName.AsStringView(),
+ fxv8::ReentrantToInt32Helper(info.GetIsolate(), info[3]), iIndexValue,
+ bIsStar);
- std::unique_ptr<CFXJSE_Value> argAccessor = args.GetValue(0);
- if (argAccessor->IsArray()) {
- auto pLengthValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- argAccessor->GetObjectProperty("length", pLengthValue.get());
- int32_t iLength = pLengthValue->ToInteger();
+ v8::Local<v8::Value> argAccessor = info[0];
+ if (fxv8::IsArray(argAccessor)) {
+ v8::Local<v8::Array> arr = argAccessor.As<v8::Array>();
+ uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
if (iLength < 3) {
pContext->ThrowArgumentMismatchException();
return;
}
- int32_t iCounter = 0;
- auto hJSObjValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
- std::vector<std::vector<std::unique_ptr<CFXJSE_Value>>> resolveValues(
- iLength - 2);
+ std::vector<std::vector<v8::Local<v8::Value>>> resolveValues(iLength - 2);
bool bAttribute = false;
- for (int32_t i = 2; i < iLength; i++) {
- argAccessor->GetObjectPropertyByIdx(i, hJSObjValue.get());
- XFA_RESOLVENODE_RS resolveNodeRS;
- if (ResolveObjects(pThis, hJSObjValue.get(), bsSomExp.AsStringView(),
- &resolveNodeRS, bDotAccessor, bHasNoResolveName)) {
- ParseResolveResult(pThis, resolveNodeRS, hJSObjValue.get(),
- &resolveValues[i - 2], &bAttribute);
- iCounter += resolveValues[i - 2].size();
+ bool bAllEmpty = true;
+ for (uint32_t i = 2; i < iLength; i++) {
+ v8::Local<v8::Value> hJSObjValue =
+ fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, i);
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+ ResolveObjects(pThis, hJSObjValue, bsSomExp.AsStringView(),
+ bDotAccessor, bHasNoResolveName);
+ if (maybeResult.has_value()) {
+ resolveValues[i - 2] = ParseResolveResult(pThis, maybeResult.value(),
+ hJSObjValue, &bAttribute);
+ bAllEmpty = bAllEmpty && resolveValues[i - 2].empty();
}
}
- if (iCounter < 1) {
- pContext->ThrowPropertyNotInObjectException(
- WideString::FromUTF8(bsName.AsStringView()),
- WideString::FromUTF8(bsSomExp.AsStringView()));
+ if (bAllEmpty) {
+ pContext->ThrowPropertyNotInObjectException(bsName.AsStringView(),
+ bsSomExp.AsStringView());
return;
}
- std::vector<std::unique_ptr<CFXJSE_Value>> values;
- for (int32_t i = 0; i < iCounter + 2; i++)
- values.push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
-
- values[0]->SetInteger(1);
- if (bAttribute)
- values[1]->SetString(bsName.AsStringView());
- else
- values[1]->SetNull();
-
- int32_t iIndex = 2;
- for (int32_t i = 0; i < iLength - 2; i++) {
- for (size_t j = 0; j < resolveValues[i].size(); j++) {
- values[iIndex]->Assign(resolveValues[i][j].get());
- iIndex++;
- }
+ std::vector<v8::Local<v8::Value>> values;
+ values.push_back(fxv8::NewNumberHelper(pIsolate, 1));
+ values.push_back(
+ bAttribute ? fxv8::NewStringHelper(pIsolate, bsName.AsStringView())
+ .As<v8::Value>()
+ : fxv8::NewNullHelper(pIsolate).As<v8::Value>());
+ for (uint32_t i = 0; i < iLength - 2; i++) {
+ for (size_t j = 0; j < resolveValues[i].size(); j++)
+ values.push_back(resolveValues[i][j]);
}
- args.GetReturnValue()->SetArray(values);
+ info.GetReturnValue().Set(fxv8::NewArrayHelper(pIsolate, values));
return;
}
- XFA_RESOLVENODE_RS resolveNodeRS;
- bool bRet = false;
- ByteString bsAccessorName = args.GetUTF8String(1);
- if (argAccessor->IsObject() ||
- (argAccessor->IsNull() && bsAccessorName.IsEmpty())) {
- bRet = ResolveObjects(pThis, argAccessor.get(), bsSomExp.AsStringView(),
- &resolveNodeRS, bDotAccessor, bHasNoResolveName);
- } else if (!argAccessor->IsObject() && !bsAccessorName.IsEmpty() &&
- GetObjectForName(pThis, argAccessor.get(),
- bsAccessorName.AsStringView())) {
- bRet = ResolveObjects(pThis, argAccessor.get(), bsSomExp.AsStringView(),
- &resolveNodeRS, bDotAccessor, bHasNoResolveName);
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult;
+ ByteString bsAccessorName =
+ fxv8::ReentrantToByteStringHelper(info.GetIsolate(), info[1]);
+ if (fxv8::IsObject(argAccessor) ||
+ (fxv8::IsNull(argAccessor) && bsAccessorName.IsEmpty())) {
+ maybeResult = ResolveObjects(pThis, argAccessor, bsSomExp.AsStringView(),
+ bDotAccessor, bHasNoResolveName);
+ } else if (!fxv8::IsObject(argAccessor) && !bsAccessorName.IsEmpty()) {
+ v8::Local<v8::Value> obj =
+ GetObjectForName(pThis, bsAccessorName.AsStringView());
+ if (!obj.IsEmpty()) {
+ argAccessor = obj;
+ maybeResult = ResolveObjects(pThis, argAccessor, bsSomExp.AsStringView(),
+ bDotAccessor, bHasNoResolveName);
+ }
}
- if (!bRet) {
- pContext->ThrowPropertyNotInObjectException(
- WideString::FromUTF8(bsName.AsStringView()),
- WideString::FromUTF8(bsSomExp.AsStringView()));
+ if (!maybeResult.has_value()) {
+ pContext->ThrowPropertyNotInObjectException(bsName.AsStringView(),
+ bsSomExp.AsStringView());
return;
}
- std::vector<std::unique_ptr<CFXJSE_Value>> resolveValues;
bool bAttribute = false;
- ParseResolveResult(pThis, resolveNodeRS, argAccessor.get(), &resolveValues,
- &bAttribute);
+ std::vector<v8::Local<v8::Value>> resolveValues =
+ ParseResolveResult(pThis, maybeResult.value(), argAccessor, &bAttribute);
- std::vector<std::unique_ptr<CFXJSE_Value>> values;
- for (size_t i = 0; i < resolveValues.size() + 2; i++)
- values.push_back(pdfium::MakeUnique<CFXJSE_Value>(pIsolate));
-
- values[0]->SetInteger(1);
- if (bAttribute)
- values[1]->SetString(bsName.AsStringView());
- else
- values[1]->SetNull();
+ std::vector<v8::Local<v8::Value>> values(resolveValues.size() + 2);
+ values[0] = fxv8::NewNumberHelper(pIsolate, 1);
+ values[1] = bAttribute
+ ? fxv8::NewStringHelper(pIsolate, bsName.AsStringView())
+ .As<v8::Value>()
+ : fxv8::NewNullHelper(pIsolate).As<v8::Value>();
for (size_t i = 0; i < resolveValues.size(); i++)
- values[i + 2]->Assign(resolveValues[i].get());
+ values[i + 2] = resolveValues[i];
- args.GetReturnValue()->SetArray(values);
+ info.GetReturnValue().Set(fxv8::NewArrayHelper(pIsolate, values));
+}
+
+bool CFXJSE_FormCalcContext::ApplyToExpansion(
+ std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn,
+ const v8::FunctionCallbackInfo<v8::Value>& info,
+ bool bStrict) {
+ v8::Isolate* pIsolate = info.GetIsolate();
+ for (int32_t i = 0; i < info.Length(); i++) {
+ v8::Local<v8::Value> argValue = info[i];
+ if (fxv8::IsArray(argValue)) {
+ if (!ApplyToArray(pIsolate, fn, argValue.As<v8::Array>()) && bStrict) {
+ ThrowArgumentMismatchException();
+ return false;
+ }
+ } else if (fxv8::IsObject(argValue)) {
+ ApplyToObject(pIsolate, fn, argValue.As<v8::Object>());
+ } else if (!fxv8::IsNull(argValue)) {
+ fn(pIsolate, argValue);
+ }
+ }
+ return true;
+}
+
+bool CFXJSE_FormCalcContext::ApplyToArray(
+ v8::Isolate* pIsolate,
+ std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn,
+ v8::Local<v8::Array> pArray) {
+ uint32_t iLength = fxv8::GetArrayLengthHelper(pArray);
+ if (iLength < 3)
+ return false;
+
+ v8::Local<v8::Value> propertyValue =
+ fxv8::ReentrantGetArrayElementHelper(pIsolate, pArray, 1);
+
+ ByteString bsName;
+ const bool nullprop = fxv8::IsNull(propertyValue);
+ if (!nullprop)
+ bsName = fxv8::ReentrantToByteStringHelper(pIsolate, propertyValue);
+
+ for (uint32_t j = 2; j < iLength; j++) {
+ v8::Local<v8::Value> jsValue =
+ fxv8::ReentrantGetArrayElementHelper(pIsolate, pArray, j);
+ if (!fxv8::IsObject(jsValue))
+ continue;
+
+ v8::Local<v8::Object> jsObjectValue = jsValue.As<v8::Object>();
+ v8::Local<v8::Value> newPropertyValue =
+ nullprop ? GetObjectDefaultValue(pIsolate, jsObjectValue)
+ : fxv8::ReentrantGetObjectPropertyHelper(
+ pIsolate, jsObjectValue, bsName.AsStringView());
+ if (!fxv8::IsNull(newPropertyValue))
+ fn(pIsolate, newPropertyValue);
+ }
+ return true;
+}
+
+void CFXJSE_FormCalcContext::ApplyToObject(
+ v8::Isolate* pIsolate,
+ std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn,
+ v8::Local<v8::Object> pObject) {
+ v8::Local<v8::Value> newPropertyValue =
+ GetObjectDefaultValue(pIsolate, pObject);
+ if (!fxv8::IsNull(newPropertyValue))
+ fn(pIsolate, newPropertyValue);
}
void CFXJSE_FormCalcContext::ThrowNoDefaultPropertyException(
ByteStringView name) const {
- ThrowException(WideString::FromUTF8(name) +
- WideString::FromASCII(" doesn't have a default property."));
+ ByteString msg(name);
+ msg += " doesn't have a default property.";
+ ThrowException(msg.AsStringView());
}
void CFXJSE_FormCalcContext::ThrowCompilerErrorException() const {
- ThrowException(WideString::FromASCII("Compiler error."));
+ ThrowException("Compiler error.");
}
void CFXJSE_FormCalcContext::ThrowDivideByZeroException() const {
- ThrowException(WideString::FromASCII("Divide by zero."));
+ ThrowException("Divide by zero.");
}
void CFXJSE_FormCalcContext::ThrowServerDeniedException() const {
- ThrowException(WideString::FromASCII("Server does not permit operation."));
+ ThrowException("Server does not permit operation.");
}
void CFXJSE_FormCalcContext::ThrowPropertyNotInObjectException(
- const WideString& name,
- const WideString& exp) const {
- ThrowException(
- WideString::FromASCII("An attempt was made to reference property '") +
- name + WideString::FromASCII("' of a non-object in SOM expression ") +
- exp + L".");
+ ByteStringView name,
+ ByteStringView exp) const {
+ ByteString msg("An attempt was made to reference property '");
+ msg += name;
+ msg += "' of a non-object in SOM expression ";
+ msg += exp;
+ msg += ".";
+ ThrowException(msg.AsStringView());
}
void CFXJSE_FormCalcContext::ThrowParamCountMismatchException(
- const WideString& method) const {
- ThrowException(
- WideString::FromASCII("Incorrect number of parameters calling method '") +
- method + L"'.");
+ ByteStringView method) const {
+ ByteString msg("Incorrect number of parameters calling method '");
+ msg += method;
+ msg += "'.";
+ ThrowException(msg.AsStringView());
}
void CFXJSE_FormCalcContext::ThrowArgumentMismatchException() const {
- ThrowException(WideString::FromASCII(
- "Argument mismatch in property or function argument."));
+ ThrowException("Argument mismatch in property or function argument.");
}
-void CFXJSE_FormCalcContext::ThrowException(const WideString& str) const {
- ASSERT(!str.IsEmpty());
- FXJSE_ThrowMessage(str.ToUTF8().AsStringView());
+void CFXJSE_FormCalcContext::ThrowException(ByteStringView str) const {
+ DCHECK(!str.IsEmpty());
+ FXJSE_ThrowMessage(GetIsolate(), str);
}
diff --git a/fxjs/xfa/cfxjse_formcalc_context.h b/fxjs/xfa/cfxjse_formcalc_context.h
index cf1bc95..3c7d271 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.h
+++ b/fxjs/xfa/cfxjse_formcalc_context.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,21 +7,27 @@
#ifndef FXJS_XFA_CFXJSE_FORMCALC_CONTEXT_H_
#define FXJS_XFA_CFXJSE_FORMCALC_CONTEXT_H_
-#include <memory>
-#include <vector>
+#include <stdint.h>
-#include "core/fxcrt/unowned_ptr.h"
+#include <functional>
+
+#include "core/fxcrt/widetext_buffer.h"
#include "fxjs/xfa/fxjse.h"
-#include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "v8/include/cppgc/persistent.h"
+#include "v8/include/v8-forward.h"
+#include "v8/include/v8-persistent-handle.h"
-class CFXJSE_Arguments;
class CFXJSE_Context;
-class CFX_WideTextBuf;
class CXFA_Document;
+namespace cppgc {
+class Heap;
+} // namespace cppgc
+
class CFXJSE_FormCalcContext final : public CFXJSE_HostObject {
public:
- CFXJSE_FormCalcContext(v8::Isolate* pScriptIsolate,
+ CFXJSE_FormCalcContext(v8::Isolate* pIsolate,
CFXJSE_Context* pScriptContext,
CXFA_Document* pDoc);
~CFXJSE_FormCalcContext() override;
@@ -29,387 +35,279 @@
// CFXJSE_HostObject:
CFXJSE_FormCalcContext* AsFormCalcContext() override;
- static void Abs(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Avg(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Ceil(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Count(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Floor(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Max(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Min(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Mod(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Round(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Sum(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Date(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Date2Num(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void DateFmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void IsoDate2Num(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void IsoTime2Num(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void LocalDateFmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void LocalTimeFmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Num2Date(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Num2GMTime(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Num2Time(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Time(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Time2Num(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void TimeFmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
+ static void Abs(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Avg(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Ceil(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Count(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Floor(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Max(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Min(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Mod(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Round(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Sum(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Date(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Date2Num(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void DateFmt(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void IsoDate2Num(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void IsoTime2Num(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void LocalDateFmt(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void LocalTimeFmt(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Num2Date(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Num2GMTime(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Num2Time(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Time(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Time2Num(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void TimeFmt(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
- static ByteString Local2IsoDate(CFXJSE_Value* pThis,
+ static ByteString Local2IsoDate(CFXJSE_HostObject* pThis,
ByteStringView bsDate,
ByteStringView bsFormat,
ByteStringView bsLocale);
- static ByteString IsoDate2Local(CFXJSE_Value* pThis,
+ static ByteString IsoDate2Local(CFXJSE_HostObject* pThis,
ByteStringView bsDate,
ByteStringView bsFormat,
ByteStringView bsLocale);
- static ByteString IsoTime2Local(CFXJSE_Value* pThis,
+ static ByteString IsoTime2Local(CFXJSE_HostObject* pThis,
ByteStringView bsTime,
ByteStringView bsFormat,
ByteStringView bsLocale);
- static ByteString GetLocalDateFormat(CFXJSE_Value* pThis,
+ static ByteString GetLocalDateFormat(CFXJSE_HostObject* pThis,
int32_t iStyle,
ByteStringView bsLocale,
bool bStandard);
- static ByteString GetLocalTimeFormat(CFXJSE_Value* pThis,
+ static ByteString GetLocalTimeFormat(CFXJSE_HostObject* pThis,
int32_t iStyle,
ByteStringView bsLocale,
bool bStandard);
- static ByteString GetStandardDateFormat(CFXJSE_Value* pThis,
+ static ByteString GetStandardDateFormat(CFXJSE_HostObject* pThis,
int32_t iStyle,
ByteStringView bsLocale);
- static ByteString GetStandardTimeFormat(CFXJSE_Value* pThis,
+ static ByteString GetStandardTimeFormat(CFXJSE_HostObject* pThis,
int32_t iStyle,
ByteStringView bsLocale);
- static ByteString Num2AllTime(CFXJSE_Value* pThis,
+ static ByteString Num2AllTime(CFXJSE_HostObject* pThis,
int32_t iTime,
ByteStringView bsFormat,
ByteStringView bsLocale,
bool bGM);
- static void Apr(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void CTerm(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void FV(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void IPmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void NPV(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Pmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void PPmt(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void PV(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Rate(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Term(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Choose(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Exists(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void HasValue(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Oneof(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Within(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void If(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Eval(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Ref(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void UnitType(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void UnitValue(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
+ static void Apr(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void CTerm(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void FV(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void IPmt(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void NPV(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Pmt(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void PPmt(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void PV(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Rate(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Term(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Choose(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Exists(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void HasValue(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Oneof(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Within(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void If(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Eval(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Ref(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void UnitType(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void UnitValue(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
- static void At(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Concat(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Decode(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Encode(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Format(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Left(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Len(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Lower(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Ltrim(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Parse(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Replace(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Right(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Rtrim(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Space(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Str(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Stuff(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Substr(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Uuid(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Upper(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void WordNum(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
+ static void At(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Concat(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Decode(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Encode(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Format(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Left(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Len(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Lower(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Ltrim(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Parse(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Replace(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Right(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Rtrim(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Space(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Str(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Stuff(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Substr(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Uuid(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Upper(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void WordNum(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
- static void Get(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Post(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void Put(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void assign_value_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void logical_or_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void logical_and_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void equality_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void notequality_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static bool fm_ref_equal(CFXJSE_Value* pThis, CFXJSE_Arguments& args);
- static void less_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void lessequal_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void greater_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void greaterequal_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void plus_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void minus_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void multiple_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void divide_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void positive_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void negative_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void logical_not_operator(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void dot_accessor(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void dotdot_accessor(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void eval_translation(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void is_fm_object(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void is_fm_array(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void get_fm_value(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void get_fm_jsobj(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void fm_var_filter(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
- static void concat_fm_object(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args);
+ static void Get(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Post(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void Put(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void assign_value_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void logical_or_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void logical_and_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void equality_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void notequality_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static bool fm_ref_equal(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void less_operator(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void lessequal_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void greater_operator(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void greaterequal_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void plus_operator(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void minus_operator(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void multiple_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void divide_operator(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void positive_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void negative_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void logical_not_operator(
+ CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void dot_accessor(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void dotdot_accessor(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void eval_translation(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void is_fm_object(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void is_fm_array(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void get_fm_value(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void get_fm_jsobj(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void fm_var_filter(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void concat_fm_object(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
- static int32_t hvalue_get_array_length(CFXJSE_Value* pThis,
- CFXJSE_Value* arg);
- static bool simpleValueCompare(CFXJSE_Value* pThis,
- CFXJSE_Value* firstValue,
- CFXJSE_Value* secondValue);
- static std::vector<std::unique_ptr<CFXJSE_Value>> unfoldArgs(
- CFXJSE_Value* pThis,
- CFXJSE_Arguments& args);
- static void GetObjectDefaultValue(CFXJSE_Value* pObjectValue,
- CFXJSE_Value* pDefaultValue);
- static bool SetObjectDefaultValue(CFXJSE_Value* pObjectValue,
- CFXJSE_Value* pNewValue);
static ByteString GenerateSomExpression(ByteStringView bsName,
int32_t iIndexFlags,
int32_t iIndexValue,
bool bIsStar);
- static bool GetObjectForName(CFXJSE_Value* pThis,
- CFXJSE_Value* accessorValue,
- ByteStringView bsAccessorName);
- static bool ResolveObjects(CFXJSE_Value* pThis,
- CFXJSE_Value* pParentValue,
- ByteStringView bsSomExp,
- XFA_RESOLVENODE_RS* resolveNodeRS,
- bool bdotAccessor,
- bool bHasNoResolveName);
- static void ParseResolveResult(
- CFXJSE_Value* pThis,
- const XFA_RESOLVENODE_RS& resolveNodeRS,
- CFXJSE_Value* pParentValue,
- std::vector<std::unique_ptr<CFXJSE_Value>>* resultValues,
- bool* bAttribute);
+ static absl::optional<WideTextBuffer> Translate(cppgc::Heap* pHeap,
+ WideStringView wsFormcalc);
- static std::unique_ptr<CFXJSE_Value> GetSimpleValue(CFXJSE_Value* pThis,
- CFXJSE_Arguments& args,
- uint32_t index);
- static bool ValueIsNull(CFXJSE_Value* pThis, CFXJSE_Value* pValue);
- static int32_t ValueToInteger(CFXJSE_Value* pThis, CFXJSE_Value* pValue);
- static float ValueToFloat(CFXJSE_Value* pThis, CFXJSE_Value* pValue);
- static double ValueToDouble(CFXJSE_Value* pThis, CFXJSE_Value* pValue);
- static ByteString ValueToUTF8String(CFXJSE_Value* pValue);
- static double ExtractDouble(CFXJSE_Value* pThis,
- CFXJSE_Value* src,
- bool* ret);
-
- static bool Translate(WideStringView wsFormcalc,
- CFX_WideTextBuf* wsJavascript);
-
- void GlobalPropertyGetter(CFXJSE_Value* pValue);
-
- private:
- static void DotAccessorCommon(CFXJSE_Value* pThis,
- ByteStringView bsFuncName,
- CFXJSE_Arguments& args,
- bool bDotAccessor);
-
- v8::Isolate* GetScriptRuntime() const { return m_pIsolate.Get(); }
+ v8::Local<v8::Value> GlobalPropertyGetter();
+ v8::Isolate* GetIsolate() const { return m_pIsolate; }
CXFA_Document* GetDocument() const { return m_pDocument.Get(); }
+ private:
+ static void DotAccessorCommon(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info,
+ bool bDotAccessor);
+
+ bool ApplyToExpansion(
+ std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn,
+ const v8::FunctionCallbackInfo<v8::Value>& info,
+ bool bStrict);
+
+ bool ApplyToArray(v8::Isolate* pIsolate,
+ std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn,
+ v8::Local<v8::Array> pArray);
+
+ void ApplyToObject(v8::Isolate* pIsolate,
+ std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn,
+ v8::Local<v8::Object> pObject);
+
+ void ThrowArgumentMismatchException() const;
void ThrowNoDefaultPropertyException(ByteStringView name) const;
void ThrowCompilerErrorException() const;
void ThrowDivideByZeroException() const;
void ThrowServerDeniedException() const;
- void ThrowPropertyNotInObjectException(const WideString& name,
- const WideString& exp) const;
- void ThrowArgumentMismatchException() const;
- void ThrowParamCountMismatchException(const WideString& method) const;
- void ThrowException(const WideString& str) const;
+ void ThrowPropertyNotInObjectException(ByteStringView name,
+ ByteStringView exp) const;
+ void ThrowParamCountMismatchException(ByteStringView method) const;
+ void ThrowException(ByteStringView str) const;
- UnownedPtr<v8::Isolate> m_pIsolate;
- std::unique_ptr<CFXJSE_Value> m_pValue;
- UnownedPtr<CXFA_Document> const m_pDocument;
+ UnownedPtr<v8::Isolate> const m_pIsolate;
+ v8::Global<v8::Value> m_Value;
+ cppgc::WeakPersistent<CXFA_Document> const m_pDocument;
};
#endif // FXJS_XFA_CFXJSE_FORMCALC_CONTEXT_H_
diff --git a/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp b/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
index 19fc730..1478bf9 100644
--- a/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
@@ -1,11 +1,17 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <math.h>
+
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_engine.h"
+#include "fxjs/xfa/cfxjse_isolatetracker.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/scoped_set_tz.h"
#include "testing/xfa_js_embedder_test.h"
+#include "third_party/base/cxx17_backports.h"
#include "xfa/fxfa/cxfa_eventparam.h"
class CFXJSE_FormCalcContextEmbedderTest : public XFAJSEmbedderTest {
@@ -14,8 +20,85 @@
~CFXJSE_FormCalcContextEmbedderTest() override = default;
protected:
- bool ExecuteExpectNull(ByteStringView input) {
- return Execute(input) && GetValue()->IsNull();
+ CFXJSE_Context* GetJseContext() {
+ return GetScriptContext()->GetJseContextForTest();
+ }
+
+ void ExecuteExpectError(ByteStringView input) {
+ EXPECT_FALSE(Execute(input)) << "Program: " << input;
+ }
+
+ void ExecuteExpectNull(ByteStringView input) {
+ EXPECT_TRUE(Execute(input)) << "Program: " << input;
+
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
+ EXPECT_TRUE(fxv8::IsNull(GetValue())) << "Program: " << input;
+ }
+
+ void ExecuteExpectBool(ByteStringView input, bool expected) {
+ EXPECT_TRUE(Execute(input)) << "Program: " << input;
+
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
+ v8::Local<v8::Value> value = GetValue();
+
+ // Yes, bools might be integers, somehow.
+ EXPECT_TRUE(fxv8::IsBoolean(value) || fxv8::IsInteger(value))
+ << "Program: " << input;
+ EXPECT_EQ(expected, fxv8::ReentrantToBooleanHelper(isolate(), value))
+ << "Program: " << input;
+ }
+
+ void ExecuteExpectInt32(ByteStringView input, int32_t expected) {
+ EXPECT_TRUE(Execute(input)) << "Program: " << input;
+
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsInteger(value)) << "Program: " << input;
+ EXPECT_EQ(expected, fxv8::ReentrantToInt32Helper(isolate(), value))
+ << "Program: " << input;
+ }
+
+ void ExecuteExpectFloat(ByteStringView input, float expected) {
+ EXPECT_TRUE(Execute(input)) << "Program: " << input;
+
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsNumber(value));
+ EXPECT_FLOAT_EQ(expected, fxv8::ReentrantToFloatHelper(isolate(), value))
+ << "Program: " << input;
+ }
+
+ void ExecuteExpectFloatNear(ByteStringView input, float expected) {
+ constexpr float kPrecision = 0.000001f;
+
+ EXPECT_TRUE(Execute(input)) << "Program: " << input;
+
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsNumber(value));
+ EXPECT_NEAR(expected, fxv8::ReentrantToFloatHelper(isolate(), value),
+ kPrecision)
+ << "Program: " << input;
+ }
+
+ void ExecuteExpectNaN(ByteStringView input) {
+ EXPECT_TRUE(Execute(input)) << "Program: " << input;
+
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsNumber(value));
+ EXPECT_TRUE(isnan(fxv8::ReentrantToDoubleHelper(isolate(), value)));
+ }
+
+ void ExecuteExpectString(ByteStringView input, const char* expected) {
+ EXPECT_TRUE(Execute(input)) << "Program: " << input;
+
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsString(value));
+ EXPECT_STREQ(expected,
+ fxv8::ReentrantToByteStringHelper(isolate(), value).c_str())
+ << "Program: " << input;
}
};
@@ -32,309 +115,167 @@
TEST_F(CFXJSE_FormCalcContextEmbedderTest, TranslateNumber) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
-
- const char input[] = "123";
- EXPECT_TRUE(Execute(input));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(123, value->ToInteger()) << "Program: " << input;
+ ExecuteExpectInt32("123", 123);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Numeric) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"123 + 456", 579},
- {"2 - 3 * 10 / 2 + 7", -6},
- {"10 * 3 + 5 * 4", 50},
- {"(5 - \"abc\") * 3", 15},
- {"\"100\" / 10e1", 1},
- {"5 + null + 3", 8},
- // {"if (\"abc\") then\n"
- // " 10\n"
- // "else\n"
- // " 20\n"
- // "endif",
- // 20},
- // {"3 / 0 + 1", 0},
- {"-(17)", -17},
- {"-(-17)", 17},
- {"+(17)", 17},
- {"+(-17)", -17},
- {"if (1 < 2) then\n1\nendif", 1},
- {"if (\"abc\" > \"def\") then\n"
- " 1 and 0\n"
- "else\n"
- " 0\n"
- "endif",
- 0}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("123 + 456", 579);
+ ExecuteExpectInt32("2 - 3 * 10 / 2 + 7", -6);
+ ExecuteExpectInt32("10 * 3 + 5 * 4", 50);
+ ExecuteExpectInt32("(5 - \"abc\") * 3", 15);
+ ExecuteExpectInt32("\"100\" / 10e1", 1);
+ ExecuteExpectInt32("5 + null + 3", 8);
+#if 0
+ // TODO(thestig): Investigate these cases.
+ ExecuteExpectInt32(
+ "if (\"abc\") then\n"
+ " 10\n"
+ "else\n"
+ " 20\n"
+ "endif",
+ 20);
+ ExecuteExpectInt32("3 / 0 + 1", 0);
+#endif
+ ExecuteExpectInt32("-(17)", -17);
+ ExecuteExpectInt32("-(-17)", 17);
+ ExecuteExpectInt32("+(17)", 17);
+ ExecuteExpectInt32("+(-17)", -17);
+ ExecuteExpectInt32("if (1 < 2) then\n1\nendif", 1);
+ ExecuteExpectInt32(
+ "if (\"abc\" > \"def\") then\n"
+ " 1 and 0\n"
+ "else\n"
+ " 0\n"
+ "endif",
+ 0);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Strings) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {
- {"\"abc\"", "abc"},
- {"concat(\"The total is \", 2, \" dollars and \", 57, \" cents.\")",
- "The total is 2 dollars and 57 cents."}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("\"abc\"", "abc");
+ ExecuteExpectString(
+ "concat(\"The total is \", 2, \" dollars and \", 57, \" cents.\")",
+ "The total is 2 dollars and 57 cents.");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Booleans) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- bool result;
- } tests[] = {{"0 and 1 or 2 > 1", true},
- {"2 < 3 not 1 == 1", false},
- {"\"abc\" | 2", true},
- {"1 or 0", true},
- {"0 | 0", false},
- {"0 or 1 | 0 or 0", true},
- {"1 and 0", false},
- // {"0 & 0", true}, // TODO(dsinclair) Confirm with Reader.
- {"0 and 1 & 0 and 0", false},
- {"not(\"true\")", true},
- {"not(1)", false},
- {"3 == 3", true},
- {"3 <> 4", true},
- {"\"abc\" eq \"def\"", false},
- {"\"def\" ne \"abc\"", true},
- {"5 + 5 == 10", true},
- {"5 + 5 <> \"10\"", false},
- {"3 < 3", false},
- {"3 > 4", false},
- {"\"abc\" <= \"def\"", true},
- {"\"def\" > \"abc\"", true},
- {"12 >= 12", true},
- {"\"true\" < \"false\"", false}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger()) << "Program: " << tests[i].program;
- EXPECT_EQ(tests[i].result, value->ToBoolean())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectBool("0 and 1 or 2 > 1", true);
+ ExecuteExpectBool("2 < 3 not 1 == 1", false);
+ ExecuteExpectBool("\"abc\" | 2", true);
+ ExecuteExpectBool("1 or 0", true);
+ ExecuteExpectBool("0 | 0", false);
+ ExecuteExpectBool("0 or 1 | 0 or 0", true);
+ ExecuteExpectBool("1 and 0", false);
+ ExecuteExpectBool("0 and 1 & 0 and 0", false);
+ ExecuteExpectBool("not(\"true\")", true);
+ ExecuteExpectBool("not(1)", false);
+ ExecuteExpectBool("3 == 3", true);
+ ExecuteExpectBool("3 <> 4", true);
+ ExecuteExpectBool("\"abc\" eq \"def\"", false);
+ ExecuteExpectBool("\"def\" ne \"abc\"", true);
+ ExecuteExpectBool("5 + 5 == 10", true);
+ ExecuteExpectBool("5 + 5 <> \"10\"", false);
+ ExecuteExpectBool("3 < 3", false);
+ ExecuteExpectBool("3 > 4", false);
+ ExecuteExpectBool("\"abc\" <= \"def\"", true);
+ ExecuteExpectBool("\"def\" > \"abc\"", true);
+ ExecuteExpectBool("12 >= 12", true);
+ ExecuteExpectBool("\"true\" < \"false\"", false);
+#if 0
+ // TODO(thestig): Investigate this case.
+ // Confirm with Reader.
+ ExecuteExpectBool("0 & 0", true);
+#endif
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Abs) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {{"Abs(1.03)", 1.03f}, {"Abs(-1.03)", 1.03f}, {"Abs(0)", 0.0f}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectFloat("Abs(1.03)", 1.03f);
+ ExecuteExpectFloat("Abs(-1.03)", 1.03f);
+ ExecuteExpectFloat("Abs(0)", 0.0f);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Avg) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {{"Avg(0, 32, 16)", 16.0f}, {"Avg(2.5, 17, null)", 9.75f}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectFloat("Avg(0, 32, 16)", 16.0f);
+ ExecuteExpectFloat("Avg(2.5, 17, null)", 9.75f);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Ceil) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"Ceil(2.5875)", 3}, {"Ceil(-5.9)", -5}, {"Ceil(\"abc\")", 0}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("Ceil(2.5875)", 3);
+ ExecuteExpectInt32("Ceil(-5.9)", -5);
+ ExecuteExpectInt32("Ceil(\"abc\")", 0);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Count) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"Count(\"Tony\", \"Blue\", 41)", 3}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("Count(\"Tony\", \"Blue\", 41)", 3);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Floor) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"Floor(21.3409873)", 21},
- {"Floor(5.999965342)", 5},
- {"Floor(3.2 * 15)", 48}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("Floor(21.3409873)", 21);
+ ExecuteExpectInt32("Floor(5.999965342)", 5);
+ ExecuteExpectInt32("Floor(3.2 * 15)", 48);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Max) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"Max(234, 15, 107)", 234},
- {"Max(\"abc\", 15, \"Tony Blue\")", 15},
- {"Max(\"abc\")", 0}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("Max(234, 15, 107)", 234);
+ ExecuteExpectInt32("Max(\"abc\", 15, \"Tony Blue\")", 15);
+ ExecuteExpectInt32("Max(\"abc\")", 0);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Min) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"Min(234, 15, 107)", 15},
- // TODO(dsinclair): Verify with Reader; I believe this should
- // have a return of 0.
- // {"Min(\"abc\", 15, \"Tony Blue\")", 15},
- {"Min(\"abc\")", 0}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("Min(234, 15, 107)", 15);
+#if 0
+ // TODO(thestig): Investigate these cases.
+ // Verify with Reader; This should have a return value of 0.
+ ExecuteExpectInt32("Min(\"abc\", 15, \"Tony Blue\")", 15);
+#endif
+ ExecuteExpectInt32("Min(\"abc\")", 0);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Mod) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"Mod(64, -3)", 1}, {"Mod(-13, 3)", -1}, {"Mod(\"abc\", 2)", 0}};
+ ExecuteExpectInt32("Mod(64, -3)", 1);
+ ExecuteExpectInt32("Mod(-13, 3)", -1);
+ ExecuteExpectInt32("Mod(\"abc\", 2)", 0);
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectNaN("Mod(10, NaN)");
+ ExecuteExpectNaN("Mod(10, Infinity)");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Round) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {{"Round(12.389764537, 4)", 12.3898f},
- {"Round(20/3, 2)", 6.67f},
- {"Round(8.9897, \"abc\")", 9.0f},
- {"Round(FV(400, 0.10/12, 30*12), 2)", 904195.17f}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber()) << "Program: " << tests[i].program;
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectFloat("Round(12.389764537, 4)", 12.3898f);
+ ExecuteExpectFloat("Round(20/3, 2)", 6.67f);
+ ExecuteExpectFloat("Round(8.9897, \"abc\")", 9.0f);
+ ExecuteExpectFloat("Round(FV(400, 0.10/12, 30*12), 2)", 904195.17f);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Sum) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"Sum(2, 4, 6, 8)", 20},
- {"Sum(-2, 4, -6, 8)", 4},
- {"Sum(4, 16, \"abc\", 19)", 39}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("Sum(2, 4, 6, 8)", 20);
+ ExecuteExpectInt32("Sum(-2, 4, -6, 8)", 4);
+ ExecuteExpectInt32("Sum(4, 16, \"abc\", 19)", 39);
}
// TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Date) {
@@ -346,7 +287,7 @@
// EXPECT_TRUE(Execute("Date()"));
-// CFXJSE_Value* value = GetValue();
+// v8::Local<v8::Value> value = GetValue();
// EXPECT_TRUE(value->IsNumber());
// EXPECT_EQ(days, value->ToInteger());
// }
@@ -354,203 +295,100 @@
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Date2Num) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {
- // {"Date2Num(\"Mar 15, 1996\")", 35138},
- {"Date2Num(\"1/1/1900\", \"D/M/YYYY\")", 1},
- {"Date2Num(\"03/15/96\", \"MM/DD/YY\")", 35138},
- // {"Date2Num(\"Aug 1, 1996\", \"MMM D, YYYY\")", 35277},
- {"Date2Num(\"96-08-20\", \"YY-MM-DD\", \"fr_FR\")", 35296},
- {"Date2Num(\"1/3/00\", \"D/M/YY\") - Date2Num(\"1/2/00\", \"D/M/YY\")",
- 29}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("Date2Num(\"1/1/1900\", \"D/M/YYYY\")", 1);
+ ExecuteExpectInt32("Date2Num(\"03/15/96\", \"MM/DD/YY\")", 35138);
+ ExecuteExpectInt32("Date2Num(\"96-08-20\", \"YY-MM-DD\", \"fr_FR\")", 35296);
+ ExecuteExpectInt32(
+ "Date2Num(\"1/3/00\", \"D/M/YY\") - Date2Num(\"1/2/00\", \"D/M/YY\")",
+ 29);
+#if 0
+ // TODO(thestig): Investigate these cases.
+ ExecuteExpectInt32("Date2Num(\"Mar 15, 1996\")", 35138);
+ ExecuteExpectInt32("Date2Num(\"Aug 1, 1996\", \"MMM D, YYYY\")", 35277);
+#endif
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, DateFmt) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {
- // {"DateFmt(1)", "M/D/YY"},
- // {"DateFmt(2, \"fr_CA\")", "YY-MM-DD"},
- {"DateFmt(3, \"de_DE\")", "D. MMMM YYYY"},
- // {"DateFmt(4, \"fr_FR\")", "EEE D' MMMM YYYY"}
- };
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("DateFmt(3, \"de_DE\")", "D. MMMM YYYY");
+#if 0
+ // TODO(thestig): Investigate these cases.
+ ExecuteExpectString("DateFmt(1)", "M/D/YY");
+ ExecuteExpectString("DateFmt(2, \"fr_CA\")", "YY-MM-DD");
+ ExecuteExpectString("DateFmt(4, \"fr_FR\")", "EEE D' MMMM YYYY");
+#endif
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, IsoDate2Num) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"IsoDate2Num(\"1900\")", 1},
- {"IsoDate2Num(\"1900-01\")", 1},
- {"IsoDate2Num(\"1900-01-01\")", 1},
- {"IsoDate2Num(\"19960315T20:20:20\")", 35138},
- {"IsoDate2Num(\"2000-03-01\") - IsoDate2Num(\"20000201\")", 29}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("IsoDate2Num(\"1900\")", 1);
+ ExecuteExpectInt32("IsoDate2Num(\"1900-01\")", 1);
+ ExecuteExpectInt32("IsoDate2Num(\"1900-01-01\")", 1);
+ ExecuteExpectInt32("IsoDate2Num(\"19960315T20:20:20\")", 35138);
+ ExecuteExpectInt32("IsoDate2Num(\"2000-03-01\") - IsoDate2Num(\"20000201\")",
+ 29);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_IsoTime2Num) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"IsoTime2Num(\"00:00:00Z\")", 1}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("IsoTime2Num(\"00:00:00Z\")", 1);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, LocalDateFmt) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {// {"LocalDateFmt(1, \"de_DE\")", "tt.MM.uu"},
- // {"LocalDateFmt(2, \"fr_CA\")", "aa-MM-jj"},
- {"LocalDateFmt(3, \"de_CH\")", "t. MMMM jjjj"},
- {"LocalDateFmt(4, \"fr_FR\")", "EEEE j MMMM aaaa"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("LocalDateFmt(3, \"de_CH\")", "t. MMMM jjjj");
+ ExecuteExpectString("LocalDateFmt(4, \"fr_FR\")", "EEEE j MMMM aaaa");
+#if 0
+ // TODO(thestig): Investigate these cases.
+ ExecuteExpectString("LocalDateFmt(1, \"de_DE\")", "tt.MM.uu");
+ ExecuteExpectString("LocalDateFmt(2, \"fr_CA\")", "aa-MM-jj");
+#endif
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_LocalTimeFmt) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"LocalTimeFmt(1, \"de_DE\")", "HH:mm"},
- {"LocalTimeFmt(2, \"fr_CA\")", "HH:mm::ss"},
- {"LocalTimeFmt(3, \"de_CH\")", "HH:mm:ss z"},
- {"LocalTimeFmt(4, \"fr_FR\")", "HH' h 'mm z"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("LocalTimeFmt(1, \"de_DE\")", "HH:mm");
+ ExecuteExpectString("LocalTimeFmt(2, \"fr_CA\")", "HH:mm::ss");
+ ExecuteExpectString("LocalTimeFmt(3, \"de_CH\")", "HH:mm:ss z");
+ ExecuteExpectString("LocalTimeFmt(4, \"fr_FR\")", "HH' h 'mm z");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Num2Date) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {
- {"Num2Date(1, \"DD/MM/YYYY\")", "01/01/1900"},
- {"Num2Date(35139, \"DD-MMM-YYYY\", \"de_DE\")", "16-Mrz-1996"},
- // {"Num2Date(Date2Num(\"Mar 15, 2000\") - Date2Num(\"98-03-15\", "
- // "\"YY-MM-DD\", \"fr_CA\"))",
- // "Jan 1, 1902"}
- };
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString()) << "Program: " << tests[i].program;
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Num2Date(1, \"DD/MM/YYYY\")", "01/01/1900");
+ ExecuteExpectString("Num2Date(35139, \"DD-MMM-YYYY\", \"de_DE\")",
+ "16-Mrz-1996");
+#if 0
+ // TODO(thestig): Investigate this case.
+ ExecuteExpectString(
+ "Num2Date(Date2Num(\"Mar 15, 2000\") - Date2Num(\"98-03-15\", "
+ "\"YY-MM-DD\", \"fr_CA\"))",
+ "Jan 1, 1902");
+#endif
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Num2GMTime) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {// Broken on Windows only.
- {"Num2GMTime(1, \"HH:MM:SS\")", "00:00:00"},
- // Below broken on other platforms.
- {"Num2GMTime(65593001, \"HH:MM:SS Z\")", "18:13:13 GMT"},
- {"Num2GMTime(43993001, TimeFmt(4, \"de_DE\"), \"de_DE\")",
- "12.13 Uhr GMT"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ // Broken on Windows only.
+ ExecuteExpectString("Num2GMTime(1, \"HH:MM:SS\")", "00:00:00");
+ // Below broken on other platforms.
+ ExecuteExpectString("Num2GMTime(65593001, \"HH:MM:SS Z\")", "18:13:13 GMT");
+ ExecuteExpectString("Num2GMTime(43993001, TimeFmt(4, \"de_DE\"), \"de_DE\")",
+ "12.13 Uhr GMT");
}
// TODO(dsinclair): Broken on Mac ...
TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Num2Time) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Num2Time(1, \"HH:MM:SS\")", "00:00:00"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Num2Time(1, \"HH:MM:SS\")", "00:00:00");
}
// TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Time) {
@@ -561,7 +399,7 @@
// EXPECT_TRUE(Execute("Time()"));
-// CFXJSE_Value* value = GetValue();
+// v8::Local<v8::Value> value = GetValue();
// EXPECT_TRUE(value->IsInteger());
// EXPECT_EQ(tp.tv_sec * 1000L + tp.tv_usec / 1000, value->ToInteger())
// << "Program: Time()";
@@ -570,653 +408,352 @@
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Time2Num) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {
- // {"Time2Num(\"00:00:00 GMT\", \"HH:MM:SS Z\")", 1},
- {"Time2Num(\"13:13:13 GMT\", \"HH:MM:SS Z\", \"fr_FR\")", 47593001}};
+ ExecuteExpectInt32("Time2Num(\"00:00:00 GMT\", \"HH:MM:SS Z\")", 1);
+ ExecuteExpectInt32("Time2Num(\"00:00:01 GMT\", \"HH:MM:SS Z\")", 1001);
+ ExecuteExpectInt32("Time2Num(\"00:01:00 GMT\", \"HH:MM:SS Z\")", 60001);
+ ExecuteExpectInt32("Time2Num(\"01:00:00 GMT\", \"HH:MM:SS Z\")", 3600001);
+ ExecuteExpectInt32("Time2Num(\"23:59:59 GMT\", \"HH:MM:SS Z\")", 86399001);
+ // https://crbug.com/pdfium/1257
+ ExecuteExpectInt32("Time2Num(\"\", \"\", 1)", 0);
+ ExecuteExpectInt32("Time2Num(\"13:13:13 GMT\", \"HH:MM:SS Z\", \"fr_FR\")",
+ 47593001);
+}
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
+TEST_F(CFXJSE_FormCalcContextEmbedderTest, Time2NumWithTZ) {
+ ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
+ static constexpr const char* kTimeZones[] = {
+ "UTC+14", "UTC-14", "UTC+9:30", "UTC-0:30",
+ "UTC+0:30", "UTC-0:01", "UTC+0:01"};
+ for (const char* tz : kTimeZones) {
+ ScopedSetTZ scoped_set_tz(tz);
+ ExecuteExpectInt32("Time2Num(\"00:00:00 GMT\", \"HH:MM:SS Z\")", 1);
+ ExecuteExpectInt32("Time2Num(\"11:59:59 GMT\", \"HH:MM:SS Z\")", 43199001);
+ ExecuteExpectInt32("Time2Num(\"12:00:00 GMT\", \"HH:MM:SS Z\")", 43200001);
+ ExecuteExpectInt32("Time2Num(\"23:59:59 GMT\", \"HH:MM:SS Z\")", 86399001);
+ }
+ {
+ ScopedSetTZ scoped_set_tz("UTC-3:00");
+ ExecuteExpectInt32("Time2Num(\"1:13:13 PM\")", 36793001);
+ ExecuteExpectInt32(
+ "Time2Num(\"13:13:13 GMT\", \"HH:MM:SS Z\") - "
+ "Time2Num(\"13:13:13\", \"HH:MM:SS\")",
+ 10800000);
}
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, TimeFmt) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {
- // {"TimeFmt(1)", "h::MM A"},
- {"TimeFmt(2, \"fr_CA\")", "HH:MM:SS"},
- {"TimeFmt(3, \"fr_FR\")", "HH:MM:SS Z"},
- // {"TimeFmt(4, \"de_DE\")", "H.MM' Uhr 'Z"}
- };
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("TimeFmt(2, \"fr_CA\")", "HH:MM:SS");
+ ExecuteExpectString("TimeFmt(3, \"fr_FR\")", "HH:MM:SS Z");
+#if 0
+ // TODO(thestig): Investigate these cases.
+ ExecuteExpectString("TimeFmt(1)", "h::MM A");
+ ExecuteExpectString("TimeFmt(4, \"de_DE\")", "H.MM' Uhr 'Z");
+#endif
}
-TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Apr) {
+TEST_F(CFXJSE_FormCalcContextEmbedderTest, Apr) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {{"Apr(35000, 269.50, 360)", 0.08515404566f},
- {"Apr(210000 * 0.75, 850 + 110, 25 * 26)", 0.07161332404f}};
+ ExecuteExpectFloatNear("Apr(35000, 269.50, 360)", 0.08515404566f);
+ ExecuteExpectFloatNear("Apr(210000 * 0.75, 850 + 110, 25 * 26)",
+ 0.07161332404f);
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectError("Apr(2, 2, 2147483648)");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, CTerm) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {
- // {"CTerm(0.02, 1000, 100)", 116.2767474515f},
- {"CTerm(0.10, 500000, 12000)", 39.13224648502f},
- // {"CTerm(0.0275 + 0.0025, 1000000, 55000 * 0.10)", 176.02226044975f}
- };
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectFloat("CTerm(0.10, 500000, 12000)", 39.13224648502f);
+#if 0
+ // TODO(thestig): Investigate these cases.
+ ExecuteExpectFloat("CTerm(0.02, 1000, 100)", 116.2767474515f);
+ ExecuteExpectFloat("CTerm(0.0275 + 0.0025, 1000000, 55000 * 0.10)",
+ 176.02226044975f);
+#endif
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, FV) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {{"FV(400, 0.10 / 12, 30 * 12)", 904195.16991842445f},
- {"FV(1000, 0.075 / 4, 10 * 4)", 58791.96145535981f}};
+ ExecuteExpectFloat("FV(400, 0.10 / 12, 30 * 12)", 904195.16991842445f);
+ ExecuteExpectFloat("FV(1000, 0.075 / 4, 10 * 4)", 58791.96145535981f);
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectError("FV(2, 2, 2147483648)");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, IPmt) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {{"IPmt(30000, 0.085, 295.50, 7, 3)", 624.8839283142f},
- {"IPmt(160000, 0.0475, 980, 24, 12)", 7103.80833569485f},
- {"IPmt(15000, 0.065, 65.50, 15, 1)", 0.0f}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectFloat("IPmt(30000, 0.085, 295.50, 7, 3)", 624.8839283142f);
+ ExecuteExpectFloat("IPmt(160000, 0.0475, 980, 24, 12)", 7103.80833569485f);
+ ExecuteExpectFloat("IPmt(15000, 0.065, 65.50, 15, 1)", 0.0f);
}
-TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_NPV) {
+TEST_F(CFXJSE_FormCalcContextEmbedderTest, NPV) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {{"NPV(0.065, 5000)", 4694.83568075117f},
- {"NPV(0.10, 500, 1500, 4000, 10000)", 11529.60863329007f},
- {"NPV(0.0275 / 12, 50, 60, 40, 100, 25)", 273.14193838457f}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber()) << "Program: " << tests[i].program;
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectFloat("NPV(0.065, 5000)", 4694.83568075117f);
+ ExecuteExpectFloat("NPV(0.10, 500, 1500, 4000, 10000)", 11529.60863329007f);
+ ExecuteExpectFloat("NPV(0.0275 / 12, 50, 60, 40, 100, 25)", 273.14193838457f);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Pmt) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {// {"Pmt(150000, 0.0475 / 12, 25 * 12)", 855.17604207164f},
- {"Pmt(25000, 0.085, 12)", 3403.82145169876f}};
+ ExecuteExpectFloat("Pmt(25000, 0.085, 12)", 3403.82145169876f);
+ ExecuteExpectFloat("Pmt(5000, 0.01, 1)", 5050);
+ ExecuteExpectFloat("Pmt(5000, 0.01, 1.5)", 5050);
+ ExecuteExpectFloat("Pmt(30000.00, .085 / 12, 12 * 12)", 333.01666929435f);
+ ExecuteExpectFloat("Pmt(10000, .08 / 12, 10)", 1037.03208935916f);
+ ExecuteExpectFloat("Pmt(150000, 0.0475 / 12, 25 * 12)", 855.17604207164f);
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ // https://crbug.com/1293179
+ ExecuteExpectError("Pmt(2, 2, 99999997952)");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, PPmt) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {
- {"PPmt(30000, 0.085, 295.50, 7, 3)", 261.6160716858f},
- {"PPmt(160000, 0.0475, 980, 24, 12)", 4656.19166430515f},
- // {"PPmt(15000, 0.065, 65.50, 15, 1)", 0.0f}
- };
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectFloat("PPmt(30000, 0.085, 295.50, 7, 3)", 261.6160716858f);
+ ExecuteExpectFloat("PPmt(160000, 0.0475, 980, 24, 12)", 4656.19166430515f);
+#if 0
+ // TODO(thestig): Investigate this case.
+ ExecuteExpectFloat("PPmt(15000, 0.065, 65.50, 15, 1)", 0.0f);
+#endif
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, PV) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {
- {"PV(400, 0.10 / 12, 30 * 12)", 45580.32799074439f},
- // {"PV(1000, 0.075 / 4, 10 * 4)", 58791.96145535981f}
- };
+ ExecuteExpectFloat("PV(400, 0.10 / 12, 30 * 12)", 45580.32799074439f);
+ ExecuteExpectFloat("PV(1000, 0.075 / 4, 10 * 4)", 27964.88770467326f);
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ // https://crbug.com/1296840
+ ExecuteExpectError("PV(2, 2, 2147483648)");
}
-TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Rate) {
+TEST_F(CFXJSE_FormCalcContextEmbedderTest, Rate) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {{"Rate(12000, 8000, 5)", 0.0844717712f},
- {"Rate(10000, 0.25 * 5000, 4 * 12)", 0.04427378243f}};
+ ExecuteExpectFloatNear("Rate(12000, 8000, 5)", 0.0844717712f);
+ ExecuteExpectFloatNear("Rate(10000, 0.25 * 5000, 4 * 12)", 0.04427378243f);
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectError("Rate(2, 2, 2147483648)");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Term) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {// {"Term(475, .05, 1500)", 3.00477517728f},
- {"Term(2500, 0.0275 + 0.0025, 5000)", 1.97128786369f}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectFloat("Term(2500, 0.0275 + 0.0025, 5000)", 1.97128786369f);
+#if 0
+ // TODO(thestig): Investigate this case.
+ ExecuteExpectFloat("Term(475, .05, 1500)", 3.00477517728f);
+#endif
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Choose) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {
- {"Choose(3, \"Taxes\", \"Price\", \"Person\", \"Teller\")", "Person"},
- {"Choose(2, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)", "9"},
- {"Choose(20/3, \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\")",
- "F"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Choose(3, \"Taxes\", \"Price\", \"Person\", \"Teller\")",
+ "Person");
+ ExecuteExpectString("Choose(2, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)", "9");
+ ExecuteExpectString(
+ "Choose(20/3, \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\")",
+ "F");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Exists) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
-
- EXPECT_TRUE(Execute("Exists(\"hello world\")"));
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_FALSE(value->ToBoolean());
+ ExecuteExpectBool("Exists(\"hello world\")", false);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, HasValue) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- bool result;
- } tests[] = {{"HasValue(2)", true}, {"HasValue(\" \")", false}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger()) << "Program: " << tests[i].program;
- EXPECT_EQ(tests[i].result, value->ToBoolean())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectBool("HasValue(2)", true);
+ ExecuteExpectBool("HasValue(\" \")", false);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Oneof) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- bool result;
- } tests[] = {
- {"Oneof(3, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)", true},
- {"Oneof(\"John\", \"Bill\", \"Gary\", \"Joan\", \"John\", \"Lisa\")",
- true},
- {"Oneof(3, 1, 25)", false},
- {"Oneof(3, 3, null)", true},
- {"Oneof(3, null, null)", false},
- };
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger()) << "Program: " << tests[i].program;
- EXPECT_EQ(tests[i].result, value->ToBoolean())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectBool("Oneof(3, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)", true);
+ ExecuteExpectBool(
+ "Oneof(\"John\", \"Bill\", \"Gary\", \"Joan\", \"John\", \"Lisa\")",
+ true);
+ ExecuteExpectBool("Oneof(3, 1, 25)", false);
+ ExecuteExpectBool("Oneof(3, 3, null)", true);
+ ExecuteExpectBool("Oneof(3, null, null)", false);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Within) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- bool result;
- } tests[] = {{"Within(\"C\", \"A\", \"D\")", true},
- {"Within(1.5, 0, 2)", true},
- {"Within(-1, 0, 2)", false}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger()) << "Program: " << tests[i].program;
- EXPECT_EQ(tests[i].result, value->ToBoolean())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectBool("Within(\"C\", \"A\", \"D\")", true);
+ ExecuteExpectBool("Within(1.5, 0, 2)", true);
+ ExecuteExpectBool("Within(-1, 0, 2)", false);
}
-TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Eval) {
+TEST_F(CFXJSE_FormCalcContextEmbedderTest, Eval) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"eval(\"10*3+5*4\")", 50}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("eval(\"10*3+5*4\")", 50);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Null) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Null()", "null"},
- {"Concat(\"ABC\", Null(), \"DEF\")", "ABCDEF"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
-
- EXPECT_TRUE(Execute("Null() + 5"));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(5, value->ToInteger());
+ ExecuteExpectString("Null()", "null");
+ ExecuteExpectString("Concat(\"ABC\", Null(), \"DEF\")", "ABCDEF");
+ ExecuteExpectInt32("Null() + 5", 5);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Ref) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Ref(\"10*3+5*4\")", "10*3+5*4"}, {"Ref(\"hello\")", "hello"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Ref(\"10*3+5*4\")", "10*3+5*4");
+ ExecuteExpectString("Ref(\"hello\")", "hello");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, UnitType) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"UnitType(\"36 in\")", "in"},
- {"UnitType(\"2.54centimeters\")", "cm"},
- {"UnitType(\"picas\")", "pt"},
- {"UnitType(\"2.cm\")", "cm"},
- {"UnitType(\"2.zero cm\")", "in"},
- {"UnitType(\"kilometers\")", "in"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("UnitType(\"36 in\")", "in");
+ ExecuteExpectString("UnitType(\"2.54centimeters\")", "cm");
+ ExecuteExpectString("UnitType(\"picas\")", "pt");
+ ExecuteExpectString("UnitType(\"2.cm\")", "cm");
+ ExecuteExpectString("UnitType(\"2.zero cm\")", "in");
+ ExecuteExpectString("UnitType(\"kilometers\")", "in");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, UnitValue) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- float result;
- } tests[] = {
- {"UnitValue(\"2in\")", 2.0f}, {"UnitValue(\"2in\", \"cm\")", 5.08f},
- // {"UnitValue(\"6\", \"pt\")", 432f},
- // {"UnitType(\"A\", \"cm\")", 0.0f},
- // {"UnitType(\"5.08cm\", \"kilograms\")", 2.0f}
- };
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(tests[i].result, value->ToFloat())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectFloat("UnitValue(\"2in\")", 2.0f);
+ ExecuteExpectFloat("UnitValue(\"2in\", \"cm\")", 5.08f);
+#if 0
+ // TODO(thestig): Investigate these cases.
+ // Should the UnitType cases move into the UnitType test case?
+ ExecuteExpectFloat("UnitValue(\"6\", \"pt\")", 432f);
+ ExecuteExpectFloat("UnitType(\"A\", \"cm\")", 0.0f);
+ ExecuteExpectFloat("UnitType(\"5.08cm\", \"kilograms\")", 2.0f);
+#endif
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, At) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {{"At(\"ABCDEFGH\", \"AB\")", 1},
- {"At(\"ABCDEFGH\", \"F\")", 6},
- {"At(23412931298471, 29)", 5}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("At(\"ABCDEFGH\", \"AB\")", 1);
+ ExecuteExpectInt32("At(\"ABCDEFGH\", \"F\")", 6);
+ ExecuteExpectInt32("At(23412931298471, 29)", 5);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Concat) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Concat(\"ABC\", \"DEF\")", "ABCDEF"},
- {"Concat(\"Tony\", Space(1), \"Blue\")", "Tony Blue"},
- {"Concat(\"You owe \", WordNum(1154.67, 2), \".\")",
- "You owe One Thousand One Hundred Fifty-four Dollars And "
- "Sixty-seven Cents."}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Concat(\"ABC\", \"DEF\")", "ABCDEF");
+ ExecuteExpectString("Concat(\"Tony\", Space(1), \"Blue\")", "Tony Blue");
+ ExecuteExpectString("Concat(\"You owe \", WordNum(1154.67, 2), \".\")",
+ "You owe One Thousand One Hundred Fifty-four Dollars And "
+ "Sixty-seven Cents.");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Decode) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {
- // HTML
- {R"(Decode("", "html"))", ""},
- {R"(Decode("abcÂxyz", "html"))", "abc\xC3\x82xyz"},
- {R"(Decode("abc&NoneSuchButVeryLongIndeed;", "html"))", "abc"},
- {R"(Decode("AÆÁ", "html"))", "A\xC3\x86\xC3\x81"},
- {R"(Decode("xyz&#", "html"))", "xyz"},
- {R"(Decode("|&zzzzzz;|", "html"))", "||"},
+ // HTML
+ ExecuteExpectString(R"(Decode("", "html"))", "");
+ ExecuteExpectString(R"(Decode("abcÂxyz", "html"))", "abc\xC3\x82xyz");
+ ExecuteExpectString(R"(Decode("abc&NoneSuchButVeryLongIndeed;", "html"))",
+ "abc");
+ ExecuteExpectString(R"(Decode("AÆÁ", "html"))",
+ "A\xC3\x86\xC3\x81");
+ ExecuteExpectString(R"(Decode("xyz&#", "html"))", "xyz");
+ ExecuteExpectString(R"(Decode("|&zzzzzz;|", "html"))", "||");
- // XML
- {R"(Decode("", "xml"))", ""},
- {R"(Decode("~!@#$%%^&*()_+|`", "xml"))", "~!@#$%%^&*()_+|`"},
- {R"(Decode("abc&nonesuchbutverylongindeed;", "xml"))", "abc"},
- {R"(Decode(""E<>[].'", "xml"))", "\"E<>[].'"},
- {R"(Decode("xyz&#", "xml"))", "xyz"},
- {R"(Decode("|&zzzzzz;|", "xml"))", "||"},
+ // XML
+ ExecuteExpectString(R"(Decode("", "xml"))", "");
+ ExecuteExpectString(R"(Decode("~!@#$%%^&*()_+|`", "xml"))",
+ "~!@#$%%^&*()_+|`");
+ ExecuteExpectString(R"(Decode("abc&nonesuchbutverylongindeed;", "xml"))",
+ "abc");
+ ExecuteExpectString(R"(Decode(""E<>[].'", "xml"))",
+ "\"E<>[].'");
+ ExecuteExpectString(R"(Decode("xyz&#", "xml"))", "xyz");
+ ExecuteExpectString(R"(Decode("|&zzzzzz;|", "xml"))", "||");
- // URL
- {R"(Decode("", "url"))", ""},
- {R"(Decode("~%26^&*()_+|`{", "url"))", "~&^&*()_+|`{"},
- {R"(Decode("~%26^&*()_+|`{", "mbogo"))", "~&^&*()_+|`{"},
- {R"(Decode("~%26^&*()_+|`{"))", "~&^&*()_+|`{"},
- {R"(Decode("~%~~"))", ""},
- {R"(Decode("?%~"))", ""},
- {R"(Decode("?%"))", "?"},
- };
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ // URL
+ ExecuteExpectString(R"(Decode("", "url"))", "");
+ ExecuteExpectString(R"(Decode("~%26^&*()_+|`{", "url"))", "~&^&*()_+|`{");
+ ExecuteExpectString(R"(Decode("~%26^&*()_+|`{", "mbogo"))", "~&^&*()_+|`{");
+ ExecuteExpectString(R"(Decode("~%26^&*()_+|`{"))", "~&^&*()_+|`{");
+ ExecuteExpectString(R"(Decode("~%~~"))", "");
+ ExecuteExpectString(R"(Decode("?%~"))", "");
+ ExecuteExpectString(R"(Decode("?%"))", "?");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Encode) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {
- {"Encode(\"X/~&^*<=>?|\")", "X%2f%7e%26%5e*%3c%3d%3e%3f%7c"},
- {"Encode(\"X/~&^*<=>?|\", \"mbogo\")", "X%2f%7e%26%5e*%3c%3d%3e%3f%7c"},
- {"Encode(\"X/~&^*<=>?|\", \"url\")", "X%2f%7e%26%5e*%3c%3d%3e%3f%7c"},
- {"Encode(\"X/~&^*<=>?|\", \"xml\")", "X/~&^*<=>?|"},
- {"Encode(\"X/~&^*<=>?|\", \"html\")", "X/~&^*<=>?|"},
+ ExecuteExpectString("Encode(\"X/~&^*<=>?|\")",
+ "X%2f%7e%26%5e*%3c%3d%3e%3f%7c");
+ ExecuteExpectString("Encode(\"X/~&^*<=>?|\", \"mbogo\")",
+ "X%2f%7e%26%5e*%3c%3d%3e%3f%7c");
+ ExecuteExpectString("Encode(\"X/~&^*<=>?|\", \"url\")",
+ "X%2f%7e%26%5e*%3c%3d%3e%3f%7c");
+ ExecuteExpectString("Encode(\"X/~&^*<=>?|\", \"xml\")",
+ "X/~&^*<=>?|");
+ ExecuteExpectString("Encode(\"X/~&^*<=>?|\", \"html\")",
+ "X/~&^*<=>?|");
- {"Encode(\"\\u0022\\u00f5\\ufed0\", \"url\")", "%22%f5%fe%d0"},
- {"Encode(\"\\u0022\\u00f4\\ufed0\", \"xml\")", ""ôﻐ"},
- {"Encode(\"\\u0022\\u00f5\\ufed0\", \"html\")", ""õﻐ"},
+ ExecuteExpectString("Encode(\"\\u0022\\u00f5\\ufed0\", \"url\")",
+ "%22%f5%fe%d0");
+ ExecuteExpectString("Encode(\"\\u0022\\u00f4\\ufed0\", \"xml\")",
+ ""ôﻐ");
+ ExecuteExpectString("Encode(\"\\u0022\\u00f5\\ufed0\", \"html\")",
+ ""õﻐ");
-#if !defined(OS_WIN)
- // Windows wchar_t isn't wide enough to handle these anyways.
- // TODO(tsepez): fix surrogate encodings.
- {"Encode(\"\\uD83D\\uDCA9\", \"url\")", "%01%f4%a9"},
- {"Encode(\"\\uD83D\\uDCA9\", \"xml\")", ""},
- {"Encode(\"\\uD83D\\uDCA9\", \"html\")", ""},
-#endif // !defined(OS_WIN)
- };
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+#if !BUILDFLAG(IS_WIN)
+ // Windows wchar_t isn't wide enough to handle these anyways.
+ // TODO(tsepez): fix surrogate encodings.
+ ExecuteExpectString("Encode(\"\\uD83D\\uDCA9\", \"url\")", "%01%f4%a9");
+ ExecuteExpectString("Encode(\"\\uD83D\\uDCA9\", \"xml\")", "");
+ ExecuteExpectString("Encode(\"\\uD83D\\uDCA9\", \"html\")", "");
+#endif // !BUILDFLAG(IS_WIN)
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Format) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Format(\"MMM D, YYYY\", \"20020901\")", "Sep 1, 2002"},
- {"Format(\"$9,999,999.99\", 1234567.89)", "$1,234,567.89"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Format(\"MMM D, YYYY\", \"20020901\")", "Sep 1, 2002");
+ ExecuteExpectString("Format(\"$9,999,999.99\", 1234567.89)", "$1,234,567.89");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Left) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Left(\"ABCDEFGH\", 3)", "ABC"},
- {"Left(\"Tony Blue\", 5)", "Tony "}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Left(\"ABCDEFGH\", 3)", "ABC");
+ ExecuteExpectString("Left(\"Tony Blue\", 5)", "Tony ");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Len) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- int result;
- } tests[] = {
- {"Len(\"ABCDEFGH\")", 8}, {"Len(4)", 1}, {"Len(Str(4.532, 6, 4))", 6}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger());
- EXPECT_EQ(tests[i].result, value->ToInteger())
- << "Program: " << tests[i].program;
- }
+ ExecuteExpectInt32("Len(\"ABCDEFGH\")", 8);
+ ExecuteExpectInt32("Len(4)", 1);
+ ExecuteExpectInt32("Len(Str(4.532, 6, 4))", 6);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Lower) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Lower(\"ABC\")", "abc"},
- {"Lower(\"21 Main St.\")", "21 main st."},
- {"Lower(15)", "15"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Lower(\"ABC\")", "abc");
+ ExecuteExpectString("Lower(\"21 Main St.\")", "21 main st.");
+ ExecuteExpectString("Lower(15)", "15");
}
// This is testing for an OOB read, so will likely only fail under ASAN.
@@ -1232,311 +769,262 @@
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Ltrim) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Ltrim(\" ABCD\")", "ABCD"},
- {"Ltrim(Rtrim(\" Tony Blue \"))", "Tony Blue"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Ltrim(\" ABCD\")", "ABCD");
+ ExecuteExpectString("Ltrim(Rtrim(\" Tony Blue \"))", "Tony Blue");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, DISABLED_Parse) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Parse(\"MMM D, YYYY\", \"Sep 1, 2002\")", "2002-09-01"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
-
- EXPECT_TRUE(Execute("Parse(\"$9,999,999.99\", \"$1,234,567.89\")"));
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber());
- EXPECT_FLOAT_EQ(1234567.89f, value->ToFloat());
+ ExecuteExpectString("Parse(\"MMM D, YYYY\", \"Sep 1, 2002\")", "2002-09-01");
+ ExecuteExpectFloat("Parse(\"$9,999,999.99\", \"$1,234,567.89\")",
+ 1234567.89f);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Replace) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Replace(\"Tony Blue\", \"Tony\", \"Chris\")", "Chris Blue"},
- {"Replace(\"ABCDEFGH\", \"D\")", "ABCEFGH"},
- {"Replace(\"ABCDEFGH\", \"d\")", "ABCDEFGH"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Replace(\"Tony Blue\", \"Tony\", \"Chris\")",
+ "Chris Blue");
+ ExecuteExpectString("Replace(\"ABCDEFGH\", \"D\")", "ABCEFGH");
+ ExecuteExpectString("Replace(\"ABCDEFGH\", \"d\")", "ABCDEFGH");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Right) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Right(\"ABCDEFGH\", 3)", "FGH"},
- {"Right(\"Tony Blue\", 5)", " Blue"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Right(\"ABCDEFGH\", 3)", "FGH");
+ ExecuteExpectString("Right(\"Tony Blue\", 5)", " Blue");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Rtrim) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Rtrim(\"ABCD \")", "ABCD"},
- {"Rtrim(\"Tony Blue \t\")", "Tony Blue"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Rtrim(\"ABCD \")", "ABCD");
+ ExecuteExpectString("Rtrim(\"Tony Blue \t\")", "Tony Blue");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Space) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Space(5)", " "},
- {"Concat(\"Tony\", Space(1), \"Blue\")", "Tony Blue"}};
+ ExecuteExpectString("Space(5)", " ");
+ ExecuteExpectString("Concat(\"Tony\", Space(1), \"Blue\")", "Tony Blue");
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ // Error cases.
+ ExecuteExpectError("Space(15654909)");
+ ExecuteExpectError("Space(99999999)");
+ ExecuteExpectError("Space()");
+ ExecuteExpectError("Space(1, 2)");
+ ExecuteExpectNull("Space( $)");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Str) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Str(2.456)", " 2"},
- {"Str(4.532, 6, 4)", "4.5320"},
- {"Str(234.458, 4)", " 234"},
- {"Str(31.2345, 4, 2)", "****"}};
+ ExecuteExpectString("Str(2.456)", " 2");
+ ExecuteExpectString("Str(4.532, 6, 4)", "4.5320");
+ ExecuteExpectString("Str(234.458, 4)", " 234");
+ ExecuteExpectString("Str(31.2345, 4, 2)", "****");
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
+ // Test maximum "n3" precision value.
+ ExecuteExpectString("Str(-765, 19, 14)", "-765.00000000000000");
+ ExecuteExpectString("Str(-765, 20, 15)", "-765.000000000000000");
+ ExecuteExpectString("Str(-765, 21, 16)", " -765.000000000000000");
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ // Error cases.
+ ExecuteExpectError("Str()");
+ ExecuteExpectError("Str(1, 2, 3, 4)");
+ ExecuteExpectError("Str(42, 15654909)");
+ ExecuteExpectNull("Str( $)");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Stuff) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Stuff(\"TonyBlue\", 5, 0, \" \")", "Tony Blue"},
- {"Stuff(\"ABCDEFGH\", 4, 2)", "ABCFGH"},
- {"Stuff(\"members-list@myweb.com\", 0, 0, \"cc:\")",
- "cc:members-list@myweb.com"}};
+ // Test wrong number of parameters.
+ ExecuteExpectError("Stuff(1, 2)");
+ ExecuteExpectError("Stuff(1, 2, 3, 4, 5)");
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
+ // Test null arguments.
+ ExecuteExpectNull("Stuff(null, 0, 4)");
+ ExecuteExpectNull("Stuff(\"ABCDEFG\", null, 4)");
+ ExecuteExpectNull("Stuff(\"ABCDEFG\", 0, null)");
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ // Insertions.
+ ExecuteExpectString("Stuff(\"\", 0, 0, \"clams\")", "clams");
+ ExecuteExpectString("Stuff(\"TonyBlue\", 5, 0, \" \")", "Tony Blue");
+
+ // Deletions.
+ ExecuteExpectString("Stuff(\"A\", 1, 0)", "A");
+ ExecuteExpectString("Stuff(\"A\", 1, 1)", "");
+ ExecuteExpectString("Stuff(\"ABCDEFGH\", 4, 2)", "ABCFGH");
+ ExecuteExpectString("Stuff(\"ABCDEFGH\", 7, 2)", "ABCDEF");
+
+ // Test index clamping.
+ ExecuteExpectString("Stuff(\"ABCDEFGH\", -400, 400)", "");
+
+ // Need significant amount of text to test start + count overflow due to
+ // intermediate float representation of count not being able to hold
+ // INT_MAX.
+ ExecuteExpectString(
+ "Stuff(\""
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678900"
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678900"
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678900"
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678900"
+ "\", 133, 2147483520)",
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678900"
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678900"
+ "abcd");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Substr) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
// Test wrong number of parameters.
- EXPECT_FALSE(Execute("Substr()"));
- EXPECT_FALSE(Execute("Substr(1)"));
- EXPECT_FALSE(Execute("Substr(1, 2)"));
- EXPECT_FALSE(Execute("Substr(1, 2, 3, 4)"));
+ ExecuteExpectError("Substr()");
+ ExecuteExpectError("Substr(1)");
+ ExecuteExpectError("Substr(1, 2)");
+ ExecuteExpectError("Substr(1, 2, 3, 4)");
// Test null input.
- EXPECT_TRUE(ExecuteExpectNull("Substr(null, 0, 4)"));
- EXPECT_TRUE(ExecuteExpectNull("Substr(\"ABCDEFG\", null, 4)"));
- EXPECT_TRUE(ExecuteExpectNull("Substr(\"ABCDEFG\", 0, null)"));
- EXPECT_TRUE(ExecuteExpectNull("Substr(null, null, 4)"));
- EXPECT_TRUE(ExecuteExpectNull("Substr(null, 0, null)"));
- EXPECT_TRUE(ExecuteExpectNull("Substr(\"ABCDEFG\", null, null)"));
- EXPECT_TRUE(ExecuteExpectNull("Substr(null, null, null)"));
+ ExecuteExpectNull("Substr(null, 0, 4)");
+ ExecuteExpectNull("Substr(\"ABCDEFG\", null, 4)");
+ ExecuteExpectNull("Substr(\"ABCDEFG\", 0, null)");
+ ExecuteExpectNull("Substr(null, null, 4)");
+ ExecuteExpectNull("Substr(null, 0, null)");
+ ExecuteExpectNull("Substr(\"ABCDEFG\", null, null)");
+ ExecuteExpectNull("Substr(null, null, null)");
- struct {
- const char* program;
- const char* result;
- } static const kTests[] = {{"Substr(\"ABCDEFG\", -1, 4)", "ABCD"},
- {"Substr(\"ABCDEFG\", 0, 4)", "ABCD"},
- {"Substr(\"ABCDEFG\", 3, 4)", "CDEF"},
- {"Substr(\"ABCDEFG\", 4, 4)", "DEFG"},
- {"Substr(\"ABCDEFG\", 5, 4)", "EFG"},
- {"Substr(\"ABCDEFG\", 6, 4)", "FG"},
- {"Substr(\"ABCDEFG\", 7, 4)", "G"},
- {"Substr(\"ABCDEFG\", 8, 4)", ""},
- {"Substr(\"ABCDEFG\", 5, -1)", ""},
- {"Substr(\"ABCDEFG\", 5, 0)", ""},
- {"Substr(\"ABCDEFG\", 5, 1)", "E"},
- {"Substr(\"abcdefghi\", 5, 3)", "efg"},
- {"Substr(3214, 2, 1)", "2"},
- {"Substr(\"21 Waterloo St.\", 4, 5)", "Water"}};
-
- for (const auto& test : kTests) {
- EXPECT_TRUE(Execute(test.program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(test.result, value->ToString().c_str())
- << "Program: " << test.program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Substr(\"ABCDEFG\", -1, 4)", "ABCD");
+ ExecuteExpectString("Substr(\"ABCDEFG\", 0, 4)", "ABCD");
+ ExecuteExpectString("Substr(\"ABCDEFG\", 3, 4)", "CDEF");
+ ExecuteExpectString("Substr(\"ABCDEFG\", 4, 4)", "DEFG");
+ ExecuteExpectString("Substr(\"ABCDEFG\", 5, 4)", "EFG");
+ ExecuteExpectString("Substr(\"ABCDEFG\", 6, 4)", "FG");
+ ExecuteExpectString("Substr(\"ABCDEFG\", 7, 4)", "G");
+ ExecuteExpectString("Substr(\"ABCDEFG\", 8, 4)", "");
+ ExecuteExpectString("Substr(\"ABCDEFG\", 5, -1)", "");
+ ExecuteExpectString("Substr(\"ABCDEFG\", 5, 0)", "");
+ ExecuteExpectString("Substr(\"ABCDEFG\", 5, 1)", "E");
+ ExecuteExpectString("Substr(\"abcdefghi\", 5, 3)", "efg");
+ ExecuteExpectString("Substr(3214, 2, 1)", "2");
+ ExecuteExpectString("Substr(\"21 Waterloo St.\", 4, 5)", "Water");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Uuid) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
-
EXPECT_TRUE(Execute("Uuid()"));
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetJseContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsString(value));
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Upper) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {{"Upper(\"abc\")", "ABC"},
- {"Upper(\"21 Main St.\")", "21 MAIN ST."},
- {"Upper(15)", "15"}};
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ ExecuteExpectString("Upper(\"abc\")", "ABC");
+ ExecuteExpectString("Upper(\"21 Main St.\")", "21 MAIN ST.");
+ ExecuteExpectString("Upper(15)", "15");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, WordNum) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- struct {
- const char* program;
- const char* result;
- } tests[] = {
- // {"WordNum(123.45)",
- // "One Hundred and Twenty-three"}, // This looks like it's wrong in the
- // // Formcalc document.
- // {"WordNum(123.45, 1)", "One Hundred and Twenty-three Dollars"},
- {"WordNum(1154.67, 2)",
- "One Thousand One Hundred Fifty-four Dollars And Sixty-seven Cents"},
- {"WordNum(43, 2)", "Forty-three Dollars And Zero Cents"}};
+ // Wrong number of parameters.
+ ExecuteExpectError("WordNum()");
+ ExecuteExpectError("WordNum(1, 2, 3, 4)");
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_TRUE(Execute(tests[i].program));
+ // Normal format codes.
+ ExecuteExpectString("WordNum(123.45)", "One Hundred Twenty-three");
+ ExecuteExpectString("WordNum(123.45, 0)", "One Hundred Twenty-three");
+ ExecuteExpectString("WordNum(123.45, 1)", "One Hundred Twenty-three Dollars");
+ ExecuteExpectString("WordNum(123.45, 2)",
+ "One Hundred Twenty-three Dollars And Forty-five Cents");
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ(tests[i].result, value->ToString().c_str())
- << "Program: " << tests[i].program << " Result: '" << value->ToString()
- << "'";
- }
+ // Invalid format code.
+ ExecuteExpectString("WordNum(123.45, -1)", "");
+ ExecuteExpectString("WordNum(123.45, 3)", "");
+
+ // Locale string is ignored.
+ ExecuteExpectString("WordNum(123.45, 0, \"zh_CN\")",
+ "One Hundred Twenty-three");
+
+ // Zero (and near zero) values.
+ ExecuteExpectString("WordNum(0, 0)", "Zero");
+ ExecuteExpectString("WordNum(0, 1)", "Zero Dollars");
+ ExecuteExpectString("WordNum(0, 2)", "Zero Dollars And Zero Cents");
+ ExecuteExpectString("WordNum(0.12, 0)", "Zero");
+ ExecuteExpectString("WordNum(0.12, 1)", "Zero Dollars");
+ ExecuteExpectString("WordNum(0.12, 2)", "Zero Dollars And Twelve Cents");
+
+ // Negative values.
+ ExecuteExpectString("WordNum(-1, 0)", "*");
+ ExecuteExpectString("WordNum(-1, 1)", "*");
+ ExecuteExpectString("WordNum(-1, 2)", "*");
+
+ // Test larger values
+ // TODO(tsepez): check on "Thousand Zero"
+ ExecuteExpectString("WordNum(1.234e+6)",
+ "One Million Two Hundred Thirty-four Thousand Zero");
+
+ // TODO(tsepez): check on "Zero Thousand Zero"
+ ExecuteExpectString(
+ "WordNum(1.234e+9)",
+ "One Billion Two Hundred Thirty-four Million Zero Thousand Zero");
+
+ // TODO(tsepez): check on "Zero Million"
+ ExecuteExpectString(
+ "WordNum(1.234e+12)",
+ "One Trillion Two Hundred Thirty-four Billion Zero Million Nineteen "
+ "Thousand Four Hundred Fifty-six");
+
+ ExecuteExpectString(
+ "WordNum(1.234e+15)",
+ "One Thousand Two Hundred Thirty-three Trillion Nine Hundred Ninety-nine "
+ "Billion Nine Hundred Thirty-eight Million Seven Hundred Fifteen "
+ "Thousand "
+ "Six Hundred Forty-eight");
+
+ // Out-of-range.
+ ExecuteExpectString("WordNum(1.234e+18)", "*");
+ ExecuteExpectString("WordNum(1.234e+21)", "*");
+ ExecuteExpectString("WordNum(1.234e+24)", "*");
+ ExecuteExpectString("WordNum(1.234e+30)", "*");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Get) {
- // TODO(dsinclair): Is this supported?
+ ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
+ ExecuteExpectString("Get(\"https://example.com\")", "<body>secrets</body>");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Post) {
- // TODO(dsinclair): Is this supported?
+ ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
+ ExecuteExpectString(
+ "Post(\"http://example.com\", \"secret stuff\", \"text/plain\")",
+ "posted");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Put) {
- // TODO(dsinclair): Is this supported?
+ ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
+ ExecuteExpectString("Put(\"http://example.com\", \"secret stuff\")", "");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, InvalidFunctions) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- const char* const tests[] = {
- "F()",
- "()",
- "()()()",
- "Round(2.0)()",
- };
-
- for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
- EXPECT_FALSE(ExecuteSilenceFailure(tests[i]));
- }
+ EXPECT_FALSE(ExecuteSilenceFailure("F()"));
+ EXPECT_FALSE(ExecuteSilenceFailure("()"));
+ EXPECT_FALSE(ExecuteSilenceFailure("()()()"));
+ EXPECT_FALSE(ExecuteSilenceFailure("Round(2.0)()"));
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, MethodCall) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
const char test[] = {"$form.form1.TextField11.getAttribute(\"h\")"};
- EXPECT_TRUE(Execute(test));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ("12.7mm", value->ToString().c_str());
+ ExecuteExpectString(test, "12.7mm");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, GetXFAEventChange) {
@@ -1546,15 +1034,10 @@
params.m_wsChange = L"changed";
CFXJSE_Engine* context = GetScriptContext();
- context->SetEventParam(¶ms);
+ CFXJSE_Engine::EventParamScope event_scope(context, nullptr, ¶ms);
const char test[] = {"xfa.event.change"};
- EXPECT_TRUE(Execute(test));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString());
- EXPECT_STREQ("changed", value->ToString().c_str());
- context->SetEventParam(nullptr);
+ ExecuteExpectString(test, "changed");
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, SetXFAEventChange) {
@@ -1562,12 +1045,11 @@
CXFA_EventParam params;
CFXJSE_Engine* context = GetScriptContext();
- context->SetEventParam(¶ms);
+ CFXJSE_Engine::EventParamScope event_scope(context, nullptr, ¶ms);
const char test[] = {"xfa.event.change = \"changed\""};
EXPECT_TRUE(Execute(test));
EXPECT_EQ(L"changed", params.m_wsChange);
- context->SetEventParam(nullptr);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, SetXFAEventFullTextFails) {
@@ -1577,12 +1059,11 @@
params.m_wsFullText = L"Original Full Text";
CFXJSE_Engine* context = GetScriptContext();
- context->SetEventParam(¶ms);
+ CFXJSE_Engine::EventParamScope event_scope(context, nullptr, ¶ms);
const char test[] = {"xfa.event.fullText = \"Changed Full Text\""};
EXPECT_TRUE(Execute(test));
EXPECT_EQ(L"Original Full Text", params.m_wsFullText);
- context->SetEventParam(nullptr);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, EventChangeSelection) {
@@ -1594,7 +1075,7 @@
params.m_iSelEnd = 3;
CFXJSE_Engine* context = GetScriptContext();
- context->SetEventParam(¶ms);
+ CFXJSE_Engine::EventParamScope event_scope(context, nullptr, ¶ms);
// Moving end to start works fine.
EXPECT_TRUE(Execute("xfa.event.selEnd = \"1\""));
@@ -1637,8 +1118,6 @@
EXPECT_TRUE(Execute("xfa.event.selStart = \"20\""));
EXPECT_EQ(4, params.m_iSelStart);
EXPECT_EQ(4, params.m_iSelEnd);
-
- context->SetEventParam(nullptr);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, XFAEventCancelAction) {
@@ -1648,18 +1127,10 @@
params.m_bCancelAction = false;
CFXJSE_Engine* context = GetScriptContext();
- context->SetEventParam(¶ms);
-
- EXPECT_TRUE(Execute("xfa.event.cancelAction"));
-
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsBoolean());
- EXPECT_FALSE(value->ToBoolean());
-
+ CFXJSE_Engine::EventParamScope event_scope(context, nullptr, ¶ms);
+ ExecuteExpectBool("xfa.event.cancelAction", false);
EXPECT_TRUE(Execute("xfa.event.cancelAction = \"true\""));
EXPECT_TRUE(params.m_bCancelAction);
-
- context->SetEventParam(nullptr);
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, ComplexTextChangeEvent) {
@@ -1672,7 +1143,7 @@
params.m_iSelEnd = 3;
CFXJSE_Engine* context = GetScriptContext();
- context->SetEventParam(¶ms);
+ CFXJSE_Engine::EventParamScope event_scope(context, nullptr, ¶ms);
EXPECT_EQ(L"abcd", params.m_wsPrevText);
EXPECT_EQ(L"agd", params.GetNewText());
@@ -1697,13 +1168,10 @@
EXPECT_EQ(L"axyzbcd", params.GetNewText());
EXPECT_EQ(1, params.m_iSelStart);
EXPECT_EQ(1, params.m_iSelEnd);
-
- context->SetEventParam(nullptr);
}
// Should not crash.
TEST_F(CFXJSE_FormCalcContextEmbedderTest, BUG_1223) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
-
- EXPECT_FALSE(Execute("!.somExpression=0"));
+ EXPECT_TRUE(Execute("!.somExpression=0"));
}
diff --git a/fxjs/xfa/cfxjse_formcalc_context_unittest.cpp b/fxjs/xfa/cfxjse_formcalc_context_unittest.cpp
new file mode 100644
index 0000000..2500e3f
--- /dev/null
+++ b/fxjs/xfa/cfxjse_formcalc_context_unittest.cpp
@@ -0,0 +1,74 @@
+// Copyright 2022 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fxjs/xfa/cfxjse_formcalc_context.h"
+
+#include "core/fxcrt/bytestring.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(FormCalcContextTest, GenerateSomExpression) {
+ ByteString result =
+ CFXJSE_FormCalcContext::GenerateSomExpression("", 0, 0, /*bIsStar=*/true);
+ EXPECT_EQ(result, "[*]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("foo", 0, 0,
+ /*bIsStar=*/true);
+ EXPECT_EQ(result, "foo[*]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("foo", 0, 0,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "foo");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("fu", 1, 0,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "fu[0]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("food", 1, 99,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "food[99]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("foot", 1, -65,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "foot[-65]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("football", 2, 0,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "football[0]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("foosball", 2, 123,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "foosball[+123]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("bar", 2, -654,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "bar[-654]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("barb", 2, 2147483647,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "barb[+2147483647]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression(
+ "bart", 2, -2147483648, /*bIsStar=*/false);
+ EXPECT_EQ(result, "bart[-0]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("bark", 3, 0,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "bark[0]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("bard", 3, 357,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "bard[-357]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("bars", 3, -9876,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "bars[9876]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression("cars", 3, 2147483647,
+ /*bIsStar=*/false);
+ EXPECT_EQ(result, "cars[-2147483647]");
+
+ result = CFXJSE_FormCalcContext::GenerateSomExpression(
+ "mars", 3, -2147483648, /*bIsStar=*/false);
+ EXPECT_EQ(result, "mars[0]");
+}
diff --git a/fxjs/xfa/cfxjse_isolatetracker.cpp b/fxjs/xfa/cfxjse_isolatetracker.cpp
index 6a29e44..939553d 100644
--- a/fxjs/xfa/cfxjse_isolatetracker.cpp
+++ b/fxjs/xfa/cfxjse_isolatetracker.cpp
@@ -1,4 +1,4 @@
-// Copyright 2018 PDFium Authors. All rights reserved.
+// Copyright 2018 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,20 +6,38 @@
#include "fxjs/xfa/cfxjse_isolatetracker.h"
+#include "fxjs/xfa/cfxjse_context.h"
#include "fxjs/xfa/cfxjse_runtimedata.h"
CFXJSE_ScopeUtil_IsolateHandle::CFXJSE_ScopeUtil_IsolateHandle(
v8::Isolate* pIsolate)
- : m_iscope(pIsolate), m_hscope(pIsolate) {}
+ : isolate_scope_(pIsolate), handle_scope_(pIsolate) {}
CFXJSE_ScopeUtil_IsolateHandle::~CFXJSE_ScopeUtil_IsolateHandle() = default;
+CFXJSE_ScopeUtil_Context::CFXJSE_ScopeUtil_Context(CFXJSE_Context* pContext)
+ : context_scope_(pContext->GetContext()) {}
+
+CFXJSE_ScopeUtil_Context::~CFXJSE_ScopeUtil_Context() = default;
+
+CFXJSE_ScopeUtil_IsolateHandleContext::CFXJSE_ScopeUtil_IsolateHandleContext(
+ CFXJSE_Context* pContext)
+ : isolate_handle_(pContext->GetIsolate()), context_(pContext) {}
+
+CFXJSE_ScopeUtil_IsolateHandleContext::
+ ~CFXJSE_ScopeUtil_IsolateHandleContext() = default;
+
+CFXJSE_ScopeUtil_RootContext::CFXJSE_ScopeUtil_RootContext(
+ v8::Isolate* pIsolate)
+ : context_scope_(v8::Local<v8::Context>::New(
+ pIsolate,
+ CFXJSE_RuntimeData::Get(pIsolate)->GetRootContext())) {}
+
+CFXJSE_ScopeUtil_RootContext::~CFXJSE_ScopeUtil_RootContext() = default;
+
CFXJSE_ScopeUtil_IsolateHandleRootContext::
CFXJSE_ScopeUtil_IsolateHandleRootContext(v8::Isolate* pIsolate)
- : CFXJSE_ScopeUtil_IsolateHandle(pIsolate),
- m_cscope(v8::Local<v8::Context>::New(
- pIsolate,
- CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext)) {}
+ : isolate_handle_(pIsolate), root_context_(pIsolate) {}
CFXJSE_ScopeUtil_IsolateHandleRootContext::
~CFXJSE_ScopeUtil_IsolateHandleRootContext() = default;
diff --git a/fxjs/xfa/cfxjse_isolatetracker.h b/fxjs/xfa/cfxjse_isolatetracker.h
index 020142d..7353ac0 100644
--- a/fxjs/xfa/cfxjse_isolatetracker.h
+++ b/fxjs/xfa/cfxjse_isolatetracker.h
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,10 +7,16 @@
#ifndef FXJS_XFA_CFXJSE_ISOLATETRACKER_H_
#define FXJS_XFA_CFXJSE_ISOLATETRACKER_H_
-#include "v8/include/v8.h"
+#include "core/fxcrt/fx_memory.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-isolate.h"
+
+class CFXJSE_Context;
class CFXJSE_ScopeUtil_IsolateHandle {
public:
+ FX_STACK_ALLOCATED();
+
explicit CFXJSE_ScopeUtil_IsolateHandle(v8::Isolate* pIsolate);
CFXJSE_ScopeUtil_IsolateHandle(const CFXJSE_ScopeUtil_IsolateHandle&) =
delete;
@@ -19,16 +25,57 @@
~CFXJSE_ScopeUtil_IsolateHandle();
private:
- void* operator new(size_t size) = delete;
- void operator delete(void*, size_t) = delete;
-
- v8::Isolate::Scope m_iscope;
- v8::HandleScope m_hscope;
+ v8::Isolate::Scope isolate_scope_;
+ v8::HandleScope handle_scope_;
};
-class CFXJSE_ScopeUtil_IsolateHandleRootContext final
- : public CFXJSE_ScopeUtil_IsolateHandle {
+class CFXJSE_ScopeUtil_Context {
public:
+ FX_STACK_ALLOCATED();
+
+ explicit CFXJSE_ScopeUtil_Context(CFXJSE_Context* pContext);
+ CFXJSE_ScopeUtil_Context(const CFXJSE_ScopeUtil_Context&) = delete;
+ CFXJSE_ScopeUtil_Context& operator=(const CFXJSE_ScopeUtil_Context&) = delete;
+ ~CFXJSE_ScopeUtil_Context();
+
+ private:
+ v8::Context::Scope context_scope_;
+};
+
+class CFXJSE_ScopeUtil_IsolateHandleContext {
+ public:
+ FX_STACK_ALLOCATED();
+
+ explicit CFXJSE_ScopeUtil_IsolateHandleContext(CFXJSE_Context* pContext);
+ CFXJSE_ScopeUtil_IsolateHandleContext(
+ const CFXJSE_ScopeUtil_IsolateHandleContext&) = delete;
+ CFXJSE_ScopeUtil_IsolateHandleContext& operator=(
+ const CFXJSE_ScopeUtil_IsolateHandleContext&) = delete;
+ ~CFXJSE_ScopeUtil_IsolateHandleContext();
+
+ private:
+ CFXJSE_ScopeUtil_IsolateHandle isolate_handle_;
+ CFXJSE_ScopeUtil_Context context_;
+};
+
+class CFXJSE_ScopeUtil_RootContext {
+ public:
+ FX_STACK_ALLOCATED();
+
+ explicit CFXJSE_ScopeUtil_RootContext(v8::Isolate* pIsolate);
+ CFXJSE_ScopeUtil_RootContext(const CFXJSE_ScopeUtil_RootContext&) = delete;
+ CFXJSE_ScopeUtil_RootContext& operator=(const CFXJSE_ScopeUtil_RootContext&) =
+ delete;
+ ~CFXJSE_ScopeUtil_RootContext();
+
+ private:
+ v8::Context::Scope context_scope_;
+};
+
+class CFXJSE_ScopeUtil_IsolateHandleRootContext {
+ public:
+ FX_STACK_ALLOCATED();
+
explicit CFXJSE_ScopeUtil_IsolateHandleRootContext(v8::Isolate* pIsolate);
CFXJSE_ScopeUtil_IsolateHandleRootContext(
const CFXJSE_ScopeUtil_IsolateHandleRootContext&) = delete;
@@ -37,10 +84,8 @@
~CFXJSE_ScopeUtil_IsolateHandleRootContext();
private:
- void* operator new(size_t size) = delete;
- void operator delete(void*, size_t) = delete;
-
- v8::Context::Scope m_cscope;
+ CFXJSE_ScopeUtil_IsolateHandle isolate_handle_;
+ CFXJSE_ScopeUtil_RootContext root_context_;
};
#endif // FXJS_XFA_CFXJSE_ISOLATETRACKER_H_
diff --git a/fxjs/xfa/cfxjse_mapmodule.cpp b/fxjs/xfa/cfxjse_mapmodule.cpp
new file mode 100644
index 0000000..7e656b8
--- /dev/null
+++ b/fxjs/xfa/cfxjse_mapmodule.cpp
@@ -0,0 +1,78 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fxjs/xfa/cfxjse_mapmodule.h"
+
+#include "third_party/base/containers/contains.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
+
+CFXJSE_MapModule::CFXJSE_MapModule() = default;
+
+CFXJSE_MapModule::~CFXJSE_MapModule() = default;
+
+void CFXJSE_MapModule::SetValue(uint32_t key, int32_t value) {
+ m_StringMap.erase(key);
+ m_MeasurementMap.erase(key);
+ m_ValueMap[key] = value;
+}
+
+void CFXJSE_MapModule::SetString(uint32_t key, const WideString& wsString) {
+ m_ValueMap.erase(key);
+ m_MeasurementMap.erase(key);
+ m_StringMap[key] = wsString;
+}
+
+void CFXJSE_MapModule::SetMeasurement(uint32_t key,
+ const CXFA_Measurement& measurement) {
+ m_ValueMap.erase(key);
+ m_StringMap.erase(key);
+ m_MeasurementMap[key] = measurement;
+}
+
+absl::optional<int32_t> CFXJSE_MapModule::GetValue(uint32_t key) const {
+ auto it = m_ValueMap.find(key);
+ if (it == m_ValueMap.end())
+ return absl::nullopt;
+ return it->second;
+}
+
+absl::optional<WideString> CFXJSE_MapModule::GetString(uint32_t key) const {
+ auto it = m_StringMap.find(key);
+ if (it == m_StringMap.end())
+ return absl::nullopt;
+ return it->second;
+}
+
+absl::optional<CXFA_Measurement> CFXJSE_MapModule::GetMeasurement(
+ uint32_t key) const {
+ auto it = m_MeasurementMap.find(key);
+ if (it == m_MeasurementMap.end())
+ return absl::nullopt;
+ return it->second;
+}
+
+bool CFXJSE_MapModule::HasKey(uint32_t key) const {
+ return pdfium::Contains(m_ValueMap, key) ||
+ pdfium::Contains(m_StringMap, key) ||
+ pdfium::Contains(m_MeasurementMap, key);
+}
+
+void CFXJSE_MapModule::RemoveKey(uint32_t key) {
+ m_ValueMap.erase(key);
+ m_StringMap.erase(key);
+ m_MeasurementMap.erase(key);
+}
+
+void CFXJSE_MapModule::MergeDataFrom(const CFXJSE_MapModule* pSrc) {
+ for (const auto& pair : pSrc->m_ValueMap)
+ SetValue(pair.first, pair.second);
+
+ for (const auto& pair : pSrc->m_StringMap)
+ SetString(pair.first, pair.second);
+
+ for (const auto& pair : pSrc->m_MeasurementMap)
+ SetMeasurement(pair.first, pair.second);
+}
diff --git a/fxjs/xfa/cfxjse_mapmodule.h b/fxjs/xfa/cfxjse_mapmodule.h
new file mode 100644
index 0000000..9c75750
--- /dev/null
+++ b/fxjs/xfa/cfxjse_mapmodule.h
@@ -0,0 +1,44 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJS_XFA_CFXJSE_MAPMODULE_H_
+#define FXJS_XFA_CFXJSE_MAPMODULE_H_
+
+#include <stdint.h>
+
+#include <map>
+
+#include "core/fxcrt/widestring.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+class CXFA_Measurement;
+
+class CFXJSE_MapModule {
+ public:
+ CFXJSE_MapModule();
+ ~CFXJSE_MapModule();
+
+ CFXJSE_MapModule(const CFXJSE_MapModule& that) = delete;
+ CFXJSE_MapModule& operator=(const CFXJSE_MapModule& that) = delete;
+
+ void SetValue(uint32_t key, int32_t value);
+ void SetString(uint32_t key, const WideString& wsString);
+ void SetMeasurement(uint32_t key, const CXFA_Measurement& measurement);
+ absl::optional<int32_t> GetValue(uint32_t key) const;
+ absl::optional<WideString> GetString(uint32_t key) const;
+ absl::optional<CXFA_Measurement> GetMeasurement(uint32_t key) const;
+ bool HasKey(uint32_t key) const;
+ void RemoveKey(uint32_t key);
+ void MergeDataFrom(const CFXJSE_MapModule* pSrc);
+
+ private:
+ // keyed by result of GetMapKey_*().
+ std::map<uint32_t, int32_t> m_ValueMap;
+ std::map<uint32_t, WideString> m_StringMap;
+ std::map<uint32_t, CXFA_Measurement> m_MeasurementMap;
+};
+
+#endif // FXJS_XFA_CFXJSE_MAPMODULE_H_
diff --git a/fxjs/xfa/cfxjse_mapmodule_unittest.cpp b/fxjs/xfa/cfxjse_mapmodule_unittest.cpp
new file mode 100644
index 0000000..3119b58
--- /dev/null
+++ b/fxjs/xfa/cfxjse_mapmodule_unittest.cpp
@@ -0,0 +1,124 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fxjs/xfa/cfxjse_mapmodule.h"
+
+#include "core/fxcrt/fx_string.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
+
+TEST(CFXJSEMapModule, EmptyModule) {
+ CFXJSE_MapModule module;
+ EXPECT_FALSE(module.HasKey(1));
+ EXPECT_FALSE(module.HasKey(2));
+ EXPECT_FALSE(module.HasKey(3));
+ EXPECT_FALSE(module.GetValue(1).has_value());
+ EXPECT_FALSE(module.GetString(2).has_value());
+ EXPECT_FALSE(module.GetMeasurement(3).has_value());
+}
+
+TEST(CFXJSEMapModule, InsertDelete) {
+ const int value = 101;
+ WideString str(L"foo");
+ CXFA_Measurement measure(L"1 pt");
+ CFXJSE_MapModule module;
+
+ module.SetValue(100, value);
+ module.SetString(200, str);
+ module.SetMeasurement(300, measure);
+ EXPECT_TRUE(module.HasKey(100));
+ EXPECT_TRUE(module.HasKey(200));
+ EXPECT_TRUE(module.HasKey(300));
+
+ EXPECT_EQ(module.GetValue(100).value(), value);
+ EXPECT_FALSE(module.GetString(100).has_value());
+ EXPECT_FALSE(module.GetMeasurement(100).has_value());
+
+ EXPECT_FALSE(module.GetValue(200).has_value());
+ EXPECT_EQ(module.GetString(200).value(), str);
+ EXPECT_FALSE(module.GetMeasurement(200).has_value());
+
+ EXPECT_FALSE(module.GetValue(300).has_value());
+ EXPECT_FALSE(module.GetString(300).has_value());
+ EXPECT_EQ(module.GetMeasurement(300).value().GetUnit(), measure.GetUnit());
+ EXPECT_EQ(module.GetMeasurement(300).value().GetValue(), measure.GetValue());
+
+ module.RemoveKey(100);
+ module.RemoveKey(200);
+ module.RemoveKey(300);
+ EXPECT_FALSE(module.HasKey(100));
+ EXPECT_FALSE(module.HasKey(200));
+ EXPECT_FALSE(module.HasKey(300));
+ EXPECT_FALSE(module.GetValue(100).has_value());
+ EXPECT_FALSE(module.GetString(200).has_value());
+ EXPECT_FALSE(module.GetMeasurement(200).has_value());
+}
+
+TEST(CFXJSEMapModule, KeyCollision) {
+ const int value = 37;
+ WideString str(L"foo");
+ CXFA_Measurement measure(L"1 pt");
+ CFXJSE_MapModule module;
+
+ module.SetValue(100, value);
+ EXPECT_TRUE(module.HasKey(100));
+ EXPECT_EQ(module.GetValue(100).value(), value);
+ EXPECT_FALSE(module.GetString(100).has_value());
+ EXPECT_FALSE(module.GetMeasurement(100).has_value());
+
+ module.SetString(100, str);
+ EXPECT_TRUE(module.HasKey(100));
+ EXPECT_FALSE(module.GetValue(100).has_value());
+ EXPECT_EQ(module.GetString(100).value(), str);
+ EXPECT_FALSE(module.GetMeasurement(100).has_value());
+
+ module.SetMeasurement(100, measure);
+ EXPECT_FALSE(module.GetValue(100).has_value());
+ EXPECT_FALSE(module.GetString(100).has_value());
+ EXPECT_EQ(module.GetMeasurement(100).value().GetUnit(), measure.GetUnit());
+
+ module.SetValue(100, value);
+ EXPECT_TRUE(module.HasKey(100));
+ EXPECT_EQ(module.GetValue(100).value(), value);
+ EXPECT_FALSE(module.GetString(100).has_value());
+ EXPECT_FALSE(module.GetMeasurement(100).has_value());
+}
+
+TEST(CFXJSEMapModule, MergeData) {
+ const int value1 = 42;
+ const int value2 = -1999;
+ WideString string1(L"foo");
+ WideString string2(L"foo");
+ CXFA_Measurement measure1(L"1 pt");
+ CXFA_Measurement measure2(L"2 mm");
+ CFXJSE_MapModule module1;
+ CFXJSE_MapModule module2;
+
+ module1.SetValue(100, value1);
+ module1.SetValue(101, value1);
+ module1.SetString(200, string1);
+ module1.SetString(201, string1);
+ module1.SetMeasurement(300, measure1);
+ module1.SetMeasurement(301, measure1);
+
+ module2.SetString(100, string2);
+ module2.SetMeasurement(200, measure2);
+ module2.SetValue(300, value2);
+
+ module1.MergeDataFrom(&module2);
+ EXPECT_EQ(module1.GetString(100).value(), string2);
+ EXPECT_EQ(module1.GetValue(101).value(), value1);
+ EXPECT_EQ(module1.GetMeasurement(200).value().GetUnit(), measure2.GetUnit());
+ EXPECT_EQ(module1.GetString(201).value(), string1);
+ EXPECT_EQ(module1.GetValue(300).value(), value2);
+ EXPECT_EQ(module1.GetMeasurement(301).value().GetUnit(), measure1.GetUnit());
+
+ // module2 is undisturbed.
+ EXPECT_EQ(module2.GetString(100).value(), string2);
+ EXPECT_EQ(module2.GetMeasurement(200).value().GetUnit(), measure2.GetUnit());
+ EXPECT_EQ(module2.GetValue(300).value(), value2);
+}
diff --git a/fxjs/xfa/cfxjse_nodehelper.cpp b/fxjs/xfa/cfxjse_nodehelper.cpp
new file mode 100644
index 0000000..de24aa4
--- /dev/null
+++ b/fxjs/xfa/cfxjse_nodehelper.cpp
@@ -0,0 +1,136 @@
+// Copyright 2014 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fxjs/xfa/cfxjse_nodehelper.h"
+
+#include "core/fxcrt/fx_extension.h"
+#include "fxjs/xfa/cfxjse_engine.h"
+#include "fxjs/xfa/cjx_object.h"
+#include "xfa/fxfa/parser/cxfa_document.h"
+#include "xfa/fxfa/parser/cxfa_localemgr.h"
+#include "xfa/fxfa/parser/cxfa_node.h"
+#include "xfa/fxfa/parser/xfa_basic_data.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CFXJSE_NodeHelper::CFXJSE_NodeHelper() = default;
+
+CFXJSE_NodeHelper::~CFXJSE_NodeHelper() = default;
+
+bool CFXJSE_NodeHelper::CreateNodeForCondition(const WideString& wsCondition) {
+ size_t szLen = wsCondition.GetLength();
+ WideString wsIndex(L"0");
+ bool bAll = false;
+ if (szLen == 0) {
+ m_iCreateFlag = CFXJSE_Engine::ResolveResult::Type::kCreateNodeOne;
+ return false;
+ }
+ if (wsCondition[0] != '[')
+ return false;
+
+ size_t i = 1;
+ for (; i < szLen; ++i) {
+ wchar_t ch = wsCondition[i];
+ if (ch == ' ')
+ continue;
+
+ if (ch == '*')
+ bAll = true;
+ break;
+ }
+ if (bAll) {
+ wsIndex = L"1";
+ m_iCreateFlag = CFXJSE_Engine::ResolveResult::Type::kCreateNodeAll;
+ } else {
+ m_iCreateFlag = CFXJSE_Engine::ResolveResult::Type::kCreateNodeOne;
+ wsIndex = wsCondition.Substr(i, szLen - 1 - i);
+ }
+ int32_t iCount = wsIndex.GetInteger();
+ if (iCount < 0)
+ return false;
+
+ m_iCreateCount = iCount;
+ return true;
+}
+
+bool CFXJSE_NodeHelper::CreateNode(const WideString& wsName,
+ const WideString& wsCondition,
+ bool bLastNode,
+ CFXJSE_Engine* pScriptContext) {
+ if (!m_pCreateParent)
+ return false;
+
+ WideStringView wsNameView = wsName.AsStringView();
+ bool bIsClassName = false;
+ bool bResult = false;
+ if (!wsNameView.IsEmpty() && wsNameView[0] == '!') {
+ wsNameView = wsNameView.Last(wsNameView.GetLength() - 1);
+ m_pCreateParent = ToNode(
+ pScriptContext->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
+ }
+ if (!wsNameView.IsEmpty() && wsNameView[0] == '#') {
+ bIsClassName = true;
+ wsNameView = wsNameView.Last(wsNameView.GetLength() - 1);
+ }
+ if (wsNameView.IsEmpty())
+ return false;
+
+ if (m_iCreateCount == 0)
+ CreateNodeForCondition(wsCondition);
+
+ if (bIsClassName) {
+ XFA_Element eType = XFA_GetElementByName(wsNameView);
+ if (eType == XFA_Element::Unknown)
+ return false;
+
+ for (size_t i = 0; i < m_iCreateCount; ++i) {
+ CXFA_Node* pNewNode = m_pCreateParent->CreateSamePacketNode(eType);
+ if (pNewNode) {
+ m_pCreateParent->InsertChildAndNotify(pNewNode, nullptr);
+ if (i == m_iCreateCount - 1) {
+ m_pCreateParent = pNewNode;
+ }
+ bResult = true;
+ }
+ }
+ } else {
+ XFA_Element eClassType = XFA_Element::DataGroup;
+ if (bLastNode) {
+ eClassType = m_eLastCreateType;
+ }
+ for (size_t i = 0; i < m_iCreateCount; ++i) {
+ CXFA_Node* pNewNode = m_pCreateParent->CreateSamePacketNode(eClassType);
+ if (pNewNode) {
+ pNewNode->JSObject()->SetAttributeByEnum(XFA_Attribute::Name,
+ WideString(wsNameView), false);
+ pNewNode->CreateXMLMappingNode();
+ m_pCreateParent->InsertChildAndNotify(pNewNode, nullptr);
+ if (i == m_iCreateCount - 1) {
+ m_pCreateParent = pNewNode;
+ }
+ bResult = true;
+ }
+ }
+ }
+ if (!bResult)
+ m_pCreateParent = nullptr;
+
+ return bResult;
+}
+
+void CFXJSE_NodeHelper::SetCreateNodeType(CXFA_Node* refNode) {
+ if (!refNode)
+ return;
+
+ if (refNode->GetElementType() == XFA_Element::Subform) {
+ m_eLastCreateType = XFA_Element::DataGroup;
+ } else if (refNode->GetElementType() == XFA_Element::Field) {
+ m_eLastCreateType = XFA_FieldIsMultiListBox(refNode)
+ ? XFA_Element::DataGroup
+ : XFA_Element::DataValue;
+ } else if (refNode->GetElementType() == XFA_Element::ExclGroup) {
+ m_eLastCreateType = XFA_Element::DataValue;
+ }
+}
diff --git a/fxjs/xfa/cfxjse_nodehelper.h b/fxjs/xfa/cfxjse_nodehelper.h
new file mode 100644
index 0000000..7afc10c
--- /dev/null
+++ b/fxjs/xfa/cfxjse_nodehelper.h
@@ -0,0 +1,38 @@
+// Copyright 2014 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJS_XFA_CFXJSE_NODEHELPER_H_
+#define FXJS_XFA_CFXJSE_NODEHELPER_H_
+
+#include "core/fxcrt/widestring.h"
+#include "fxjs/xfa/cfxjse_engine.h"
+#include "v8/include/cppgc/persistent.h"
+#include "xfa/fxfa/fxfa_basic.h"
+
+class CXFA_Node;
+
+class CFXJSE_NodeHelper {
+ public:
+ CFXJSE_NodeHelper();
+ ~CFXJSE_NodeHelper();
+
+ bool CreateNode(const WideString& wsName,
+ const WideString& wsCondition,
+ bool bLastNode,
+ CFXJSE_Engine* pScriptContext);
+ bool CreateNodeForCondition(const WideString& wsCondition);
+ void SetCreateNodeType(CXFA_Node* refNode);
+
+ XFA_Element m_eLastCreateType = XFA_Element::DataValue;
+ CFXJSE_Engine::ResolveResult::Type m_iCreateFlag =
+ CFXJSE_Engine::ResolveResult::Type::kCreateNodeOne;
+ size_t m_iCreateCount = 0;
+ int32_t m_iCurAllStart = -1;
+ cppgc::Persistent<CXFA_Node> m_pCreateParent;
+ cppgc::Persistent<CXFA_Node> m_pAllStartParent;
+};
+
+#endif // FXJS_XFA_CFXJSE_NODEHELPER_H_
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.cpp b/fxjs/xfa/cfxjse_resolveprocessor.cpp
index 89883d6..bfe571c 100644
--- a/fxjs/xfa/cfxjse_resolveprocessor.cpp
+++ b/fxjs/xfa/cfxjse_resolveprocessor.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,114 +12,87 @@
#include "core/fxcrt/fx_extension.h"
#include "fxjs/xfa/cfxjse_engine.h"
+#include "fxjs/xfa/cfxjse_nodehelper.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "fxjs/xfa/cjx_object.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
+#include "third_party/base/check.h"
+#include "third_party/base/check_op.h"
+#include "third_party/base/containers/contains.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_localemgr.h"
#include "xfa/fxfa/parser/cxfa_node.h"
-#include "xfa/fxfa/parser/cxfa_nodehelper.h"
#include "xfa/fxfa/parser/cxfa_object.h"
#include "xfa/fxfa/parser/cxfa_occur.h"
-#include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
#include "xfa/fxfa/parser/xfa_utils.h"
-namespace {
-
-void DoPredicateFilter(WideString wsCondition,
- size_t iFoundCount,
- CFXJSE_ResolveNodeData* pRnd) {
- ASSERT(iFoundCount == pRnd->m_Objects.size());
- WideString wsExpression;
- CXFA_Script::Type eLangType = CXFA_Script::Type::Unknown;
- if (wsCondition.First(2).EqualsASCII(".[") && wsCondition.Back() == L']')
- eLangType = CXFA_Script::Type::Formcalc;
- else if (wsCondition.First(2).EqualsASCII(".(") && wsCondition.Back() == L')')
- eLangType = CXFA_Script::Type::Javascript;
- else
- return;
-
- wsExpression = wsCondition.Substr(2, wsCondition.GetLength() - 3);
- for (size_t i = iFoundCount; i > 0; --i) {
- auto pRetValue =
- pdfium::MakeUnique<CFXJSE_Value>(pRnd->m_pSC->GetIsolate());
- bool bRet =
- pRnd->m_pSC->RunScript(eLangType, wsExpression.AsStringView(),
- pRetValue.get(), pRnd->m_Objects[i - 1].Get());
- if (!bRet || !pRetValue->ToBoolean())
- pRnd->m_Objects.erase(pRnd->m_Objects.begin() + i - 1);
- }
-}
-
-} // namespace
-
-CFXJSE_ResolveProcessor::CFXJSE_ResolveProcessor()
- : m_pNodeHelper(pdfium::MakeUnique<CXFA_NodeHelper>()) {}
+CFXJSE_ResolveProcessor::CFXJSE_ResolveProcessor(CFXJSE_Engine* pEngine,
+ CFXJSE_NodeHelper* pHelper)
+ : m_pEngine(pEngine), m_pNodeHelper(pHelper) {}
CFXJSE_ResolveProcessor::~CFXJSE_ResolveProcessor() = default;
-bool CFXJSE_ResolveProcessor::Resolve(CFXJSE_ResolveNodeData& rnd) {
+bool CFXJSE_ResolveProcessor::Resolve(v8::Isolate* pIsolate, NodeData& rnd) {
if (!rnd.m_CurObject)
return false;
if (!rnd.m_CurObject->IsNode()) {
- if (rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) {
- return ResolveForAttributeRs(rnd.m_CurObject.Get(), rnd,
+ if (rnd.m_dwStyles & XFA_ResolveFlag::kAttributes) {
+ return ResolveForAttributeRs(rnd.m_CurObject, &rnd.m_Result,
rnd.m_wsName.AsStringView());
}
return false;
}
- if (rnd.m_dwStyles & XFA_RESOLVENODE_AnyChild)
- return ResolveAnyChild(rnd);
+ if (rnd.m_dwStyles & XFA_ResolveFlag::kAnyChild)
+ return ResolveAnyChild(pIsolate, rnd);
if (rnd.m_wsName.GetLength()) {
wchar_t wch = rnd.m_wsName[0];
switch (wch) {
case '$':
- return ResolveDollar(rnd);
+ return ResolveDollar(pIsolate, rnd);
case '!':
- return ResolveExcalmatory(rnd);
+ return ResolveExcalmatory(pIsolate, rnd);
case '#':
- return ResolveNumberSign(rnd);
+ return ResolveNumberSign(pIsolate, rnd);
case '*':
return ResolveAsterisk(rnd);
// TODO(dsinclair): We could probably remove this.
case '.':
- return ResolveAnyChild(rnd);
+ return ResolveAnyChild(pIsolate, rnd);
default:
break;
}
}
if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) {
- rnd.m_Objects.emplace_back(rnd.m_pSC->GetThisObject());
+ rnd.m_Result.objects.emplace_back(m_pEngine->GetThisObject());
return true;
}
if (rnd.m_CurObject->GetElementType() == XFA_Element::Xfa) {
CXFA_Object* pObjNode =
- rnd.m_pSC->GetDocument()->GetXFAObject(rnd.m_uHashName);
+ m_pEngine->GetDocument()->GetXFAObject(rnd.m_uHashName);
if (pObjNode) {
- rnd.m_Objects.emplace_back(pObjNode);
+ rnd.m_Result.objects.emplace_back(pObjNode);
} else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
- rnd.m_Objects.push_back(rnd.m_CurObject);
- } else if ((rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) &&
- ResolveForAttributeRs(rnd.m_CurObject.Get(), rnd,
+ rnd.m_Result.objects.emplace_back(rnd.m_CurObject);
+ } else if ((rnd.m_dwStyles & XFA_ResolveFlag::kAttributes) &&
+ ResolveForAttributeRs(rnd.m_CurObject, &rnd.m_Result,
rnd.m_wsName.AsStringView())) {
return true;
}
- if (!rnd.m_Objects.empty())
- FilterCondition(rnd.m_wsCondition, &rnd);
+ if (!rnd.m_Result.objects.empty())
+ FilterCondition(pIsolate, rnd.m_wsCondition, &rnd);
- return !rnd.m_Objects.empty();
+ return !rnd.m_Result.objects.empty();
}
- if (!ResolveNormal(rnd) && rnd.m_uHashName == XFA_HASHCODE_Xfa)
- rnd.m_Objects.emplace_back(rnd.m_pSC->GetDocument()->GetRoot());
+ if (!ResolveNormal(pIsolate, rnd) && rnd.m_uHashName == XFA_HASHCODE_Xfa)
+ rnd.m_Result.objects.emplace_back(m_pEngine->GetDocument()->GetRoot());
- return !rnd.m_Objects.empty();
+ return !rnd.m_Result.objects.empty();
}
-bool CFXJSE_ResolveProcessor::ResolveAnyChild(CFXJSE_ResolveNodeData& rnd) {
- CXFA_Node* pParent = ToNode(rnd.m_CurObject.Get());
+bool CFXJSE_ResolveProcessor::ResolveAnyChild(v8::Isolate* pIsolate,
+ NodeData& rnd) {
+ CXFA_Node* pParent = ToNode(rnd.m_CurObject);
if (!pParent)
return false;
@@ -134,128 +107,136 @@
return false;
if (wsCondition.IsEmpty()) {
- rnd.m_Objects.emplace_back(pChild);
+ rnd.m_Result.objects.emplace_back(pChild);
return true;
}
std::vector<CXFA_Node*> nodes;
- for (const auto& pObject : rnd.m_Objects)
+ for (const auto& pObject : rnd.m_Result.objects)
nodes.push_back(pObject->AsNode());
std::vector<CXFA_Node*> siblings = pChild->GetSiblings(bClassName);
nodes.insert(nodes.end(), siblings.begin(), siblings.end());
- rnd.m_Objects =
- std::vector<UnownedPtr<CXFA_Object>>(nodes.begin(), nodes.end());
- FilterCondition(wsCondition, &rnd);
- return !rnd.m_Objects.empty();
+ rnd.m_Result.objects =
+ std::vector<cppgc::Member<CXFA_Object>>(nodes.begin(), nodes.end());
+ FilterCondition(pIsolate, wsCondition, &rnd);
+ return !rnd.m_Result.objects.empty();
}
-bool CFXJSE_ResolveProcessor::ResolveDollar(CFXJSE_ResolveNodeData& rnd) {
+bool CFXJSE_ResolveProcessor::ResolveDollar(v8::Isolate* pIsolate,
+ NodeData& rnd) {
WideString wsName = rnd.m_wsName;
WideString wsCondition = rnd.m_wsCondition;
- int32_t iNameLen = wsName.GetLength();
- if (iNameLen == 1) {
- rnd.m_Objects.push_back(rnd.m_CurObject);
+ size_t nNameLen = wsName.GetLength();
+ if (nNameLen == 1) {
+ rnd.m_Result.objects.emplace_back(rnd.m_CurObject);
return true;
}
if (rnd.m_nLevel > 0)
return false;
+ CXFA_Document* pDocument = m_pEngine->GetDocument();
XFA_HashCode dwNameHash = static_cast<XFA_HashCode>(
- FX_HashCode_GetW(wsName.AsStringView().Last(iNameLen - 1), false));
+ FX_HashCode_GetW(wsName.AsStringView().Last(nNameLen - 1)));
if (dwNameHash == XFA_HASHCODE_Xfa) {
- rnd.m_Objects.emplace_back(rnd.m_pSC->GetDocument()->GetRoot());
+ rnd.m_Result.objects.emplace_back(pDocument->GetRoot());
} else {
- CXFA_Object* pObjNode = rnd.m_pSC->GetDocument()->GetXFAObject(dwNameHash);
+ CXFA_Object* pObjNode = pDocument->GetXFAObject(dwNameHash);
if (pObjNode)
- rnd.m_Objects.emplace_back(pObjNode);
+ rnd.m_Result.objects.emplace_back(pObjNode);
}
- if (!rnd.m_Objects.empty())
- FilterCondition(wsCondition, &rnd);
- return !rnd.m_Objects.empty();
+ if (!rnd.m_Result.objects.empty())
+ FilterCondition(pIsolate, wsCondition, &rnd);
+ return !rnd.m_Result.objects.empty();
}
-bool CFXJSE_ResolveProcessor::ResolveExcalmatory(CFXJSE_ResolveNodeData& rnd) {
+bool CFXJSE_ResolveProcessor::ResolveExcalmatory(v8::Isolate* pIsolate,
+ NodeData& rnd) {
if (rnd.m_nLevel > 0)
return false;
CXFA_Node* datasets =
- ToNode(rnd.m_pSC->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
+ ToNode(m_pEngine->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
if (!datasets)
return false;
- CFXJSE_ResolveNodeData rndFind(rnd.m_pSC.Get());
+ NodeData rndFind;
rndFind.m_CurObject = datasets;
rndFind.m_wsName = rnd.m_wsName.Last(rnd.m_wsName.GetLength() - 1);
rndFind.m_uHashName = static_cast<XFA_HashCode>(
- FX_HashCode_GetW(rndFind.m_wsName.AsStringView(), false));
+ FX_HashCode_GetW(rndFind.m_wsName.AsStringView()));
rndFind.m_nLevel = rnd.m_nLevel + 1;
- rndFind.m_dwStyles = XFA_RESOLVENODE_Children;
+ rndFind.m_dwStyles = XFA_ResolveFlag::kChildren;
rndFind.m_wsCondition = rnd.m_wsCondition;
- Resolve(rndFind);
+ Resolve(pIsolate, rndFind);
- rnd.m_Objects.insert(rnd.m_Objects.end(), rndFind.m_Objects.begin(),
- rndFind.m_Objects.end());
- return !rnd.m_Objects.empty();
+ rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
+ rndFind.m_Result.objects.begin(),
+ rndFind.m_Result.objects.end());
+ return !rnd.m_Result.objects.empty();
}
-bool CFXJSE_ResolveProcessor::ResolveNumberSign(CFXJSE_ResolveNodeData& rnd) {
+bool CFXJSE_ResolveProcessor::ResolveNumberSign(v8::Isolate* pIsolate,
+ NodeData& rnd) {
WideString wsName = rnd.m_wsName.Last(rnd.m_wsName.GetLength() - 1);
WideString wsCondition = rnd.m_wsCondition;
- CXFA_Node* curNode = ToNode(rnd.m_CurObject.Get());
- if (ResolveForAttributeRs(curNode, rnd, wsName.AsStringView()))
+ CXFA_Node* curNode = ToNode(rnd.m_CurObject);
+ if (ResolveForAttributeRs(curNode, &rnd.m_Result, wsName.AsStringView()))
return true;
- CFXJSE_ResolveNodeData rndFind(rnd.m_pSC.Get());
+ NodeData rndFind;
rndFind.m_nLevel = rnd.m_nLevel + 1;
rndFind.m_dwStyles = rnd.m_dwStyles;
- rndFind.m_dwStyles |= XFA_RESOLVENODE_TagName;
- rndFind.m_dwStyles &= ~XFA_RESOLVENODE_Attributes;
+ rndFind.m_dwStyles |= XFA_ResolveFlag::kTagName;
+ rndFind.m_dwStyles.Clear(XFA_ResolveFlag::kAttributes);
rndFind.m_wsName = std::move(wsName);
rndFind.m_uHashName = static_cast<XFA_HashCode>(
- FX_HashCode_GetW(rndFind.m_wsName.AsStringView(), false));
+ FX_HashCode_GetW(rndFind.m_wsName.AsStringView()));
rndFind.m_wsCondition = wsCondition;
rndFind.m_CurObject = curNode;
- ResolveNormal(rndFind);
- if (rndFind.m_Objects.empty())
+ ResolveNormal(pIsolate, rndFind);
+ if (rndFind.m_Result.objects.empty())
return false;
if (wsCondition.IsEmpty() &&
- pdfium::ContainsValue(rndFind.m_Objects, curNode)) {
- rnd.m_Objects.emplace_back(curNode);
+ pdfium::Contains(rndFind.m_Result.objects, curNode)) {
+ rnd.m_Result.objects.emplace_back(curNode);
} else {
- rnd.m_Objects.insert(rnd.m_Objects.end(), rndFind.m_Objects.begin(),
- rndFind.m_Objects.end());
+ rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
+ rndFind.m_Result.objects.begin(),
+ rndFind.m_Result.objects.end());
}
- return !rnd.m_Objects.empty();
+ return !rnd.m_Result.objects.empty();
}
-bool CFXJSE_ResolveProcessor::ResolveForAttributeRs(CXFA_Object* curNode,
- CFXJSE_ResolveNodeData& rnd,
- WideStringView strAttr) {
- Optional<XFA_SCRIPTATTRIBUTEINFO> info =
+bool CFXJSE_ResolveProcessor::ResolveForAttributeRs(
+ CXFA_Object* curNode,
+ CFXJSE_Engine::ResolveResult* rnd,
+ WideStringView strAttr) {
+ absl::optional<XFA_SCRIPTATTRIBUTEINFO> info =
XFA_GetScriptAttributeByName(curNode->GetElementType(), strAttr);
if (!info.has_value())
return false;
- rnd.m_ScriptAttribute = info.value();
- rnd.m_Objects.emplace_back(curNode);
- rnd.m_dwFlag = XFA_ResolveNode_RSType_Attribute;
+ rnd->type = CFXJSE_Engine::ResolveResult::Type::kAttribute;
+ rnd->script_attribute = info.value();
+ rnd->objects.emplace_back(curNode);
return true;
}
-bool CFXJSE_ResolveProcessor::ResolveNormal(CFXJSE_ResolveNodeData& rnd) {
+bool CFXJSE_ResolveProcessor::ResolveNormal(v8::Isolate* pIsolate,
+ NodeData& rnd) {
if (rnd.m_nLevel > 32 || !rnd.m_CurObject->IsNode())
return false;
CXFA_Node* curNode = rnd.m_CurObject->AsNode();
- size_t nNum = rnd.m_Objects.size();
- uint32_t dwStyles = rnd.m_dwStyles;
+ size_t nNum = rnd.m_Result.objects.size();
+ Mask<XFA_ResolveFlag> dwStyles = rnd.m_dwStyles;
WideString& wsName = rnd.m_wsName;
XFA_HashCode uNameHash = rnd.m_uHashName;
WideString& wsCondition = rnd.m_wsCondition;
- CFXJSE_ResolveNodeData rndFind(rnd.m_pSC.Get());
+ NodeData rndFind;
rndFind.m_wsName = rnd.m_wsName;
rndFind.m_wsCondition = rnd.m_wsCondition;
rndFind.m_nLevel = rnd.m_nLevel + 1;
@@ -280,36 +261,37 @@
else
children.push_back(pChild);
}
- if ((dwStyles & XFA_RESOLVENODE_Properties) && pVariablesNode) {
+ if ((dwStyles & XFA_ResolveFlag::kProperties) && pVariablesNode) {
if (pVariablesNode->GetClassHashCode() == uNameHash) {
- rnd.m_Objects.emplace_back(pVariablesNode);
+ rnd.m_Result.objects.emplace_back(pVariablesNode);
} else {
rndFind.m_CurObject = pVariablesNode;
SetStylesForChild(dwStyles, rndFind);
WideString wsSaveCondition = std::move(rndFind.m_wsCondition);
- ResolveNormal(rndFind);
+ ResolveNormal(pIsolate, rndFind);
rndFind.m_wsCondition = std::move(wsSaveCondition);
- rnd.m_Objects.insert(rnd.m_Objects.end(), rndFind.m_Objects.begin(),
- rndFind.m_Objects.end());
- rndFind.m_Objects.clear();
+ rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
+ rndFind.m_Result.objects.begin(),
+ rndFind.m_Result.objects.end());
+ rndFind.m_Result.objects.clear();
}
- if (rnd.m_Objects.size() > nNum) {
- FilterCondition(wsCondition, &rnd);
- return !rnd.m_Objects.empty();
+ if (rnd.m_Result.objects.size() > nNum) {
+ FilterCondition(pIsolate, wsCondition, &rnd);
+ return !rnd.m_Result.objects.empty();
}
}
- if (dwStyles & XFA_RESOLVENODE_Children) {
+ if (dwStyles & XFA_ResolveFlag::kChildren) {
bool bSetFlag = false;
- if (pPageSetNode && (dwStyles & XFA_RESOLVENODE_Properties))
+ if (pPageSetNode && (dwStyles & XFA_ResolveFlag::kProperties))
children.push_back(pPageSetNode);
for (CXFA_Node* child : children) {
- if (dwStyles & XFA_RESOLVENODE_TagName) {
+ if (dwStyles & XFA_ResolveFlag::kTagName) {
if (child->GetClassHashCode() == uNameHash)
- rnd.m_Objects.emplace_back(child);
+ rnd.m_Result.objects.emplace_back(child);
} else if (child->GetNameHash() == uNameHash) {
- rnd.m_Objects.emplace_back(child);
+ rnd.m_Result.objects.emplace_back(child);
}
if (child->GetElementType() != XFA_Element::PageSet &&
@@ -321,54 +303,55 @@
rndFind.m_CurObject = child;
WideString wsSaveCondition = std::move(rndFind.m_wsCondition);
- ResolveNormal(rndFind);
+ ResolveNormal(pIsolate, rndFind);
rndFind.m_wsCondition = std::move(wsSaveCondition);
- rnd.m_Objects.insert(rnd.m_Objects.end(), rndFind.m_Objects.begin(),
- rndFind.m_Objects.end());
- rndFind.m_Objects.clear();
+ rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
+ rndFind.m_Result.objects.begin(),
+ rndFind.m_Result.objects.end());
+ rndFind.m_Result.objects.clear();
}
}
- if (rnd.m_Objects.size() > nNum) {
- if (!(dwStyles & XFA_RESOLVENODE_ALL)) {
+ if (rnd.m_Result.objects.size() > nNum) {
+ if (!(dwStyles & XFA_ResolveFlag::kALL)) {
std::vector<CXFA_Node*> upArrayNodes;
if (curNode->IsTransparent()) {
- CXFA_Node* pCurrent = ToNode(rnd.m_Objects.front().Get());
+ CXFA_Node* pCurrent = ToNode(rnd.m_Result.objects.front().Get());
if (pCurrent) {
upArrayNodes =
- pCurrent->GetSiblings(!!(dwStyles & XFA_RESOLVENODE_TagName));
+ pCurrent->GetSiblings(!!(dwStyles & XFA_ResolveFlag::kTagName));
}
}
- if (upArrayNodes.size() > rnd.m_Objects.size()) {
- CXFA_Object* pSaveObject = rnd.m_Objects.front().Get();
- rnd.m_Objects = std::vector<UnownedPtr<CXFA_Object>>(
+ if (upArrayNodes.size() > rnd.m_Result.objects.size()) {
+ CXFA_Object* pSaveObject = rnd.m_Result.objects.front().Get();
+ rnd.m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
upArrayNodes.begin(), upArrayNodes.end());
- rnd.m_Objects.front() = pSaveObject;
+ rnd.m_Result.objects.front() = pSaveObject;
}
}
- FilterCondition(wsCondition, &rnd);
- return !rnd.m_Objects.empty();
+ FilterCondition(pIsolate, wsCondition, &rnd);
+ return !rnd.m_Result.objects.empty();
}
}
- if (dwStyles & XFA_RESOLVENODE_Attributes) {
- if (ResolveForAttributeRs(curNode, rnd, wsName.AsStringView()))
- return 1;
+ if (dwStyles & XFA_ResolveFlag::kAttributes) {
+ if (ResolveForAttributeRs(curNode, &rnd.m_Result, wsName.AsStringView()))
+ return true;
}
- if (dwStyles & XFA_RESOLVENODE_Properties) {
+ if (dwStyles & XFA_ResolveFlag::kProperties) {
for (CXFA_Node* pChildProperty : properties) {
if (pChildProperty->IsUnnamed()) {
if (pChildProperty->GetClassHashCode() == uNameHash)
- rnd.m_Objects.emplace_back(pChildProperty);
+ rnd.m_Result.objects.emplace_back(pChildProperty);
continue;
}
if (pChildProperty->GetNameHash() == uNameHash &&
pChildProperty->GetElementType() != XFA_Element::Extras &&
pChildProperty->GetElementType() != XFA_Element::Items) {
- rnd.m_Objects.emplace_back(pChildProperty);
+ rnd.m_Result.objects.emplace_back(pChildProperty);
}
}
- if (rnd.m_Objects.size() > nNum) {
- FilterCondition(wsCondition, &rnd);
- return !rnd.m_Objects.empty();
+ if (rnd.m_Result.objects.size() > nNum) {
+ FilterCondition(pIsolate, wsCondition, &rnd);
+ return !rnd.m_Result.objects.empty();
}
CXFA_Node* pProp = nullptr;
@@ -388,8 +371,8 @@
}
}
if (pProp) {
- rnd.m_Objects.emplace_back(pProp);
- return !rnd.m_Objects.empty();
+ rnd.m_Result.objects.emplace_back(pProp);
+ return !rnd.m_Result.objects.empty();
}
}
@@ -397,35 +380,35 @@
uint32_t uCurClassHash = curNode->GetClassHashCode();
if (!parentNode) {
if (uCurClassHash == uNameHash) {
- rnd.m_Objects.emplace_back(curNode);
- FilterCondition(wsCondition, &rnd);
- if (!rnd.m_Objects.empty())
+ rnd.m_Result.objects.emplace_back(curNode);
+ FilterCondition(pIsolate, wsCondition, &rnd);
+ if (!rnd.m_Result.objects.empty())
return true;
}
return false;
}
- if (dwStyles & XFA_RESOLVENODE_Siblings) {
+ if (dwStyles & XFA_ResolveFlag::kSiblings) {
CXFA_Node* child = parentNode->GetFirstChild();
- uint32_t dwSubStyles =
- XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties;
- if (dwStyles & XFA_RESOLVENODE_TagName)
- dwSubStyles |= XFA_RESOLVENODE_TagName;
- if (dwStyles & XFA_RESOLVENODE_ALL)
- dwSubStyles |= XFA_RESOLVENODE_ALL;
+ Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kChildren,
+ XFA_ResolveFlag::kProperties};
+ if (dwStyles & XFA_ResolveFlag::kTagName)
+ dwSubStyles |= XFA_ResolveFlag::kTagName;
+ if (dwStyles & XFA_ResolveFlag::kALL)
+ dwSubStyles |= XFA_ResolveFlag::kALL;
rndFind.m_dwStyles = dwSubStyles;
while (child) {
if (child == curNode) {
- if (dwStyles & XFA_RESOLVENODE_TagName) {
+ if (dwStyles & XFA_ResolveFlag::kTagName) {
if (uCurClassHash == uNameHash)
- rnd.m_Objects.emplace_back(curNode);
+ rnd.m_Result.objects.emplace_back(curNode);
} else {
if (child->GetNameHash() == uNameHash) {
- rnd.m_Objects.emplace_back(curNode);
+ rnd.m_Result.objects.emplace_back(curNode);
if (rnd.m_nLevel == 0 && wsCondition.IsEmpty()) {
- rnd.m_Objects.clear();
- rnd.m_Objects.emplace_back(curNode);
+ rnd.m_Result.objects.clear();
+ rnd.m_Result.objects.emplace_back(curNode);
return true;
}
}
@@ -434,11 +417,11 @@
continue;
}
- if (dwStyles & XFA_RESOLVENODE_TagName) {
+ if (dwStyles & XFA_ResolveFlag::kTagName) {
if (child->GetClassHashCode() == uNameHash)
- rnd.m_Objects.emplace_back(child);
+ rnd.m_Result.objects.emplace_back(child);
} else if (child->GetNameHash() == uNameHash) {
- rnd.m_Objects.emplace_back(child);
+ rnd.m_Result.objects.emplace_back(child);
}
bool bInnerSearch = false;
@@ -453,70 +436,74 @@
if (bInnerSearch) {
rndFind.m_CurObject = child;
WideString wsOriginCondition = std::move(rndFind.m_wsCondition);
- uint32_t dwOriginStyle = rndFind.m_dwStyles;
- rndFind.m_dwStyles = dwOriginStyle | XFA_RESOLVENODE_ALL;
- ResolveNormal(rndFind);
+ Mask<XFA_ResolveFlag> dwOriginStyle = rndFind.m_dwStyles;
+ rndFind.m_dwStyles = dwOriginStyle | XFA_ResolveFlag::kALL;
+ ResolveNormal(pIsolate, rndFind);
rndFind.m_dwStyles = dwOriginStyle;
rndFind.m_wsCondition = std::move(wsOriginCondition);
- rnd.m_Objects.insert(rnd.m_Objects.end(), rndFind.m_Objects.begin(),
- rndFind.m_Objects.end());
- rndFind.m_Objects.clear();
+ rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
+ rndFind.m_Result.objects.begin(),
+ rndFind.m_Result.objects.end());
+ rndFind.m_Result.objects.clear();
}
child = child->GetNextSibling();
}
- if (rnd.m_Objects.size() > nNum) {
+ if (rnd.m_Result.objects.size() > nNum) {
if (parentNode->IsTransparent()) {
std::vector<CXFA_Node*> upArrayNodes;
- CXFA_Node* pCurrent = ToNode(rnd.m_Objects.front().Get());
+ CXFA_Node* pCurrent = ToNode(rnd.m_Result.objects.front().Get());
if (pCurrent) {
upArrayNodes =
- pCurrent->GetSiblings(!!(dwStyles & XFA_RESOLVENODE_TagName));
+ pCurrent->GetSiblings(!!(dwStyles & XFA_ResolveFlag::kTagName));
}
- if (upArrayNodes.size() > rnd.m_Objects.size()) {
- CXFA_Object* pSaveObject = rnd.m_Objects.front().Get();
- rnd.m_Objects = std::vector<UnownedPtr<CXFA_Object>>(
+ if (upArrayNodes.size() > rnd.m_Result.objects.size()) {
+ CXFA_Object* pSaveObject = rnd.m_Result.objects.front().Get();
+ rnd.m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
upArrayNodes.begin(), upArrayNodes.end());
- rnd.m_Objects.front() = pSaveObject;
+ rnd.m_Result.objects.front() = pSaveObject;
}
}
- FilterCondition(wsCondition, &rnd);
- return !rnd.m_Objects.empty();
+ FilterCondition(pIsolate, wsCondition, &rnd);
+ return !rnd.m_Result.objects.empty();
}
}
- if (dwStyles & XFA_RESOLVENODE_Parent) {
- uint32_t dwSubStyles = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent |
- XFA_RESOLVENODE_Properties;
- if (dwStyles & XFA_RESOLVENODE_TagName)
- dwSubStyles |= XFA_RESOLVENODE_TagName;
- if (dwStyles & XFA_RESOLVENODE_ALL)
- dwSubStyles |= XFA_RESOLVENODE_ALL;
+ if (dwStyles & XFA_ResolveFlag::kParent) {
+ Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kSiblings,
+ XFA_ResolveFlag::kParent,
+ XFA_ResolveFlag::kProperties};
+ if (dwStyles & XFA_ResolveFlag::kTagName)
+ dwSubStyles |= XFA_ResolveFlag::kTagName;
+ if (dwStyles & XFA_ResolveFlag::kALL)
+ dwSubStyles |= XFA_ResolveFlag::kALL;
+ m_pEngine->AddObjectToUpArray(parentNode);
rndFind.m_dwStyles = dwSubStyles;
rndFind.m_CurObject = parentNode;
- rnd.m_pSC->GetUpObjectArray()->push_back(parentNode);
- ResolveNormal(rndFind);
- rnd.m_Objects.insert(rnd.m_Objects.end(), rndFind.m_Objects.begin(),
- rndFind.m_Objects.end());
- rndFind.m_Objects.clear();
- if (rnd.m_Objects.size() > nNum)
+ ResolveNormal(pIsolate, rndFind);
+ rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
+ rndFind.m_Result.objects.begin(),
+ rndFind.m_Result.objects.end());
+ rndFind.m_Result.objects.clear();
+ if (rnd.m_Result.objects.size() > nNum)
return true;
}
return false;
}
-bool CFXJSE_ResolveProcessor::ResolveAsterisk(CFXJSE_ResolveNodeData& rnd) {
- CXFA_Node* curNode = ToNode(rnd.m_CurObject.Get());
+bool CFXJSE_ResolveProcessor::ResolveAsterisk(NodeData& rnd) {
+ CXFA_Node* curNode = ToNode(rnd.m_CurObject);
std::vector<CXFA_Node*> array = curNode->GetNodeListWithFilter(
- XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties);
- rnd.m_Objects.insert(rnd.m_Objects.end(), array.begin(), array.end());
- return !rnd.m_Objects.empty();
+ {XFA_NodeFilter::kChildren, XFA_NodeFilter::kProperties});
+ rnd.m_Result.objects.insert(rnd.m_Result.objects.end(), array.begin(),
+ array.end());
+ return !rnd.m_Result.objects.empty();
}
int32_t CFXJSE_ResolveProcessor::GetFilter(WideStringView wsExpression,
int32_t nStart,
- CFXJSE_ResolveNodeData& rnd) {
- ASSERT(nStart > -1);
+ NodeData& rnd) {
+ DCHECK(nStart > -1);
int32_t iLength = wsExpression.GetLength();
if (nStart >= iLength)
@@ -541,7 +528,7 @@
wCur = pSrc[nStart++];
if (wCur == '.') {
if (nNameCount == 0) {
- rnd.m_dwStyles |= XFA_RESOLVENODE_AnyChild;
+ rnd.m_dwStyles |= XFA_ResolveFlag::kAnyChild;
continue;
}
if (wPrev == '\\') {
@@ -589,14 +576,14 @@
wsName.Trim();
wsCondition.Trim();
rnd.m_uHashName =
- static_cast<XFA_HashCode>(FX_HashCode_GetW(wsName.AsStringView(), false));
+ static_cast<XFA_HashCode>(FX_HashCode_GetW(wsName.AsStringView()));
return nStart;
}
void CFXJSE_ResolveProcessor::ConditionArray(size_t iCurIndex,
WideString wsCondition,
size_t iFoundCount,
- CFXJSE_ResolveNodeData* pRnd) {
+ NodeData* pRnd) {
size_t iLen = wsCondition.GetLength();
bool bRelative = false;
bool bAll = false;
@@ -613,18 +600,18 @@
break;
}
if (bAll) {
- if (pRnd->m_dwStyles & XFA_RESOLVENODE_CreateNode) {
- if (pRnd->m_dwStyles & XFA_RESOLVENODE_Bind) {
- m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject.Get());
+ if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
+ if (pRnd->m_dwStyles & XFA_ResolveFlag::kBind) {
+ m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject);
m_pNodeHelper->m_iCreateCount = 1;
- pRnd->m_Objects.clear();
+ pRnd->m_Result.objects.clear();
m_pNodeHelper->m_iCurAllStart = -1;
m_pNodeHelper->m_pAllStartParent = nullptr;
} else if (m_pNodeHelper->m_iCurAllStart == -1) {
m_pNodeHelper->m_iCurAllStart = m_iCurStart;
- m_pNodeHelper->m_pAllStartParent = ToNode(pRnd->m_CurObject.Get());
+ m_pNodeHelper->m_pAllStartParent = ToNode(pRnd->m_CurObject);
}
- } else if (pRnd->m_dwStyles & XFA_RESOLVENODE_BindNew) {
+ } else if (pRnd->m_dwStyles & XFA_ResolveFlag::kBindNew) {
if (m_pNodeHelper->m_iCurAllStart == -1)
m_pNodeHelper->m_iCurAllStart = m_iCurStart;
}
@@ -638,51 +625,51 @@
iIndex += iCurIndex;
if (iIndex < 0 || static_cast<size_t>(iIndex) >= iFoundCount) {
- if (pRnd->m_dwStyles & XFA_RESOLVENODE_CreateNode) {
- m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject.Get());
+ if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
+ m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject);
m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1;
}
- pRnd->m_Objects.clear();
+ pRnd->m_Result.objects.clear();
} else {
- pRnd->m_Objects =
- std::vector<UnownedPtr<CXFA_Object>>(1, pRnd->m_Objects[iIndex]);
+ pRnd->m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
+ 1, pRnd->m_Result.objects[iIndex]);
}
}
-void CFXJSE_ResolveProcessor::FilterCondition(WideString wsCondition,
- CFXJSE_ResolveNodeData* pRnd) {
+void CFXJSE_ResolveProcessor::FilterCondition(v8::Isolate* pIsolate,
+ WideString wsCondition,
+ NodeData* pRnd) {
size_t iCurIndex = 0;
- const std::vector<CXFA_Node*>* pArray = pRnd->m_pSC->GetUpObjectArray();
- if (!pArray->empty()) {
- CXFA_Node* pNode = pArray->back();
- bool bIsProperty = pNode->IsProperty();
- bool bIsClassIndex =
+ CXFA_Node* pNode = m_pEngine->LastObjectFromUpArray();
+ if (pNode) {
+ const bool bIsProperty = pNode->IsProperty();
+ const bool bIsClassIndex =
pNode->IsUnnamed() ||
(bIsProperty && pNode->GetElementType() != XFA_Element::PageSet);
iCurIndex = pNode->GetIndex(bIsProperty, bIsClassIndex);
}
- size_t iFoundCount = pRnd->m_Objects.size();
+ size_t iFoundCount = pRnd->m_Result.objects.size();
wsCondition.Trim();
- int32_t iLen = wsCondition.GetLength();
- if (!iLen) {
- if (pRnd->m_dwStyles & XFA_RESOLVENODE_ALL)
+ const size_t nLen = wsCondition.GetLength();
+ if (nLen == 0) {
+ if (pRnd->m_dwStyles & XFA_ResolveFlag::kALL)
return;
if (iFoundCount == 1)
return;
if (iFoundCount <= iCurIndex) {
- if (pRnd->m_dwStyles & XFA_RESOLVENODE_CreateNode) {
- m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject.Get());
+ if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
+ m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject);
m_pNodeHelper->m_iCreateCount = iCurIndex - iFoundCount + 1;
}
- pRnd->m_Objects.clear();
+ pRnd->m_Result.objects.clear();
return;
}
- pRnd->m_Objects =
- std::vector<UnownedPtr<CXFA_Object>>(1, pRnd->m_Objects[iCurIndex]);
+ pRnd->m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
+ 1, pRnd->m_Result.objects[iCurIndex]);
return;
}
@@ -692,8 +679,8 @@
ConditionArray(iCurIndex, wsCondition, iFoundCount, pRnd);
return;
case '.':
- if (iLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '('))
- DoPredicateFilter(wsCondition, iFoundCount, pRnd);
+ if (nLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '('))
+ DoPredicateFilter(pIsolate, wsCondition, iFoundCount, pRnd);
return;
case '(':
case '"':
@@ -702,34 +689,50 @@
}
}
-void CFXJSE_ResolveProcessor::SetStylesForChild(uint32_t dwParentStyles,
- CFXJSE_ResolveNodeData& rnd) {
- uint32_t dwSubStyles = XFA_RESOLVENODE_Children;
- if (dwParentStyles & XFA_RESOLVENODE_TagName)
- dwSubStyles |= XFA_RESOLVENODE_TagName;
-
- dwSubStyles &= ~XFA_RESOLVENODE_Parent;
- dwSubStyles &= ~XFA_RESOLVENODE_Siblings;
- dwSubStyles &= ~XFA_RESOLVENODE_Properties;
- dwSubStyles |= XFA_RESOLVENODE_ALL;
+void CFXJSE_ResolveProcessor::SetStylesForChild(
+ Mask<XFA_ResolveFlag> dwParentStyles,
+ NodeData& rnd) {
+ Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kChildren,
+ XFA_ResolveFlag::kALL};
+ if (dwParentStyles & XFA_ResolveFlag::kTagName)
+ dwSubStyles |= XFA_ResolveFlag::kTagName;
rnd.m_dwStyles = dwSubStyles;
}
-void CFXJSE_ResolveProcessor::SetIndexDataBind(WideString& wsNextCondition,
- int32_t& iIndex,
- int32_t iCount) {
- if (m_pNodeHelper->CreateNodeForCondition(wsNextCondition)) {
- if (m_pNodeHelper->m_eLastCreateType == XFA_Element::DataGroup) {
- iIndex = 0;
- } else {
- iIndex = iCount - 1;
- }
- } else {
- iIndex = iCount - 1;
+int32_t CFXJSE_ResolveProcessor::IndexForDataBind(
+ const WideString& wsNextCondition,
+ int32_t iCount) {
+ if (m_pNodeHelper->CreateNodeForCondition(wsNextCondition) &&
+ m_pNodeHelper->m_eLastCreateType == XFA_Element::DataGroup) {
+ return 0;
+ }
+ return iCount - 1;
+}
+
+void CFXJSE_ResolveProcessor::DoPredicateFilter(v8::Isolate* pIsolate,
+ WideString wsCondition,
+ size_t iFoundCount,
+ NodeData* pRnd) {
+ DCHECK_EQ(iFoundCount, pRnd->m_Result.objects.size());
+ CXFA_Script::Type eLangType = CXFA_Script::Type::Unknown;
+ if (wsCondition.First(2).EqualsASCII(".[") && wsCondition.Back() == L']')
+ eLangType = CXFA_Script::Type::Formcalc;
+ else if (wsCondition.First(2).EqualsASCII(".(") && wsCondition.Back() == L')')
+ eLangType = CXFA_Script::Type::Javascript;
+ else
+ return;
+
+ WideString wsExpression = wsCondition.Substr(2, wsCondition.GetLength() - 3);
+ for (size_t i = iFoundCount; i > 0; --i) {
+ auto pRetValue = std::make_unique<CFXJSE_Value>();
+ bool bRet = m_pEngine->RunScript(eLangType, wsExpression.AsStringView(),
+ pRetValue.get(),
+ pRnd->m_Result.objects[i - 1].Get());
+ if (!bRet || !pRetValue->ToBoolean(pIsolate))
+ pRnd->m_Result.objects.erase(pRnd->m_Result.objects.begin() + i - 1);
}
}
-CFXJSE_ResolveNodeData::CFXJSE_ResolveNodeData(CFXJSE_Engine* pSC)
- : m_pSC(pSC) {}
+CFXJSE_ResolveProcessor::NodeData::NodeData() = default;
-CFXJSE_ResolveNodeData::~CFXJSE_ResolveNodeData() = default;
+CFXJSE_ResolveProcessor::NodeData::~NodeData() = default;
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.h b/fxjs/xfa/cfxjse_resolveprocessor.h
index 6e4fcba..f7125c9 100644
--- a/fxjs/xfa/cfxjse_resolveprocessor.h
+++ b/fxjs/xfa/cfxjse_resolveprocessor.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,69 +8,69 @@
#define FXJS_XFA_CFXJSE_RESOLVEPROCESSOR_H_
#include <memory>
-#include <vector>
-#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/unowned_ptr.h"
+#include "core/fxcrt/widestring.h"
#include "fxjs/xfa/cfxjse_engine.h"
+#include "v8/include/cppgc/macros.h"
#include "xfa/fxfa/fxfa_basic.h"
#include "xfa/fxfa/parser/xfa_basic_data.h"
-#include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
-class CXFA_NodeHelper;
-
-class CFXJSE_ResolveNodeData {
- public:
- explicit CFXJSE_ResolveNodeData(CFXJSE_Engine* pSC);
- ~CFXJSE_ResolveNodeData();
-
- UnownedPtr<CFXJSE_Engine> const m_pSC;
- UnownedPtr<CXFA_Object> m_CurObject;
- WideString m_wsName;
- WideString m_wsCondition;
- XFA_HashCode m_uHashName = XFA_HASHCODE_None;
- int32_t m_nLevel = 0;
- uint32_t m_dwStyles = XFA_RESOLVENODE_Children;
- XFA_ResolveNode_RSType m_dwFlag = XFA_ResolveNode_RSType_Nodes;
- std::vector<UnownedPtr<CXFA_Object>> m_Objects;
- XFA_SCRIPTATTRIBUTEINFO m_ScriptAttribute;
-};
+class CFXJSE_NodeHelper;
class CFXJSE_ResolveProcessor {
public:
- CFXJSE_ResolveProcessor();
+ class NodeData {
+ CPPGC_STACK_ALLOCATED(); // Allows Raw/Unowned pointers.
+
+ public:
+ NodeData();
+ ~NodeData();
+
+ UnownedPtr<CXFA_Object> m_CurObject; // Ok, stack-only.
+ WideString m_wsName;
+ WideString m_wsCondition;
+ XFA_HashCode m_uHashName = XFA_HASHCODE_None;
+ int32_t m_nLevel = 0;
+ Mask<XFA_ResolveFlag> m_dwStyles = XFA_ResolveFlag::kChildren;
+ CFXJSE_Engine::ResolveResult m_Result;
+ };
+
+ CFXJSE_ResolveProcessor(CFXJSE_Engine* pEngine, CFXJSE_NodeHelper* pHelper);
~CFXJSE_ResolveProcessor();
- bool Resolve(CFXJSE_ResolveNodeData& rnd);
- int32_t GetFilter(WideStringView wsExpression,
- int32_t nStart,
- CFXJSE_ResolveNodeData& rnd);
- void SetIndexDataBind(WideString& wsNextCondition,
- int32_t& iIndex,
- int32_t iCount);
+ bool Resolve(v8::Isolate* pIsolate, NodeData& rnd);
+ int32_t GetFilter(WideStringView wsExpression, int32_t nStart, NodeData& rnd);
+ int32_t IndexForDataBind(const WideString& wsNextCondition, int32_t iCount);
void SetCurStart(int32_t start) { m_iCurStart = start; }
- CXFA_NodeHelper* GetNodeHelper() { return m_pNodeHelper.get(); }
-
private:
bool ResolveForAttributeRs(CXFA_Object* curNode,
- CFXJSE_ResolveNodeData& rnd,
+ CFXJSE_Engine::ResolveResult* rnd,
WideStringView strAttr);
- bool ResolveAnyChild(CFXJSE_ResolveNodeData& rnd);
- bool ResolveDollar(CFXJSE_ResolveNodeData& rnd);
- bool ResolveExcalmatory(CFXJSE_ResolveNodeData& rnd);
- bool ResolveNumberSign(CFXJSE_ResolveNodeData& rnd);
- bool ResolveAsterisk(CFXJSE_ResolveNodeData& rnd);
- bool ResolveNormal(CFXJSE_ResolveNodeData& rnd);
- void SetStylesForChild(uint32_t dwParentStyles, CFXJSE_ResolveNodeData& rnd);
+ bool ResolveAnyChild(v8::Isolate* pIsolate, NodeData& rnd);
+ bool ResolveDollar(v8::Isolate* pIsolate, NodeData& rnd);
+ bool ResolveExcalmatory(v8::Isolate* pIsolate, NodeData& rnd);
+ bool ResolveNumberSign(v8::Isolate* pIsolate, NodeData& rnd);
+ bool ResolveAsterisk(NodeData& rnd);
+ bool ResolveNormal(v8::Isolate* pIsolate, NodeData& rnd);
+ void SetStylesForChild(Mask<XFA_ResolveFlag> dwParentStyles, NodeData& rnd);
void ConditionArray(size_t iCurIndex,
WideString wsCondition,
size_t iFoundCount,
- CFXJSE_ResolveNodeData* pRnd);
- void FilterCondition(WideString wsCondition, CFXJSE_ResolveNodeData* pRnd);
+ NodeData* pRnd);
+ void FilterCondition(v8::Isolate* pIsolate,
+ WideString wsCondition,
+ NodeData* pRnd);
+ void DoPredicateFilter(v8::Isolate* pIsolate,
+ WideString wsCondition,
+ size_t iFoundCount,
+ NodeData* pRnd);
int32_t m_iCurStart = 0;
- std::unique_ptr<CXFA_NodeHelper> const m_pNodeHelper;
+ UnownedPtr<CFXJSE_Engine> const m_pEngine;
+ UnownedPtr<CFXJSE_NodeHelper> const m_pNodeHelper;
};
#endif // FXJS_XFA_CFXJSE_RESOLVEPROCESSOR_H_
diff --git a/fxjs/xfa/cfxjse_runtimedata.cpp b/fxjs/xfa/cfxjse_runtimedata.cpp
index 0478e3e..b6a24c4 100644
--- a/fxjs/xfa/cfxjse_runtimedata.cpp
+++ b/fxjs/xfa/cfxjse_runtimedata.cpp
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,7 +9,15 @@
#include <utility>
#include "fxjs/cfxjs_engine.h"
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_isolatetracker.h"
+#include "third_party/base/check_op.h"
+#include "v8/include/v8-context.h"
+#include "v8/include/v8-external.h"
+#include "v8/include/v8-isolate.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-primitive.h"
+#include "v8/include/v8-template.h"
CFXJSE_RuntimeData::CFXJSE_RuntimeData() = default;
@@ -19,25 +27,21 @@
v8::Isolate* pIsolate) {
std::unique_ptr<CFXJSE_RuntimeData> pRuntimeData(new CFXJSE_RuntimeData());
CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
-
v8::Local<v8::FunctionTemplate> hFuncTemplate =
v8::FunctionTemplate::New(pIsolate);
v8::Local<v8::ObjectTemplate> hGlobalTemplate =
hFuncTemplate->InstanceTemplate();
- hGlobalTemplate->Set(
- v8::Symbol::GetToStringTag(pIsolate),
- v8::String::NewFromUtf8(pIsolate, "global", v8::NewStringType::kNormal)
- .ToLocalChecked());
+ hGlobalTemplate->Set(v8::Symbol::GetToStringTag(pIsolate),
+ fxv8::NewStringHelper(pIsolate, "global"));
v8::Local<v8::Context> hContext =
v8::Context::New(pIsolate, 0, hGlobalTemplate);
- ASSERT(hContext->Global()->InternalFieldCount() == 0);
- ASSERT(hContext->Global()
- ->GetPrototype()
- .As<v8::Object>()
- ->InternalFieldCount() == 0);
+ DCHECK_EQ(hContext->Global()->InternalFieldCount(), 0);
+ DCHECK_EQ(
+ hContext->Global()->GetPrototype().As<v8::Object>()->InternalFieldCount(),
+ 0);
hContext->SetSecurityToken(v8::External::New(pIsolate, pIsolate));
pRuntimeData->m_hRootContextGlobalTemplate.Reset(pIsolate, hFuncTemplate);
@@ -47,9 +51,8 @@
CFXJSE_RuntimeData* CFXJSE_RuntimeData::Get(v8::Isolate* pIsolate) {
FXJS_PerIsolateData::SetUp(pIsolate);
-
FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate);
- if (!pData->m_pFXJSERuntimeData)
- pData->m_pFXJSERuntimeData = CFXJSE_RuntimeData::Create(pIsolate);
- return static_cast<CFXJSE_RuntimeData*>(pData->m_pFXJSERuntimeData.get());
+ if (!pData->GetExtension())
+ pData->SetExtension(CFXJSE_RuntimeData::Create(pIsolate));
+ return static_cast<CFXJSE_RuntimeData*>(pData->GetExtension());
}
diff --git a/fxjs/xfa/cfxjse_runtimedata.h b/fxjs/xfa/cfxjse_runtimedata.h
index 148b01e..67925a0 100644
--- a/fxjs/xfa/cfxjse_runtimedata.h
+++ b/fxjs/xfa/cfxjse_runtimedata.h
@@ -1,4 +1,4 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
+// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,25 +10,26 @@
#include <memory>
#include "fxjs/cfxjs_engine.h"
-#include "v8/include/v8.h"
+#include "v8/include/v8-forward.h"
+#include "v8/include/v8-persistent-handle.h"
-class CFXJSE_RuntimeData : public FXJS_PerIsolateData::ExtensionIface {
+class CFXJSE_RuntimeData final : public FXJS_PerIsolateData::ExtensionIface {
public:
+ CFXJSE_RuntimeData(const CFXJSE_RuntimeData&) = delete;
+ CFXJSE_RuntimeData& operator=(const CFXJSE_RuntimeData&) = delete;
~CFXJSE_RuntimeData() override;
static CFXJSE_RuntimeData* Get(v8::Isolate* pIsolate);
- v8::Global<v8::FunctionTemplate> m_hRootContextGlobalTemplate;
- v8::Global<v8::Context> m_hRootContext;
-
- protected:
- CFXJSE_RuntimeData();
-
- static std::unique_ptr<CFXJSE_RuntimeData> Create(v8::Isolate* pIsolate);
+ const v8::Global<v8::Context>& GetRootContext() { return m_hRootContext; }
private:
- CFXJSE_RuntimeData(const CFXJSE_RuntimeData&) = delete;
- CFXJSE_RuntimeData& operator=(const CFXJSE_RuntimeData&) = delete;
+ static std::unique_ptr<CFXJSE_RuntimeData> Create(v8::Isolate* pIsolate);
+
+ CFXJSE_RuntimeData();
+
+ v8::Global<v8::FunctionTemplate> m_hRootContextGlobalTemplate;
+ v8::Global<v8::Context> m_hRootContext;
};
#endif // FXJS_XFA_CFXJSE_RUNTIMEDATA_H_
diff --git a/fxjs/xfa/cfxjse_value.cpp b/fxjs/xfa/cfxjse_value.cpp
index 1d4cec4..112a648 100644
--- a/fxjs/xfa/cfxjse_value.cpp
+++ b/fxjs/xfa/cfxjse_value.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,9 +8,16 @@
#include <math.h>
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_class.h"
#include "fxjs/xfa/cfxjse_context.h"
#include "fxjs/xfa/cfxjse_isolatetracker.h"
+#include "third_party/base/check.h"
+#include "v8/include/v8-container.h"
+#include "v8/include/v8-exception.h"
+#include "v8/include/v8-function.h"
+#include "v8/include/v8-primitive.h"
+#include "v8/include/v8-script.h"
namespace {
@@ -26,15 +33,18 @@
if (nErrExp >= 0)
return fNumber;
- double dwError = pow(2.0, nErrExp), dwErrorHalf = dwError / 2;
- double dNumber = fNumber, dNumberAbs = fabs(fNumber);
- double dNumberAbsMin = dNumberAbs - dwErrorHalf,
- dNumberAbsMax = dNumberAbs + dwErrorHalf;
+ double dwError = pow(2.0, nErrExp);
+ double dwErrorHalf = dwError / 2;
+ double dNumber = fNumber;
+ double dNumberAbs = fabs(fNumber);
+ double dNumberAbsMin = dNumberAbs - dwErrorHalf;
+ double dNumberAbsMax = dNumberAbs + dwErrorHalf;
int32_t iErrPos = 0;
if (floor(dNumberAbsMin) == floor(dNumberAbsMax)) {
dNumberAbsMin = fmod(dNumberAbsMin, 1.0);
dNumberAbsMax = fmod(dNumberAbsMax, 1.0);
- int32_t iErrPosMin = 1, iErrPosMax = 38;
+ int32_t iErrPosMin = 1;
+ int32_t iErrPosMax = 38;
do {
int32_t iMid = (iErrPosMin + iErrPosMax) / 2;
double dPow = pow(10.0, iMid);
@@ -53,228 +63,140 @@
} // namespace
-void FXJSE_ThrowMessage(ByteStringView utf8Message) {
- v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
- ASSERT(pIsolate);
-
+void FXJSE_ThrowMessage(v8::Isolate* pIsolate, ByteStringView utf8Message) {
+ DCHECK(pIsolate);
CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
- v8::Local<v8::String> hMessage =
- v8::String::NewFromUtf8(pIsolate, utf8Message.unterminated_c_str(),
- v8::NewStringType::kNormal,
- utf8Message.GetLength())
- .ToLocalChecked();
+ v8::Local<v8::String> hMessage = fxv8::NewStringHelper(pIsolate, utf8Message);
v8::Local<v8::Value> hError = v8::Exception::Error(hMessage);
pIsolate->ThrowException(hError);
}
-CFXJSE_Value::CFXJSE_Value(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {}
+CFXJSE_Value::CFXJSE_Value() = default;
-CFXJSE_Value::~CFXJSE_Value() {}
-
-CFXJSE_HostObject* CFXJSE_Value::ToHostObject() const {
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> pValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
- ASSERT(!pValue.IsEmpty());
- if (!pValue->IsObject())
- return nullptr;
-
- return FXJSE_RetrieveObjectBinding(pValue.As<v8::Object>());
+CFXJSE_Value::CFXJSE_Value(v8::Isolate* pIsolate, v8::Local<v8::Value> value) {
+ ForceSetValue(pIsolate, value);
}
-void CFXJSE_Value::SetHostObject(CFXJSE_HostObject* lpObject,
+CFXJSE_Value::~CFXJSE_Value() = default;
+
+CFXJSE_HostObject* CFXJSE_Value::ToHostObject(v8::Isolate* pIsolate) const {
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ return CFXJSE_HostObject::FromV8(
+ v8::Local<v8::Value>::New(pIsolate, m_hValue));
+}
+
+void CFXJSE_Value::SetHostObject(v8::Isolate* pIsolate,
+ CFXJSE_HostObject* pObject,
CFXJSE_Class* pClass) {
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::FunctionTemplate> hClass =
- v8::Local<v8::FunctionTemplate>::New(GetIsolate(), pClass->m_hTemplate);
- v8::Local<v8::Object> hObject =
- hClass->InstanceTemplate()
- ->NewInstance(GetIsolate()->GetCurrentContext())
- .ToLocalChecked();
- FXJSE_UpdateObjectBinding(hObject, lpObject);
- m_hValue.Reset(GetIsolate(), hObject);
-}
-
-void CFXJSE_Value::ClearHostObject() {
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- FXJSE_ClearObjectBinding(m_hValue.Get(GetIsolate()).As<v8::Object>());
- v8::Local<v8::Value> hValue = v8::Null(GetIsolate());
- m_hValue.Reset(GetIsolate(), hValue);
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ m_hValue.Reset(pIsolate, pObject->NewBoundV8Object(
+ pIsolate, pClass->GetTemplate(pIsolate)));
}
void CFXJSE_Value::SetArray(
+ v8::Isolate* pIsolate,
const std::vector<std::unique_ptr<CFXJSE_Value>>& values) {
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Array> hArrayObject =
- v8::Array::New(GetIsolate(), values.size());
- v8::Local<v8::Context> context = GetIsolate()->GetCurrentContext();
- uint32_t count = 0;
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ std::vector<v8::Local<v8::Value>> local_values;
+ local_values.reserve(values.size());
for (auto& v : values) {
if (v->IsEmpty())
- v->SetUndefined();
- hArrayObject
- ->Set(
- context, count++,
- v8::Local<v8::Value>::New(GetIsolate(), v.get()->DirectGetValue()))
- .FromJust();
+ local_values.push_back(fxv8::NewUndefinedHelper(pIsolate));
+ else
+ local_values.push_back(v->GetValue(pIsolate));
}
- m_hValue.Reset(GetIsolate(), hArrayObject);
+ v8::Local<v8::Array> hArrayObject =
+ v8::Array::New(pIsolate, local_values.data(), local_values.size());
+ m_hValue.Reset(pIsolate, hArrayObject);
}
-void CFXJSE_Value::SetFloat(float fFloat) {
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> pValue = v8::Number::New(GetIsolate(), ftod(fFloat));
- m_hValue.Reset(GetIsolate(), pValue);
+void CFXJSE_Value::SetFloat(v8::Isolate* pIsolate, float fFloat) {
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ m_hValue.Reset(pIsolate, fxv8::NewNumberHelper(pIsolate, ftod(fFloat)));
}
-bool CFXJSE_Value::SetObjectProperty(ByteStringView szPropName,
- CFXJSE_Value* lpPropValue) {
- ASSERT(lpPropValue);
- if (lpPropValue->IsEmpty())
+bool CFXJSE_Value::SetObjectProperty(v8::Isolate* pIsolate,
+ ByteStringView szPropName,
+ CFXJSE_Value* pPropValue) {
+ if (pPropValue->IsEmpty())
return false;
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hObject =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ v8::Local<v8::Value> hObject = GetValue(pIsolate);
if (!hObject->IsObject())
return false;
- v8::Local<v8::String> hPropName =
- v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(),
- v8::NewStringType::kNormal,
- szPropName.GetLength())
- .ToLocalChecked();
- v8::Local<v8::Value> hPropValue =
- v8::Local<v8::Value>::New(GetIsolate(), lpPropValue->DirectGetValue());
- v8::Maybe<bool> result = hObject.As<v8::Object>()->Set(
- GetIsolate()->GetCurrentContext(), hPropName, hPropValue);
- return result.IsJust() && result.FromJust();
+ return fxv8::ReentrantPutObjectPropertyHelper(
+ pIsolate, hObject.As<v8::Object>(), szPropName,
+ pPropValue->GetValue(pIsolate));
}
-bool CFXJSE_Value::GetObjectProperty(ByteStringView szPropName,
- CFXJSE_Value* lpPropValue) {
- ASSERT(lpPropValue);
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hObject =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+bool CFXJSE_Value::GetObjectProperty(v8::Isolate* pIsolate,
+ ByteStringView szPropName,
+ CFXJSE_Value* pPropValue) {
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ v8::Local<v8::Value> hObject = GetValue(pIsolate);
if (!hObject->IsObject())
return false;
- v8::Local<v8::String> hPropName =
- v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(),
- v8::NewStringType::kNormal,
- szPropName.GetLength())
- .ToLocalChecked();
- v8::Local<v8::Value> hPropValue =
- hObject.As<v8::Object>()
- ->Get(GetIsolate()->GetCurrentContext(), hPropName)
- .ToLocalChecked();
- lpPropValue->ForceSetValue(hPropValue);
+ pPropValue->ForceSetValue(
+ pIsolate, fxv8::ReentrantGetObjectPropertyHelper(
+ pIsolate, hObject.As<v8::Object>(), szPropName));
return true;
}
-bool CFXJSE_Value::GetObjectPropertyByIdx(uint32_t uPropIdx,
- CFXJSE_Value* lpPropValue) {
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hObject =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
- if (!hObject->IsObject())
+bool CFXJSE_Value::GetObjectPropertyByIdx(v8::Isolate* pIsolate,
+ uint32_t uPropIdx,
+ CFXJSE_Value* pPropValue) {
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ v8::Local<v8::Value> hObject = GetValue(pIsolate);
+ if (!hObject->IsArray())
return false;
- v8::Local<v8::Value> hPropValue =
- hObject.As<v8::Object>()
- ->Get(GetIsolate()->GetCurrentContext(), uPropIdx)
- .ToLocalChecked();
- lpPropValue->ForceSetValue(hPropValue);
+ pPropValue->ForceSetValue(pIsolate,
+ fxv8::ReentrantGetArrayElementHelper(
+ pIsolate, hObject.As<v8::Array>(), uPropIdx));
return true;
}
-bool CFXJSE_Value::DeleteObjectProperty(ByteStringView szPropName) {
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hObject =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
- if (!hObject->IsObject())
- return false;
-
- v8::Local<v8::String> hPropName =
- v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(),
- v8::NewStringType::kNormal,
- szPropName.GetLength())
- .ToLocalChecked();
- return hObject.As<v8::Object>()
- ->Delete(GetIsolate()->GetCurrentContext(), hPropName)
- .FromJust();
+void CFXJSE_Value::DeleteObjectProperty(v8::Isolate* pIsolate,
+ ByteStringView szPropName) {
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(pIsolate, m_hValue);
+ if (hObject->IsObject()) {
+ fxv8::ReentrantDeleteObjectPropertyHelper(
+ pIsolate, hObject.As<v8::Object>(), szPropName);
+ }
}
-bool CFXJSE_Value::HasObjectOwnProperty(ByteStringView szPropName,
- bool bUseTypeGetter) {
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hObject =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+bool CFXJSE_Value::SetObjectOwnProperty(v8::Isolate* pIsolate,
+ ByteStringView szPropName,
+ CFXJSE_Value* pPropValue) {
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(pIsolate, m_hValue);
if (!hObject->IsObject())
return false;
- v8::Local<v8::String> hKey =
- v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(),
- v8::NewStringType::kNormal,
- szPropName.GetLength())
- .ToLocalChecked();
- return hObject.As<v8::Object>()
- ->HasRealNamedProperty(GetIsolate()->GetCurrentContext(), hKey)
- .FromJust() ||
- (bUseTypeGetter &&
- hObject.As<v8::Object>()
- ->HasOwnProperty(GetIsolate()->GetCurrentContext(), hKey)
- .FromMaybe(false));
-}
-
-bool CFXJSE_Value::SetObjectOwnProperty(ByteStringView szPropName,
- CFXJSE_Value* lpPropValue) {
- ASSERT(lpPropValue);
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hObject =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
- if (!hObject->IsObject())
- return false;
-
- v8::Local<v8::String> hPropName =
- v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(),
- v8::NewStringType::kNormal,
- szPropName.GetLength())
- .ToLocalChecked();
v8::Local<v8::Value> pValue =
- v8::Local<v8::Value>::New(GetIsolate(), lpPropValue->m_hValue);
- return hObject.As<v8::Object>()
- ->DefineOwnProperty(GetIsolate()->GetCurrentContext(), hPropName, pValue)
- .FromMaybe(false);
+ v8::Local<v8::Value>::New(pIsolate, pPropValue->m_hValue);
+ return fxv8::ReentrantSetObjectOwnPropertyHelper(
+ pIsolate, hObject.As<v8::Object>(), szPropName, pValue);
}
-bool CFXJSE_Value::SetFunctionBind(CFXJSE_Value* lpOldFunction,
- CFXJSE_Value* lpNewThis) {
- ASSERT(lpOldFunction);
- ASSERT(lpNewThis);
+v8::Local<v8::Function> CFXJSE_Value::NewBoundFunction(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Function> hOldFunction,
+ v8::Local<v8::Object> hNewThis) {
+ DCHECK(!hOldFunction.IsEmpty());
+ DCHECK(!hNewThis.IsEmpty());
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
+ CFXJSE_ScopeUtil_RootContext scope(pIsolate);
v8::Local<v8::Value> rgArgs[2];
- v8::Local<v8::Value> hOldFunction =
- v8::Local<v8::Value>::New(GetIsolate(), lpOldFunction->DirectGetValue());
- if (hOldFunction.IsEmpty() || !hOldFunction->IsFunction())
- return false;
-
rgArgs[0] = hOldFunction;
- v8::Local<v8::Value> hNewThis =
- v8::Local<v8::Value>::New(GetIsolate(), lpNewThis->DirectGetValue());
- if (hNewThis.IsEmpty())
- return false;
-
rgArgs[1] = hNewThis;
- v8::Local<v8::String> hBinderFuncSource =
- v8::String::NewFromUtf8(GetIsolate(),
- "(function (oldfunction, newthis) { return "
- "oldfunction.bind(newthis); })",
- v8::NewStringType::kNormal)
- .ToLocalChecked();
- v8::Local<v8::Context> hContext = GetIsolate()->GetCurrentContext();
+ v8::Local<v8::String> hBinderFuncSource = fxv8::NewStringHelper(
+ pIsolate, "(function (fn, obj) { return fn.bind(obj); })");
+ v8::Local<v8::Context> hContext = pIsolate->GetCurrentContext();
v8::Local<v8::Function> hBinderFunc =
v8::Script::Compile(hContext, hBinderFuncSource)
.ToLocalChecked()
@@ -284,187 +206,159 @@
v8::Local<v8::Value> hBoundFunction =
hBinderFunc->Call(hContext, hContext->Global(), 2, rgArgs)
.ToLocalChecked();
- if (hBoundFunction.IsEmpty() || !hBoundFunction->IsFunction())
- return false;
+ if (!fxv8::IsFunction(hBoundFunction))
+ return v8::Local<v8::Function>();
- m_hValue.Reset(GetIsolate(), hBoundFunction);
- return true;
+ return hBoundFunction.As<v8::Function>();
+}
+
+v8::Local<v8::Value> CFXJSE_Value::GetValue(v8::Isolate* pIsolate) const {
+ return v8::Local<v8::Value>::New(pIsolate, m_hValue);
}
bool CFXJSE_Value::IsEmpty() const {
return m_hValue.IsEmpty();
}
-bool CFXJSE_Value::IsUndefined() const {
+bool CFXJSE_Value::IsUndefined(v8::Isolate* pIsolate) const {
if (IsEmpty())
return false;
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
return hValue->IsUndefined();
}
-bool CFXJSE_Value::IsNull() const {
+bool CFXJSE_Value::IsNull(v8::Isolate* pIsolate) const {
if (IsEmpty())
return false;
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
return hValue->IsNull();
}
-bool CFXJSE_Value::IsBoolean() const {
+bool CFXJSE_Value::IsBoolean(v8::Isolate* pIsolate) const {
if (IsEmpty())
return false;
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
return hValue->IsBoolean();
}
-bool CFXJSE_Value::IsString() const {
+bool CFXJSE_Value::IsString(v8::Isolate* pIsolate) const {
if (IsEmpty())
return false;
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
return hValue->IsString();
}
-bool CFXJSE_Value::IsNumber() const {
+bool CFXJSE_Value::IsNumber(v8::Isolate* pIsolate) const {
if (IsEmpty())
return false;
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
return hValue->IsNumber();
}
-bool CFXJSE_Value::IsInteger() const {
+bool CFXJSE_Value::IsInteger(v8::Isolate* pIsolate) const {
if (IsEmpty())
return false;
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
return hValue->IsInt32();
}
-bool CFXJSE_Value::IsObject() const {
+bool CFXJSE_Value::IsObject(v8::Isolate* pIsolate) const {
if (IsEmpty())
return false;
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
return hValue->IsObject();
}
-bool CFXJSE_Value::IsArray() const {
+bool CFXJSE_Value::IsArray(v8::Isolate* pIsolate) const {
if (IsEmpty())
return false;
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
return hValue->IsArray();
}
-bool CFXJSE_Value::IsFunction() const {
+bool CFXJSE_Value::IsFunction(v8::Isolate* pIsolate) const {
if (IsEmpty())
return false;
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
return hValue->IsFunction();
}
-bool CFXJSE_Value::ToBoolean() const {
- ASSERT(!IsEmpty());
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
- return hValue->BooleanValue(GetIsolate());
+bool CFXJSE_Value::ToBoolean(v8::Isolate* pIsolate) const {
+ DCHECK(!IsEmpty());
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ return fxv8::ReentrantToBooleanHelper(
+ pIsolate, v8::Local<v8::Value>::New(pIsolate, m_hValue));
}
-float CFXJSE_Value::ToFloat() const {
- ASSERT(!IsEmpty());
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
- return static_cast<float>(
- hValue->NumberValue(GetIsolate()->GetCurrentContext()).FromMaybe(0.0));
+float CFXJSE_Value::ToFloat(v8::Isolate* pIsolate) const {
+ return static_cast<float>(ToDouble(pIsolate));
}
-double CFXJSE_Value::ToDouble() const {
- ASSERT(!IsEmpty());
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
- return hValue->NumberValue(GetIsolate()->GetCurrentContext()).FromMaybe(0.0);
+double CFXJSE_Value::ToDouble(v8::Isolate* pIsolate) const {
+ DCHECK(!IsEmpty());
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ return fxv8::ReentrantToDoubleHelper(
+ pIsolate, v8::Local<v8::Value>::New(pIsolate, m_hValue));
}
-int32_t CFXJSE_Value::ToInteger() const {
- ASSERT(!IsEmpty());
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
- return static_cast<int32_t>(
- hValue->NumberValue(GetIsolate()->GetCurrentContext()).FromMaybe(0.0));
+int32_t CFXJSE_Value::ToInteger(v8::Isolate* pIsolate) const {
+ DCHECK(!IsEmpty());
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ return fxv8::ReentrantToInt32Helper(
+ pIsolate, v8::Local<v8::Value>::New(pIsolate, m_hValue));
}
-ByteString CFXJSE_Value::ToString() const {
- ASSERT(!IsEmpty());
- CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
- v8::Local<v8::String> hString =
- hValue->ToString(GetIsolate()->GetCurrentContext()).ToLocalChecked();
- v8::String::Utf8Value hStringVal(GetIsolate(), hString);
- return ByteString(*hStringVal);
+ByteString CFXJSE_Value::ToString(v8::Isolate* pIsolate) const {
+ DCHECK(!IsEmpty());
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ return fxv8::ReentrantToByteStringHelper(
+ pIsolate, v8::Local<v8::Value>::New(pIsolate, m_hValue));
}
-void CFXJSE_Value::SetUndefined() {
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue = v8::Undefined(GetIsolate());
- m_hValue.Reset(GetIsolate(), hValue);
+void CFXJSE_Value::SetUndefined(v8::Isolate* pIsolate) {
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ m_hValue.Reset(pIsolate, fxv8::NewUndefinedHelper(pIsolate));
}
-void CFXJSE_Value::SetNull() {
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue = v8::Null(GetIsolate());
- m_hValue.Reset(GetIsolate(), hValue);
+void CFXJSE_Value::SetNull(v8::Isolate* pIsolate) {
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ m_hValue.Reset(pIsolate, fxv8::NewNullHelper(pIsolate));
}
-void CFXJSE_Value::SetBoolean(bool bBoolean) {
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue = v8::Boolean::New(GetIsolate(), !!bBoolean);
- m_hValue.Reset(GetIsolate(), hValue);
+void CFXJSE_Value::SetBoolean(v8::Isolate* pIsolate, bool bBoolean) {
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ m_hValue.Reset(pIsolate, fxv8::NewBooleanHelper(pIsolate, bBoolean));
}
-void CFXJSE_Value::SetInteger(int32_t nInteger) {
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue = v8::Integer::New(GetIsolate(), nInteger);
- m_hValue.Reset(GetIsolate(), hValue);
+void CFXJSE_Value::SetInteger(v8::Isolate* pIsolate, int32_t nInteger) {
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ m_hValue.Reset(pIsolate, fxv8::NewNumberHelper(pIsolate, nInteger));
}
-void CFXJSE_Value::SetDouble(double dDouble) {
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue = v8::Number::New(GetIsolate(), dDouble);
- m_hValue.Reset(GetIsolate(), hValue);
+void CFXJSE_Value::SetDouble(v8::Isolate* pIsolate, double dDouble) {
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ m_hValue.Reset(pIsolate, fxv8::NewNumberHelper(pIsolate, dDouble));
}
-void CFXJSE_Value::SetString(ByteStringView szString) {
- CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
- v8::Local<v8::Value> hValue =
- v8::String::NewFromUtf8(GetIsolate(), szString.unterminated_c_str(),
- v8::NewStringType::kNormal, szString.GetLength())
- .ToLocalChecked();
- m_hValue.Reset(GetIsolate(), hValue);
+void CFXJSE_Value::SetString(v8::Isolate* pIsolate, ByteStringView szString) {
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ m_hValue.Reset(pIsolate, fxv8::NewStringHelper(pIsolate, szString));
}
diff --git a/fxjs/xfa/cfxjse_value.h b/fxjs/xfa/cfxjse_value.h
index 44cc58c..b8b6687 100644
--- a/fxjs/xfa/cfxjse_value.h
+++ b/fxjs/xfa/cfxjse_value.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,84 +7,91 @@
#ifndef FXJS_XFA_CFXJSE_VALUE_H_
#define FXJS_XFA_CFXJSE_VALUE_H_
+#include <stdint.h>
+
#include <memory>
#include <vector>
#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/unowned_ptr.h"
-#include "v8/include/v8.h"
+#include "third_party/base/check.h"
+#include "v8/include/v8-forward.h"
+#include "v8/include/v8-persistent-handle.h"
class CFXJSE_Class;
class CFXJSE_HostObject;
class CFXJSE_Value {
public:
- explicit CFXJSE_Value(v8::Isolate* pIsolate);
+ CFXJSE_Value();
+ CFXJSE_Value(v8::Isolate* pIsolate, v8::Local<v8::Value> value);
~CFXJSE_Value();
bool IsEmpty() const;
- bool IsUndefined() const;
- bool IsNull() const;
- bool IsBoolean() const;
- bool IsString() const;
- bool IsNumber() const;
- bool IsInteger() const;
- bool IsObject() const;
- bool IsArray() const;
- bool IsFunction() const;
- bool ToBoolean() const;
- float ToFloat() const;
- double ToDouble() const;
- int32_t ToInteger() const;
- ByteString ToString() const;
- WideString ToWideString() const {
- return WideString::FromUTF8(ToString().AsStringView());
+ bool IsUndefined(v8::Isolate* pIsolate) const;
+ bool IsNull(v8::Isolate* pIsolate) const;
+ bool IsBoolean(v8::Isolate* pIsolate) const;
+ bool IsString(v8::Isolate* pIsolate) const;
+ bool IsNumber(v8::Isolate* pIsolate) const;
+ bool IsInteger(v8::Isolate* pIsolate) const;
+ bool IsObject(v8::Isolate* pIsolate) const;
+ bool IsArray(v8::Isolate* pIsolate) const;
+ bool IsFunction(v8::Isolate* pIsolate) const;
+ bool ToBoolean(v8::Isolate* pIsolate) const;
+ float ToFloat(v8::Isolate* pIsolate) const;
+ double ToDouble(v8::Isolate* pIsolate) const;
+ int32_t ToInteger(v8::Isolate* pIsolate) const;
+ ByteString ToString(v8::Isolate* pIsolate) const;
+ WideString ToWideString(v8::Isolate* pIsolate) const {
+ return WideString::FromUTF8(ToString(pIsolate).AsStringView());
}
- CFXJSE_HostObject* ToHostObject() const;
+ CFXJSE_HostObject* ToHostObject(v8::Isolate* pIsolate) const;
- void SetUndefined();
- void SetNull();
- void SetBoolean(bool bBoolean);
- void SetInteger(int32_t nInteger);
- void SetDouble(double dDouble);
- void SetString(ByteStringView szString);
- void SetFloat(float fFloat);
+ void SetUndefined(v8::Isolate* pIsolate);
+ void SetNull(v8::Isolate* pIsolate);
+ void SetBoolean(v8::Isolate* pIsolate, bool bBoolean);
+ void SetInteger(v8::Isolate* pIsolate, int32_t nInteger);
+ void SetDouble(v8::Isolate* pIsolate, double dDouble);
+ void SetString(v8::Isolate* pIsolate, ByteStringView szString);
+ void SetFloat(v8::Isolate* pIsolate, float fFloat);
- void SetHostObject(CFXJSE_HostObject* lpObject, CFXJSE_Class* pClass);
- void ClearHostObject();
+ void SetHostObject(v8::Isolate* pIsolate,
+ CFXJSE_HostObject* pObject,
+ CFXJSE_Class* pClass);
- void SetArray(const std::vector<std::unique_ptr<CFXJSE_Value>>& values);
+ void SetArray(v8::Isolate* pIsolate,
+ const std::vector<std::unique_ptr<CFXJSE_Value>>& values);
- bool GetObjectProperty(ByteStringView szPropName, CFXJSE_Value* lpPropValue);
- bool SetObjectProperty(ByteStringView szPropName, CFXJSE_Value* lpPropValue);
- bool GetObjectPropertyByIdx(uint32_t uPropIdx, CFXJSE_Value* lpPropValue);
- bool DeleteObjectProperty(ByteStringView szPropName);
- bool HasObjectOwnProperty(ByteStringView szPropName, bool bUseTypeGetter);
- bool SetObjectOwnProperty(ByteStringView szPropName,
- CFXJSE_Value* lpPropValue);
- bool SetFunctionBind(CFXJSE_Value* lpOldFunction, CFXJSE_Value* lpNewThis);
+ bool GetObjectProperty(v8::Isolate* pIsolate,
+ ByteStringView szPropName,
+ CFXJSE_Value* pPropValue);
+ bool SetObjectProperty(v8::Isolate* pIsolate,
+ ByteStringView szPropName,
+ CFXJSE_Value* pPropValue);
+ bool GetObjectPropertyByIdx(v8::Isolate* pIsolate,
+ uint32_t uPropIdx,
+ CFXJSE_Value* pPropValue);
+ void DeleteObjectProperty(v8::Isolate* pIsolate, ByteStringView szPropName);
+ bool SetObjectOwnProperty(v8::Isolate* pIsolate,
+ ByteStringView szPropName,
+ CFXJSE_Value* pPropValue);
- v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); }
+ // Return empty local on error.
+ static v8::Local<v8::Function> NewBoundFunction(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::Function> hOldFunction,
+ v8::Local<v8::Object> lpNewThis);
+
+ v8::Local<v8::Value> GetValue(v8::Isolate* pIsolate) const;
const v8::Global<v8::Value>& DirectGetValue() const { return m_hValue; }
- void ForceSetValue(v8::Local<v8::Value> hValue) {
- m_hValue.Reset(GetIsolate(), hValue);
- }
- void Assign(const CFXJSE_Value* lpValue) {
- ASSERT(lpValue);
- if (lpValue) {
- m_hValue.Reset(GetIsolate(), lpValue->m_hValue);
- } else {
- m_hValue.Reset();
- }
+ void ForceSetValue(v8::Isolate* pIsolate, v8::Local<v8::Value> hValue) {
+ m_hValue.Reset(pIsolate, hValue);
}
private:
- CFXJSE_Value() = delete;
CFXJSE_Value(const CFXJSE_Value&) = delete;
CFXJSE_Value& operator=(const CFXJSE_Value&) = delete;
- UnownedPtr<v8::Isolate> const m_pIsolate;
v8::Global<v8::Value> m_hValue;
};
diff --git a/fxjs/xfa/cfxjse_value_embeddertest.cpp b/fxjs/xfa/cfxjse_value_embeddertest.cpp
index e9c39c1..c1e810b 100644
--- a/fxjs/xfa/cfxjse_value_embeddertest.cpp
+++ b/fxjs/xfa/cfxjse_value_embeddertest.cpp
@@ -1,4 +1,4 @@
-// Copyright 2019 PDFium Authors. All rights reserved.
+// Copyright 2019 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,34 +11,33 @@
#include "fxjs/xfa/cfxjse_engine.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/xfa_js_embedder_test.h"
-#include "third_party/base/ptr_util.h"
class CFXJSE_ValueEmbedderTest : public XFAJSEmbedderTest {};
TEST_F(CFXJSE_ValueEmbedderTest, Empty) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
- auto pValue = pdfium::MakeUnique<CFXJSE_Value>(GetIsolate());
+ auto pValue = std::make_unique<CFXJSE_Value>();
EXPECT_TRUE(pValue->IsEmpty());
- EXPECT_FALSE(pValue->IsUndefined());
- EXPECT_FALSE(pValue->IsNull());
- EXPECT_FALSE(pValue->IsBoolean());
- EXPECT_FALSE(pValue->IsString());
- EXPECT_FALSE(pValue->IsNumber());
- EXPECT_FALSE(pValue->IsObject());
- EXPECT_FALSE(pValue->IsArray());
- EXPECT_FALSE(pValue->IsFunction());
+ EXPECT_FALSE(pValue->IsUndefined(isolate()));
+ EXPECT_FALSE(pValue->IsNull(isolate()));
+ EXPECT_FALSE(pValue->IsBoolean(isolate()));
+ EXPECT_FALSE(pValue->IsString(isolate()));
+ EXPECT_FALSE(pValue->IsNumber(isolate()));
+ EXPECT_FALSE(pValue->IsObject(isolate()));
+ EXPECT_FALSE(pValue->IsArray(isolate()));
+ EXPECT_FALSE(pValue->IsFunction(isolate()));
}
TEST_F(CFXJSE_ValueEmbedderTest, EmptyArrayInsert) {
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
// Test inserting empty values into arrays.
- auto pValue = pdfium::MakeUnique<CFXJSE_Value>(GetIsolate());
+ auto pValue = std::make_unique<CFXJSE_Value>();
std::vector<std::unique_ptr<CFXJSE_Value>> vec;
vec.push_back(std::move(pValue));
- CFXJSE_Value array(GetIsolate());
- array.SetArray(vec);
- EXPECT_TRUE(array.IsArray());
+ CFXJSE_Value array;
+ array.SetArray(isolate(), vec);
+ EXPECT_TRUE(array.IsArray(isolate()));
}
diff --git a/fxjs/xfa/cjx_boolean.cpp b/fxjs/xfa/cjx_boolean.cpp
index d44e039..a7e6f8b 100644
--- a/fxjs/xfa/cjx_boolean.cpp
+++ b/fxjs/xfa/cjx_boolean.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,7 +6,9 @@
#include "fxjs/xfa/cjx_boolean.h"
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/parser/cxfa_boolean.h"
CJX_Boolean::CJX_Boolean(CXFA_Boolean* node) : CJX_Object(node) {}
@@ -17,30 +19,33 @@
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_Boolean::defaultValue(CFXJSE_Value* pValue,
+void CJX_Boolean::defaultValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (!bSetting) {
- pValue->SetBoolean(GetContent(true).EqualsASCII("1"));
+ *pValue =
+ fxv8::NewBooleanHelper(pIsolate, GetContent(true).EqualsASCII("1"));
return;
}
ByteString newValue;
- if (pValue && !(pValue->IsNull() || pValue->IsUndefined()))
- newValue = pValue->ToString();
+ if (pValue && !(fxv8::IsNull(*pValue) || fxv8::IsUndefined(*pValue)))
+ newValue = fxv8::ReentrantToByteStringHelper(pIsolate, *pValue);
int32_t iValue = FXSYS_atoi(newValue.c_str());
WideString wsNewValue(iValue == 0 ? L"0" : L"1");
WideString wsFormatValue(wsNewValue);
- CXFA_Node* pContainerNode = ToNode(GetXFAObject())->GetContainerNode();
+ CXFA_Node* pContainerNode = GetXFANode()->GetContainerNode();
if (pContainerNode)
wsFormatValue = pContainerNode->GetFormatDataValue(wsNewValue);
SetContent(wsNewValue, wsFormatValue, true, true, true);
}
-void CJX_Boolean::value(CFXJSE_Value* pValue,
+void CJX_Boolean::value(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- defaultValue(pValue, bSetting, eAttribute);
+ defaultValue(pIsolate, pValue, bSetting, eAttribute);
}
diff --git a/fxjs/xfa/cjx_boolean.h b/fxjs/xfa/cjx_boolean.h
index d2a85ba..7fc2111 100644
--- a/fxjs/xfa/cjx_boolean.h
+++ b/fxjs/xfa/cjx_boolean.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Boolean final : public CJX_Object {
public:
- explicit CJX_Boolean(CXFA_Boolean* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Boolean() override;
// CJX_Object:
@@ -24,6 +24,8 @@
JSE_PROP(value);
private:
+ explicit CJX_Boolean(CXFA_Boolean* node);
+
using Type__ = CJX_Boolean;
using ParentType__ = CJX_Object;
diff --git a/fxjs/xfa/cjx_container.cpp b/fxjs/xfa/cjx_container.cpp
index 44b1ff8..d6cabac 100644
--- a/fxjs/xfa/cjx_container.cpp
+++ b/fxjs/xfa/cjx_container.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,8 @@
#include "fxjs/xfa/cfxjse_class.h"
#include "fxjs/xfa/cfxjse_engine.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/cppgc/allocation.h"
+#include "v8/include/v8-object.h"
#include "xfa/fxfa/parser/cxfa_arraynodelist.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_field.h"
@@ -23,23 +25,24 @@
DefineMethods(MethodSpecs);
}
-CJX_Container::~CJX_Container() {}
+CJX_Container::~CJX_Container() = default;
bool CJX_Container::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_Container::getDelta(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
CJS_Result CJX_Container::getDeltas(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- auto* pEngine = static_cast<CFXJSE_Engine*>(runtime);
- return CJS_Result::Success(pEngine->NewXFAObject(
- new CXFA_ArrayNodeList(GetDocument()),
- GetDocument()->GetScriptContext()->GetJseNormalClass()->GetTemplate()));
+ CXFA_Document* pDoc = GetDocument();
+ auto* pList = cppgc::MakeGarbageCollected<CXFA_ArrayNodeList>(
+ pDoc->GetHeap()->GetAllocationHandle(), pDoc);
+ pDoc->GetNodeOwner()->PersistList(pList);
+ return CJS_Result::Success(runtime->NewNormalXFAObject(pList));
}
diff --git a/fxjs/xfa/cjx_container.h b/fxjs/xfa/cjx_container.h
index 51675e5..b44dd72 100644
--- a/fxjs/xfa/cjx_container.h
+++ b/fxjs/xfa/cjx_container.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Container : public CJX_Node {
public:
- explicit CJX_Container(CXFA_Node* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Container() override;
// CJX_Object:
@@ -23,6 +23,9 @@
JSE_METHOD(getDelta);
JSE_METHOD(getDeltas);
+ protected:
+ explicit CJX_Container(CXFA_Node* node);
+
private:
using Type__ = CJX_Container;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_datawindow.cpp b/fxjs/xfa/cjx_datawindow.cpp
index d165140..10f8365 100644
--- a/fxjs/xfa/cjx_datawindow.cpp
+++ b/fxjs/xfa/cjx_datawindow.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -22,48 +22,52 @@
DefineMethods(MethodSpecs);
}
-CJX_DataWindow::~CJX_DataWindow() {}
+CJX_DataWindow::~CJX_DataWindow() = default;
bool CJX_DataWindow::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_DataWindow::moveCurrentRecord(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
CJS_Result CJX_DataWindow::record(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
CJS_Result CJX_DataWindow::gotoRecord(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
CJS_Result CJX_DataWindow::isRecordGroup(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
-void CJX_DataWindow::recordsBefore(CFXJSE_Value* pValue,
+void CJX_DataWindow::recordsBefore(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
-void CJX_DataWindow::currentRecordNumber(CFXJSE_Value* pValue,
+void CJX_DataWindow::currentRecordNumber(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
-void CJX_DataWindow::recordsAfter(CFXJSE_Value* pValue,
+void CJX_DataWindow::recordsAfter(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
-void CJX_DataWindow::isDefined(CFXJSE_Value* pValue,
+void CJX_DataWindow::isDefined(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_datawindow.h b/fxjs/xfa/cjx_datawindow.h
index 6f3ad54..df5092d 100644
--- a/fxjs/xfa/cjx_datawindow.h
+++ b/fxjs/xfa/cjx_datawindow.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,12 +11,11 @@
#include "fxjs/xfa/jse_define.h"
#include "xfa/fxfa/fxfa_basic.h"
-class CFXJSE_Value;
class CScript_DataWindow;
class CJX_DataWindow final : public CJX_Object {
public:
- explicit CJX_DataWindow(CScript_DataWindow* window);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_DataWindow() override;
// CJX_Object:
@@ -33,6 +32,8 @@
JSE_PROP(recordsBefore);
private:
+ explicit CJX_DataWindow(CScript_DataWindow* window);
+
using Type__ = CJX_DataWindow;
using ParentType__ = CJX_Object;
diff --git a/fxjs/xfa/cjx_delta.cpp b/fxjs/xfa/cjx_delta.cpp
index 3ad20a6..266ddef 100644
--- a/fxjs/xfa/cjx_delta.cpp
+++ b/fxjs/xfa/cjx_delta.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -18,13 +18,13 @@
DefineMethods(MethodSpecs);
}
-CJX_Delta::~CJX_Delta() {}
+CJX_Delta::~CJX_Delta() = default;
bool CJX_Delta::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-CJS_Result CJX_Delta::restore(CFX_V8* runtime,
+CJS_Result CJX_Delta::restore(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -32,14 +32,17 @@
return CJS_Result::Success();
}
-void CJX_Delta::currentValue(CFXJSE_Value* pValue,
+void CJX_Delta::currentValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
-void CJX_Delta::savedValue(CFXJSE_Value* pValue,
+void CJX_Delta::savedValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
-void CJX_Delta::target(CFXJSE_Value* pValue,
+void CJX_Delta::target(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_delta.h b/fxjs/xfa/cjx_delta.h
index 716dd1e..1862558 100644
--- a/fxjs/xfa/cjx_delta.h
+++ b/fxjs/xfa/cjx_delta.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Delta final : public CJX_Object {
public:
- explicit CJX_Delta(CXFA_Delta* delta);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Delta() override;
// CJX_Object:
@@ -27,6 +27,8 @@
JSE_PROP(target);
private:
+ explicit CJX_Delta(CXFA_Delta* delta);
+
using Type__ = CJX_Delta;
using ParentType__ = CJX_Object;
diff --git a/fxjs/xfa/cjx_desc.cpp b/fxjs/xfa/cjx_desc.cpp
index 2bbff2b..792f076 100644
--- a/fxjs/xfa/cjx_desc.cpp
+++ b/fxjs/xfa/cjx_desc.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include "fxjs/cfx_v8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/parser/cxfa_desc.h"
const CJX_MethodSpec CJX_Desc::MethodSpecs[] = {{"metadata", metadata_static}};
@@ -19,13 +20,13 @@
DefineMethods(MethodSpecs);
}
-CJX_Desc::~CJX_Desc() {}
+CJX_Desc::~CJX_Desc() = default;
bool CJX_Desc::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-CJS_Result CJX_Desc::metadata(CFX_V8* runtime,
+CJS_Result CJX_Desc::metadata(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 0 && params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
diff --git a/fxjs/xfa/cjx_desc.h b/fxjs/xfa/cjx_desc.h
index 62cdec8..5474d56 100644
--- a/fxjs/xfa/cjx_desc.h
+++ b/fxjs/xfa/cjx_desc.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Desc final : public CJX_Node {
public:
- explicit CJX_Desc(CXFA_Desc* desc);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Desc() override;
// CJX_Object:
@@ -23,6 +23,8 @@
JSE_METHOD(metadata);
private:
+ explicit CJX_Desc(CXFA_Desc* desc);
+
using Type__ = CJX_Desc;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_draw.cpp b/fxjs/xfa/cjx_draw.cpp
index 4e8ddc1..82307b0 100644
--- a/fxjs/xfa/cjx_draw.cpp
+++ b/fxjs/xfa/cjx_draw.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,7 +6,11 @@
#include "fxjs/xfa/cjx_draw.h"
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "third_party/base/check.h"
+#include "v8/include/v8-primitive.h"
+#include "v8/include/v8-value.h"
#include "xfa/fxfa/parser/cxfa_draw.h"
CJX_Draw::CJX_Draw(CXFA_Draw* node) : CJX_Container(node) {}
@@ -17,32 +21,33 @@
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_Draw::rawValue(CFXJSE_Value* pValue,
+void CJX_Draw::rawValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- defaultValue(pValue, bSetting, eAttribute);
+ defaultValue(pIsolate, pValue, bSetting, eAttribute);
}
-void CJX_Draw::defaultValue(CFXJSE_Value* pValue,
+void CJX_Draw::defaultValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (!bSetting) {
- WideString content = GetContent(true);
- if (content.IsEmpty())
- pValue->SetNull();
- else
- pValue->SetString(content.ToUTF8().AsStringView());
-
+ ByteString content = GetContent(true).ToUTF8();
+ *pValue = content.IsEmpty()
+ ? fxv8::NewNullHelper(pIsolate).As<v8::Value>()
+ : fxv8::NewStringHelper(pIsolate, content.AsStringView())
+ .As<v8::Value>();
return;
}
- if (!pValue || !pValue->IsString())
+ if (!pValue || !fxv8::IsString(*pValue))
return;
- ASSERT(GetXFANode()->IsWidgetReady());
+ DCHECK(GetXFANode()->IsWidgetReady());
if (GetXFANode()->GetFFWidgetType() != XFA_FFWidgetType::kText)
return;
- WideString wsNewValue = pValue->ToWideString();
+ WideString wsNewValue = fxv8::ReentrantToWideStringHelper(pIsolate, *pValue);
SetContent(wsNewValue, wsNewValue, true, true, true);
}
diff --git a/fxjs/xfa/cjx_draw.h b/fxjs/xfa/cjx_draw.h
index bf3c3a7..a813f15 100644
--- a/fxjs/xfa/cjx_draw.h
+++ b/fxjs/xfa/cjx_draw.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Draw final : public CJX_Container {
public:
- explicit CJX_Draw(CXFA_Draw* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Draw() override;
// CJX_Object:
@@ -24,6 +24,8 @@
JSE_PROP(rawValue);
private:
+ explicit CJX_Draw(CXFA_Draw* node);
+
using Type__ = CJX_Draw;
using ParentType__ = CJX_Container;
diff --git a/fxjs/xfa/cjx_encrypt.cpp b/fxjs/xfa/cjx_encrypt.cpp
index f50133d..51e02d6 100644
--- a/fxjs/xfa/cjx_encrypt.cpp
+++ b/fxjs/xfa/cjx_encrypt.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,6 +16,7 @@
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_Encrypt::format(CFXJSE_Value* pValue,
+void CJX_Encrypt::format(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_encrypt.h b/fxjs/xfa/cjx_encrypt.h
index 826bc1f..c7d4a46 100644
--- a/fxjs/xfa/cjx_encrypt.h
+++ b/fxjs/xfa/cjx_encrypt.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Encrypt final : public CJX_Node {
public:
- explicit CJX_Encrypt(CXFA_Encrypt* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Encrypt() override;
// CJX_Object:
@@ -23,6 +23,8 @@
JSE_PROP(format);
private:
+ explicit CJX_Encrypt(CXFA_Encrypt* node);
+
using Type__ = CJX_Encrypt;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_eventpseudomodel.cpp b/fxjs/xfa/cjx_eventpseudomodel.cpp
index d037eb7..72309dc 100644
--- a/fxjs/xfa/cjx_eventpseudomodel.cpp
+++ b/fxjs/xfa/cjx_eventpseudomodel.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,37 +9,48 @@
#include <algorithm>
#include <vector>
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "third_party/base/notreached.h"
+#include "third_party/base/numerics/safe_conversions.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
-#include "xfa/fxfa/cxfa_ffwidgethandler.h"
#include "xfa/fxfa/parser/cscript_eventpseudomodel.h"
namespace {
-void StringProperty(CFXJSE_Value* pReturn, WideString* wsValue, bool bSetting) {
+void StringProperty(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pReturn,
+ WideString* wsValue,
+ bool bSetting) {
if (bSetting) {
- *wsValue = pReturn->ToWideString();
+ *wsValue = fxv8::ReentrantToWideStringHelper(pIsolate, *pReturn);
return;
}
- pReturn->SetString(wsValue->ToUTF8().AsStringView());
+ *pReturn = fxv8::NewStringHelper(pIsolate, wsValue->ToUTF8().AsStringView());
}
-void IntegerProperty(CFXJSE_Value* pReturn, int32_t* iValue, bool bSetting) {
+void IntegerProperty(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pReturn,
+ int32_t* iValue,
+ bool bSetting) {
if (bSetting) {
- *iValue = pReturn->ToInteger();
+ *iValue = fxv8::ReentrantToInt32Helper(pIsolate, *pReturn);
return;
}
- pReturn->SetInteger(*iValue);
+ *pReturn = fxv8::NewNumberHelper(pIsolate, *iValue);
}
-void BooleanProperty(CFXJSE_Value* pReturn, bool* bValue, bool bSetting) {
+void BooleanProperty(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pReturn,
+ bool* bValue,
+ bool bSetting) {
if (bSetting) {
- *bValue = pReturn->ToBoolean();
+ *bValue = fxv8::ReentrantToBooleanHelper(pIsolate, *pReturn);
return;
}
- pReturn->SetBoolean(*bValue);
+ *pReturn = fxv8::NewBooleanHelper(pIsolate, *bValue);
}
} // namespace
@@ -53,55 +64,63 @@
DefineMethods(MethodSpecs);
}
-CJX_EventPseudoModel::~CJX_EventPseudoModel() {}
+CJX_EventPseudoModel::~CJX_EventPseudoModel() = default;
bool CJX_EventPseudoModel::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_EventPseudoModel::cancelAction(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::cancelAction(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::CancelAction, bSetting);
+ Property(pIsolate, pValue, XFA_Event::CancelAction, bSetting);
}
-void CJX_EventPseudoModel::change(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::change(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::Change, bSetting);
+ Property(pIsolate, pValue, XFA_Event::Change, bSetting);
}
-void CJX_EventPseudoModel::commitKey(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::commitKey(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::CommitKey, bSetting);
+ Property(pIsolate, pValue, XFA_Event::CommitKey, bSetting);
}
-void CJX_EventPseudoModel::fullText(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::fullText(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::FullText, bSetting);
+ Property(pIsolate, pValue, XFA_Event::FullText, bSetting);
}
-void CJX_EventPseudoModel::keyDown(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::keyDown(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::Keydown, bSetting);
+ Property(pIsolate, pValue, XFA_Event::Keydown, bSetting);
}
-void CJX_EventPseudoModel::modifier(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::modifier(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::Modifier, bSetting);
+ Property(pIsolate, pValue, XFA_Event::Modifier, bSetting);
}
-void CJX_EventPseudoModel::newContentType(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::newContentType(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::NewContentType, bSetting);
+ Property(pIsolate, pValue, XFA_Event::NewContentType, bSetting);
}
-void CJX_EventPseudoModel::newText(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::newText(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting)
@@ -112,65 +131,75 @@
if (!pEventParam)
return;
- pValue->SetString(pEventParam->GetNewText().ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(
+ pIsolate, pEventParam->GetNewText().ToUTF8().AsStringView());
}
-void CJX_EventPseudoModel::prevContentType(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::prevContentType(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::PreviousContentType, bSetting);
+ Property(pIsolate, pValue, XFA_Event::PreviousContentType, bSetting);
}
-void CJX_EventPseudoModel::prevText(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::prevText(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::PreviousText, bSetting);
+ Property(pIsolate, pValue, XFA_Event::PreviousText, bSetting);
}
-void CJX_EventPseudoModel::reenter(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::reenter(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::Reenter, bSetting);
+ Property(pIsolate, pValue, XFA_Event::Reenter, bSetting);
}
-void CJX_EventPseudoModel::selEnd(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::selEnd(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::SelectionEnd, bSetting);
+ Property(pIsolate, pValue, XFA_Event::SelectionEnd, bSetting);
}
-void CJX_EventPseudoModel::selStart(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::selStart(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::SelectionStart, bSetting);
+ Property(pIsolate, pValue, XFA_Event::SelectionStart, bSetting);
}
-void CJX_EventPseudoModel::shift(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::shift(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::Shift, bSetting);
+ Property(pIsolate, pValue, XFA_Event::Shift, bSetting);
}
-void CJX_EventPseudoModel::soapFaultCode(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::soapFaultCode(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::SoapFaultCode, bSetting);
+ Property(pIsolate, pValue, XFA_Event::SoapFaultCode, bSetting);
}
-void CJX_EventPseudoModel::soapFaultString(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::soapFaultString(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::SoapFaultString, bSetting);
+ Property(pIsolate, pValue, XFA_Event::SoapFaultString, bSetting);
}
-void CJX_EventPseudoModel::target(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::target(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- Property(pValue, XFA_Event::Target, bSetting);
+ Property(pIsolate, pValue, XFA_Event::Target, bSetting);
}
CJS_Result CJX_EventPseudoModel::emit(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
@@ -181,16 +210,12 @@
if (!pNotify)
return CJS_Result::Success();
- CXFA_FFWidgetHandler* pWidgetHandler = pNotify->GetWidgetHandler();
- if (!pWidgetHandler)
- return CJS_Result::Success();
-
- pWidgetHandler->ProcessEvent(pEventParam->m_pTarget.Get(), pEventParam);
+ pNotify->HandleWidgetEvent(pScriptContext->GetEventTarget(), pEventParam);
return CJS_Result::Success();
}
CJS_Result CJX_EventPseudoModel::reset(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
@@ -200,7 +225,8 @@
return CJS_Result::Success();
}
-void CJX_EventPseudoModel::Property(CFXJSE_Value* pValue,
+void CJX_EventPseudoModel::Property(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
XFA_Event dwFlag,
bool bSetting) {
// Only the cancelAction, selStart, selEnd and change properties are writable.
@@ -217,65 +243,70 @@
switch (dwFlag) {
case XFA_Event::CancelAction:
- BooleanProperty(pValue, &pEventParam->m_bCancelAction, bSetting);
+ BooleanProperty(pIsolate, pValue, &pEventParam->m_bCancelAction,
+ bSetting);
break;
case XFA_Event::Change:
- StringProperty(pValue, &pEventParam->m_wsChange, bSetting);
+ StringProperty(pIsolate, pValue, &pEventParam->m_wsChange, bSetting);
break;
case XFA_Event::CommitKey:
- IntegerProperty(pValue, &pEventParam->m_iCommitKey, bSetting);
+ IntegerProperty(pIsolate, pValue, &pEventParam->m_iCommitKey, bSetting);
break;
case XFA_Event::FullText:
- StringProperty(pValue, &pEventParam->m_wsFullText, bSetting);
+ StringProperty(pIsolate, pValue, &pEventParam->m_wsFullText, bSetting);
break;
case XFA_Event::Keydown:
- BooleanProperty(pValue, &pEventParam->m_bKeyDown, bSetting);
+ BooleanProperty(pIsolate, pValue, &pEventParam->m_bKeyDown, bSetting);
break;
case XFA_Event::Modifier:
- BooleanProperty(pValue, &pEventParam->m_bModifier, bSetting);
+ BooleanProperty(pIsolate, pValue, &pEventParam->m_bModifier, bSetting);
break;
case XFA_Event::NewContentType:
- StringProperty(pValue, &pEventParam->m_wsNewContentType, bSetting);
+ StringProperty(pIsolate, pValue, &pEventParam->m_wsNewContentType,
+ bSetting);
break;
case XFA_Event::NewText:
NOTREACHED();
break;
case XFA_Event::PreviousContentType:
- StringProperty(pValue, &pEventParam->m_wsPrevContentType, bSetting);
+ StringProperty(pIsolate, pValue, &pEventParam->m_wsPrevContentType,
+ bSetting);
break;
case XFA_Event::PreviousText:
- StringProperty(pValue, &pEventParam->m_wsPrevText, bSetting);
+ StringProperty(pIsolate, pValue, &pEventParam->m_wsPrevText, bSetting);
break;
case XFA_Event::Reenter:
- BooleanProperty(pValue, &pEventParam->m_bReenter, bSetting);
+ BooleanProperty(pIsolate, pValue, &pEventParam->m_bReenter, bSetting);
break;
case XFA_Event::SelectionEnd:
- IntegerProperty(pValue, &pEventParam->m_iSelEnd, bSetting);
+ IntegerProperty(pIsolate, pValue, &pEventParam->m_iSelEnd, bSetting);
pEventParam->m_iSelEnd = std::max(0, pEventParam->m_iSelEnd);
- pEventParam->m_iSelEnd =
- std::min(static_cast<size_t>(pEventParam->m_iSelEnd),
- pEventParam->m_wsPrevText.GetLength());
+ pEventParam->m_iSelEnd = std::min(
+ pEventParam->m_iSelEnd, pdfium::base::checked_cast<int32_t>(
+ pEventParam->m_wsPrevText.GetLength()));
pEventParam->m_iSelStart =
std::min(pEventParam->m_iSelStart, pEventParam->m_iSelEnd);
break;
case XFA_Event::SelectionStart:
- IntegerProperty(pValue, &pEventParam->m_iSelStart, bSetting);
+ IntegerProperty(pIsolate, pValue, &pEventParam->m_iSelStart, bSetting);
pEventParam->m_iSelStart = std::max(0, pEventParam->m_iSelStart);
- pEventParam->m_iSelStart =
- std::min(static_cast<size_t>(pEventParam->m_iSelStart),
- pEventParam->m_wsPrevText.GetLength());
+ pEventParam->m_iSelStart = std::min(
+ pEventParam->m_iSelStart, pdfium::base::checked_cast<int32_t>(
+ pEventParam->m_wsPrevText.GetLength()));
pEventParam->m_iSelEnd =
std::max(pEventParam->m_iSelStart, pEventParam->m_iSelEnd);
break;
case XFA_Event::Shift:
- BooleanProperty(pValue, &pEventParam->m_bShift, bSetting);
+ BooleanProperty(pIsolate, pValue, &pEventParam->m_bShift, bSetting);
break;
case XFA_Event::SoapFaultCode:
- StringProperty(pValue, &pEventParam->m_wsSoapFaultCode, bSetting);
+ StringProperty(pIsolate, pValue, &pEventParam->m_wsSoapFaultCode,
+ bSetting);
break;
case XFA_Event::SoapFaultString:
- StringProperty(pValue, &pEventParam->m_wsSoapFaultString, bSetting);
+ StringProperty(pIsolate, pValue, &pEventParam->m_wsSoapFaultString,
+ bSetting);
break;
case XFA_Event::Target:
default:
diff --git a/fxjs/xfa/cjx_eventpseudomodel.h b/fxjs/xfa/cjx_eventpseudomodel.h
index 6f3cc84..3be881a 100644
--- a/fxjs/xfa/cjx_eventpseudomodel.h
+++ b/fxjs/xfa/cjx_eventpseudomodel.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,7 +10,6 @@
#include "fxjs/xfa/cjx_object.h"
#include "fxjs/xfa/jse_define.h"
-class CFXJSE_Value;
class CScript_EventPseudoModel;
enum class XFA_Event {
@@ -35,7 +34,7 @@
class CJX_EventPseudoModel final : public CJX_Object {
public:
- explicit CJX_EventPseudoModel(CScript_EventPseudoModel* model);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_EventPseudoModel() override;
// CJX_Object:
@@ -63,13 +62,18 @@
JSE_PROP(target);
private:
+ explicit CJX_EventPseudoModel(CScript_EventPseudoModel* model);
+
using Type__ = CJX_EventPseudoModel;
using ParentType__ = CJX_Object;
static const TypeTag static_type__ = TypeTag::EventPseudoModel;
static const CJX_MethodSpec MethodSpecs[];
- void Property(CFXJSE_Value* pValue, XFA_Event dwFlag, bool bSetting);
+ void Property(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
+ XFA_Event dwFlag,
+ bool bSetting);
};
#endif // FXJS_XFA_CJX_EVENTPSEUDOMODEL_H_
diff --git a/fxjs/xfa/cjx_exclgroup.cpp b/fxjs/xfa/cjx_exclgroup.cpp
index 00bf539..11e6982 100644
--- a/fxjs/xfa/cjx_exclgroup.cpp
+++ b/fxjs/xfa/cjx_exclgroup.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,9 +8,11 @@
#include <vector>
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/fxfa.h"
@@ -28,14 +30,14 @@
DefineMethods(MethodSpecs);
}
-CJX_ExclGroup::~CJX_ExclGroup() {}
+CJX_ExclGroup::~CJX_ExclGroup() = default;
bool CJX_ExclGroup::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_ExclGroup::execEvent(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -46,7 +48,7 @@
}
CJS_Result CJX_ExclGroup::execInitialize(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -59,7 +61,7 @@
}
CJS_Result CJX_ExclGroup::execCalculate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -72,7 +74,7 @@
}
CJS_Result CJX_ExclGroup::execValidate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -88,7 +90,7 @@
}
CJS_Result CJX_ExclGroup::selectedMember(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -102,20 +104,18 @@
pReturnNode = node->GetSelectedMember();
} else {
pReturnNode = node->SetSelectedMember(
- runtime->ToWideString(params[0]).AsStringView(), true);
+ runtime->ToWideString(params[0]).AsStringView());
}
if (!pReturnNode)
return CJS_Result::Success(runtime->NewNull());
- CFXJSE_Value* value =
- GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
- pReturnNode);
-
return CJS_Result::Success(
- value->DirectGetValue().Get(runtime->GetIsolate()));
+ GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+ pReturnNode));
}
-void CJX_ExclGroup::defaultValue(CFXJSE_Value* pValue,
+void CJX_ExclGroup::defaultValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Node* node = GetXFANode();
@@ -123,33 +123,37 @@
return;
if (bSetting) {
- node->SetSelectedMemberByValue(pValue->ToWideString().AsStringView(), true,
- true, true);
+ node->SetSelectedMemberByValue(
+ fxv8::ReentrantToWideStringHelper(pIsolate, *pValue).AsStringView(),
+ true, true, true);
return;
}
WideString wsValue = GetContent(true);
XFA_VERSION curVersion = GetDocument()->GetCurVersionMode();
if (wsValue.IsEmpty() && curVersion >= XFA_VERSION_300) {
- pValue->SetNull();
+ *pValue = fxv8::NewNullHelper(pIsolate);
return;
}
- pValue->SetString(wsValue.ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(pIsolate, wsValue.ToUTF8().AsStringView());
}
-void CJX_ExclGroup::rawValue(CFXJSE_Value* pValue,
+void CJX_ExclGroup::rawValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- defaultValue(pValue, bSetting, eAttribute);
+ defaultValue(pIsolate, pValue, bSetting, eAttribute);
}
-void CJX_ExclGroup::transient(CFXJSE_Value* pValue,
+void CJX_ExclGroup::transient(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
-void CJX_ExclGroup::errorText(CFXJSE_Value* pValue,
+void CJX_ExclGroup::errorText(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting)
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
}
diff --git a/fxjs/xfa/cjx_exclgroup.h b/fxjs/xfa/cjx_exclgroup.h
index b459808..f6a983c 100644
--- a/fxjs/xfa/cjx_exclgroup.h
+++ b/fxjs/xfa/cjx_exclgroup.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_ExclGroup final : public CJX_Node {
public:
- explicit CJX_ExclGroup(CXFA_ExclGroup* group);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_ExclGroup() override;
// CJX_Object:
@@ -32,6 +32,8 @@
JSE_PROP(transient);
private:
+ explicit CJX_ExclGroup(CXFA_ExclGroup* group);
+
using Type__ = CJX_ExclGroup;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_extras.cpp b/fxjs/xfa/cjx_extras.cpp
index a2e2eea..74cdbba 100644
--- a/fxjs/xfa/cjx_extras.cpp
+++ b/fxjs/xfa/cjx_extras.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,6 +16,7 @@
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_Extras::type(CFXJSE_Value* pValue,
+void CJX_Extras::type(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_extras.h b/fxjs/xfa/cjx_extras.h
index 0723575..6a1b212 100644
--- a/fxjs/xfa/cjx_extras.h
+++ b/fxjs/xfa/cjx_extras.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Extras final : public CJX_Node {
public:
- explicit CJX_Extras(CXFA_Extras* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Extras() override;
// CJX_Object:
@@ -23,6 +23,8 @@
JSE_PROP(type);
private:
+ explicit CJX_Extras(CXFA_Extras* node);
+
using Type__ = CJX_Extras;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_field.cpp b/fxjs/xfa/cjx_field.cpp
index ef334a3..8d158dc 100644
--- a/fxjs/xfa/cjx_field.cpp
+++ b/fxjs/xfa/cjx_field.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,8 +9,10 @@
#include <vector>
#include "fxjs/cfx_v8.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "third_party/base/numerics/safe_conversions.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fgas/crt/cfgas_decimal.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
@@ -37,14 +39,14 @@
DefineMethods(MethodSpecs);
}
-CJX_Field::~CJX_Field() {}
+CJX_Field::~CJX_Field() = default;
bool CJX_Field::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_Field::clearItems(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
CXFA_Node* node = GetXFANode();
if (node->IsWidgetReady())
@@ -53,7 +55,7 @@
}
CJS_Result CJX_Field::execEvent(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -69,7 +71,7 @@
}
CJS_Result CJX_Field::execInitialize(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -83,7 +85,7 @@
}
CJS_Result CJX_Field::deleteItem(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -97,7 +99,7 @@
}
CJS_Result CJX_Field::getSaveItem(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -110,8 +112,8 @@
if (!node->IsWidgetReady())
return CJS_Result::Success(runtime->NewNull());
- Optional<WideString> value = node->GetChoiceListItem(iIndex, true);
- if (!value)
+ absl::optional<WideString> value = node->GetChoiceListItem(iIndex, true);
+ if (!value.has_value())
return CJS_Result::Success(runtime->NewNull());
return CJS_Result::Success(
@@ -119,7 +121,7 @@
}
CJS_Result CJX_Field::boundItem(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -135,7 +137,7 @@
}
CJS_Result CJX_Field::getItemState(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -149,7 +151,7 @@
}
CJS_Result CJX_Field::execCalculate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -163,7 +165,7 @@
}
CJS_Result CJX_Field::getDisplayItem(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -176,8 +178,8 @@
if (!node->IsWidgetReady())
return CJS_Result::Success(runtime->NewNull());
- Optional<WideString> value = node->GetChoiceListItem(iIndex, false);
- if (!value)
+ absl::optional<WideString> value = node->GetChoiceListItem(iIndex, false);
+ if (!value.has_value())
return CJS_Result::Success(runtime->NewNull());
return CJS_Result::Success(
@@ -185,7 +187,7 @@
}
CJS_Result CJX_Field::setItemState(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 2)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -196,16 +198,16 @@
int32_t iIndex = runtime->ToInt32(params[0]);
if (runtime->ToInt32(params[1]) != 0) {
- node->SetItemState(iIndex, true, true, true, true);
+ node->SetItemState(iIndex, true, true, true);
return CJS_Result::Success();
}
if (node->GetItemState(iIndex))
- node->SetItemState(iIndex, false, true, true, true);
+ node->SetItemState(iIndex, false, true, true);
return CJS_Result::Success();
}
-CJS_Result CJX_Field::addItem(CFX_V8* runtime,
+CJS_Result CJX_Field::addItem(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1 && params.size() != 2)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -227,7 +229,7 @@
}
CJS_Result CJX_Field::execValidate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -242,7 +244,8 @@
runtime->NewBoolean(iRet != XFA_EventError::kError));
}
-void CJX_Field::defaultValue(CFXJSE_Value* pValue,
+void CJX_Field::defaultValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Node* xfaNode = GetXFANode();
@@ -252,12 +255,12 @@
if (bSetting) {
if (pValue) {
xfaNode->SetPreNull(xfaNode->IsNull());
- xfaNode->SetIsNull(pValue->IsNull());
+ xfaNode->SetIsNull(fxv8::IsNull(*pValue));
}
WideString wsNewText;
- if (pValue && !(pValue->IsNull() || pValue->IsUndefined()))
- wsNewText = pValue->ToWideString();
+ if (pValue && !(fxv8::IsNull(*pValue) || fxv8::IsUndefined(*pValue)))
+ wsNewText = fxv8::ReentrantToWideStringHelper(pIsolate, *pValue);
if (xfaNode->GetUIChildNode()->GetElementType() == XFA_Element::NumericEdit)
wsNewText = xfaNode->NumericLimit(wsNewText);
@@ -272,7 +275,7 @@
WideString content = GetContent(true);
if (content.IsEmpty()) {
- pValue->SetNull();
+ *pValue = fxv8::NewNullHelper(pIsolate);
return;
}
@@ -282,24 +285,27 @@
if (xfaNode->GetUIChildNode()->GetElementType() ==
XFA_Element::NumericEdit &&
(pNode->JSObject()->GetInteger(XFA_Attribute::FracDigits) == -1)) {
- pValue->SetString(content.ToUTF8().AsStringView());
+ *pValue =
+ fxv8::NewStringHelper(pIsolate, content.ToUTF8().AsStringView());
} else {
CFGAS_Decimal decimal(content.AsStringView());
- pValue->SetFloat(decimal.ToFloat());
+ *pValue = fxv8::NewNumberHelper(pIsolate, decimal.ToFloat());
}
} else if (pNode && pNode->GetElementType() == XFA_Element::Integer) {
- pValue->SetInteger(FXSYS_wtoi(content.c_str()));
+ *pValue = fxv8::NewNumberHelper(pIsolate, FXSYS_wtoi(content.c_str()));
} else if (pNode && pNode->GetElementType() == XFA_Element::Boolean) {
- pValue->SetBoolean(FXSYS_wtoi(content.c_str()) != 0);
+ *pValue =
+ fxv8::NewBooleanHelper(pIsolate, FXSYS_wtoi(content.c_str()) != 0);
} else if (pNode && pNode->GetElementType() == XFA_Element::Float) {
CFGAS_Decimal decimal(content.AsStringView());
- pValue->SetFloat(decimal.ToFloat());
+ *pValue = fxv8::NewNumberHelper(pIsolate, decimal.ToFloat());
} else {
- pValue->SetString(content.ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(pIsolate, content.ToUTF8().AsStringView());
}
}
-void CJX_Field::editValue(CFXJSE_Value* pValue,
+void CJX_Field::editValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Node* node = GetXFANode();
@@ -307,20 +313,24 @@
return;
if (bSetting) {
- node->SetValue(XFA_VALUEPICTURE_Edit, pValue->ToWideString());
+ node->SetValue(XFA_ValuePicture::kEdit,
+ fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
return;
}
- pValue->SetString(
- node->GetValue(XFA_VALUEPICTURE_Edit).ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(
+ pIsolate,
+ node->GetValue(XFA_ValuePicture::kEdit).ToUTF8().AsStringView());
}
-void CJX_Field::formatMessage(CFXJSE_Value* pValue,
+void CJX_Field::formatMessage(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- ScriptSomMessage(pValue, bSetting, XFA_SOM_FormatMessage);
+ ScriptSomMessage(pIsolate, pValue, bSetting, SOMMessageType::kFormatMessage);
}
-void CJX_Field::formattedValue(CFXJSE_Value* pValue,
+void CJX_Field::formattedValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Node* node = GetXFANode();
@@ -328,40 +338,44 @@
return;
if (bSetting) {
- node->SetValue(XFA_VALUEPICTURE_Display, pValue->ToWideString());
+ node->SetValue(XFA_ValuePicture::kDisplay,
+ fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
return;
}
- pValue->SetString(
- node->GetValue(XFA_VALUEPICTURE_Display).ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(
+ pIsolate,
+ node->GetValue(XFA_ValuePicture::kDisplay).ToUTF8().AsStringView());
}
-void CJX_Field::length(CFXJSE_Value* pValue,
+void CJX_Field::length(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
CXFA_Node* node = GetXFANode();
- if (!node->IsWidgetReady()) {
- pValue->SetInteger(0);
- return;
- }
- pValue->SetInteger(node->CountChoiceListItems(true));
+ *pValue = fxv8::NewNumberHelper(
+ pIsolate, node->IsWidgetReady() ? pdfium::base::checked_cast<int>(
+ node->CountChoiceListItems(true))
+ : 0);
}
-void CJX_Field::parentSubform(CFXJSE_Value* pValue,
+void CJX_Field::parentSubform(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- pValue->SetNull();
+ *pValue = fxv8::NewNullHelper(pIsolate);
}
-void CJX_Field::selectedIndex(CFXJSE_Value* pValue,
+void CJX_Field::selectedIndex(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Node* node = GetXFANode();
@@ -369,21 +383,22 @@
return;
if (!bSetting) {
- pValue->SetInteger(node->GetSelectedItem(0));
+ *pValue = fxv8::NewNumberHelper(pIsolate, node->GetSelectedItem(0));
return;
}
- int32_t iIndex = pValue->ToInteger();
+ int32_t iIndex = fxv8::ReentrantToInt32Helper(pIsolate, *pValue);
if (iIndex == -1) {
node->ClearAllSelections();
return;
}
- node->SetItemState(iIndex, true, true, true, true);
+ node->SetItemState(iIndex, true, true, true);
}
-void CJX_Field::rawValue(CFXJSE_Value* pValue,
+void CJX_Field::rawValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- defaultValue(pValue, bSetting, eAttribute);
+ defaultValue(pIsolate, pValue, bSetting, eAttribute);
}
diff --git a/fxjs/xfa/cjx_field.h b/fxjs/xfa/cjx_field.h
index 6e16e7a..5628fc4 100644
--- a/fxjs/xfa/cjx_field.h
+++ b/fxjs/xfa/cjx_field.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Field final : public CJX_Container {
public:
- explicit CJX_Field(CXFA_Field* field);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Field() override;
// CJX_Object:
@@ -43,6 +43,8 @@
JSE_PROP(selectedIndex);
private:
+ explicit CJX_Field(CXFA_Field* field);
+
using Type__ = CJX_Field;
using ParentType__ = CJX_Container;
diff --git a/fxjs/xfa/cjx_form.cpp b/fxjs/xfa/cjx_form.cpp
index 07e8602..4dab966 100644
--- a/fxjs/xfa/cjx_form.cpp
+++ b/fxjs/xfa/cjx_form.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,9 +8,12 @@
#include <vector>
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/cppgc/allocation.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cxfa_arraynodelist.h"
@@ -29,43 +32,42 @@
DefineMethods(MethodSpecs);
}
-CJX_Form::~CJX_Form() {}
+CJX_Form::~CJX_Form() = default;
bool CJX_Form::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_Form::formNodes(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- CXFA_Node* pDataNode =
- ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
+ CXFA_Node* pDataNode = ToNode(runtime->ToXFAObject(params[0]));
if (!pDataNode)
return CJS_Result::Failure(JSMessage::kValueError);
- CXFA_ArrayNodeList* pFormNodes = new CXFA_ArrayNodeList(GetDocument());
- CFXJSE_Value* value =
- GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
- pFormNodes);
+ CXFA_Document* pDoc = GetDocument();
+ auto* pFormNodes = cppgc::MakeGarbageCollected<CXFA_ArrayNodeList>(
+ pDoc->GetHeap()->GetAllocationHandle(), pDoc);
+ pDoc->GetNodeOwner()->PersistList(pFormNodes);
- return CJS_Result::Success(
- value->DirectGetValue().Get(runtime->GetIsolate()));
+ v8::Local<v8::Value> value = runtime->GetOrCreateJSBindingFromMap(pFormNodes);
+ return CJS_Result::Success(value);
}
-CJS_Result CJX_Form::remerge(CFX_V8* runtime,
+CJS_Result CJX_Form::remerge(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
- GetDocument()->DoDataRemerge(true);
+ GetDocument()->DoDataRemerge();
return CJS_Result::Success();
}
CJS_Result CJX_Form::execInitialize(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -78,7 +80,7 @@
}
CJS_Result CJX_Form::recalculate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
CXFA_EventParam* pEventParam =
GetDocument()->GetScriptContext()->GetEventParam();
@@ -100,7 +102,7 @@
}
CJS_Result CJX_Form::execCalculate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -113,7 +115,7 @@
}
CJS_Result CJX_Form::execValidate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 0)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -128,15 +130,20 @@
runtime->NewBoolean(iRet != XFA_EventError::kError));
}
-void CJX_Form::checksumS(CFXJSE_Value* pValue,
+void CJX_Form::checksumS(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- SetAttribute(XFA_Attribute::Checksum, pValue->ToWideString().AsStringView(),
- false);
+ SetAttributeByEnum(XFA_Attribute::Checksum,
+ fxv8::ReentrantToWideStringHelper(pIsolate, *pValue),
+ false);
return;
}
- Optional<WideString> checksum = TryAttribute(XFA_Attribute::Checksum, false);
- pValue->SetString(checksum ? checksum->ToUTF8().AsStringView() : "");
+ absl::optional<WideString> checksum =
+ TryAttribute(XFA_Attribute::Checksum, false);
+ *pValue = fxv8::NewStringHelper(
+ pIsolate,
+ checksum.has_value() ? checksum.value().ToUTF8().AsStringView() : "");
}
diff --git a/fxjs/xfa/cjx_form.h b/fxjs/xfa/cjx_form.h
index c7b1ce3..05ea04c 100644
--- a/fxjs/xfa/cjx_form.h
+++ b/fxjs/xfa/cjx_form.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Form final : public CJX_Model {
public:
- explicit CJX_Form(CXFA_Form* form);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Form() override;
// CJX_Object:
@@ -30,6 +30,8 @@
JSE_PROP(checksumS);
private:
+ explicit CJX_Form(CXFA_Form* form);
+
using Type__ = CJX_Form;
using ParentType__ = CJX_Model;
diff --git a/fxjs/xfa/cjx_handler.cpp b/fxjs/xfa/cjx_handler.cpp
index 21be88c..d8caeca 100644
--- a/fxjs/xfa/cjx_handler.cpp
+++ b/fxjs/xfa/cjx_handler.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,6 +16,7 @@
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_Handler::version(CFXJSE_Value* pValue,
+void CJX_Handler::version(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_handler.h b/fxjs/xfa/cjx_handler.h
index 348eaf1..e5cd2cb 100644
--- a/fxjs/xfa/cjx_handler.h
+++ b/fxjs/xfa/cjx_handler.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Handler final : public CJX_TextNode {
public:
- explicit CJX_Handler(CXFA_Handler* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Handler() override;
// CJX_Object:
@@ -23,6 +23,8 @@
JSE_PROP(version);
private:
+ explicit CJX_Handler(CXFA_Handler* node);
+
using Type__ = CJX_Handler;
using ParentType__ = CJX_TextNode;
diff --git a/fxjs/xfa/cjx_hostpseudomodel.cpp b/fxjs/xfa/cjx_hostpseudomodel.cpp
index c45495c..597db30 100644
--- a/fxjs/xfa/cjx_hostpseudomodel.cpp
+++ b/fxjs/xfa/cjx_hostpseudomodel.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,34 +6,33 @@
#include "fxjs/xfa/cjx_hostpseudomodel.h"
-#include <memory>
#include <vector>
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "third_party/base/check.h"
+#include "v8/include/v8-object.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cscript_hostpseudomodel.h"
#include "xfa/fxfa/parser/cxfa_node.h"
-#include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
namespace {
-int32_t FilterName(WideStringView wsExpression,
- int32_t nStart,
- WideString& wsFilter) {
- ASSERT(nStart > -1);
- int32_t iLength = wsExpression.GetLength();
- if (nStart >= iLength)
- return iLength;
+size_t FilterName(WideStringView wsExpression,
+ size_t nStart,
+ WideString& wsFilter) {
+ const size_t nLength = wsExpression.GetLength();
+ if (nStart >= nLength)
+ return nLength;
- int32_t nCount = 0;
+ size_t nCount = 0;
{
// Span's lifetime must end before ReleaseBuffer() below.
- pdfium::span<wchar_t> pBuf = wsFilter.GetBuffer(iLength - nStart);
+ pdfium::span<wchar_t> pBuf = wsFilter.GetBuffer(nLength - nStart);
const wchar_t* pSrc = wsExpression.unterminated_c_str();
- while (nStart < iLength) {
+ while (nStart < nLength) {
wchar_t wCur = pSrc[nStart++];
if (wCur == ',')
break;
@@ -70,13 +69,14 @@
DefineMethods(MethodSpecs);
}
-CJX_HostPseudoModel::~CJX_HostPseudoModel() {}
+CJX_HostPseudoModel::~CJX_HostPseudoModel() = default;
bool CJX_HostPseudoModel::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_HostPseudoModel::appType(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::appType(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -84,44 +84,47 @@
return;
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- pValue->SetString("Exchange");
+ *pValue = fxv8::NewStringHelper(pIsolate, "Exchange");
}
-void CJX_HostPseudoModel::calculationsEnabled(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::calculationsEnabled(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (!pNotify)
return;
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
+ CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
if (bSetting) {
- hDoc->GetDocEnvironment()->SetCalculationsEnabled(hDoc,
- pValue->ToBoolean());
+ hDoc->SetCalculationsEnabled(
+ fxv8::ReentrantToBooleanHelper(pIsolate, *pValue));
return;
}
- pValue->SetBoolean(hDoc->GetDocEnvironment()->IsCalculationsEnabled(hDoc));
+ *pValue = fxv8::NewBooleanHelper(pIsolate, hDoc->IsCalculationsEnabled());
}
-void CJX_HostPseudoModel::currentPage(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::currentPage(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (!pNotify)
return;
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
+ CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
if (bSetting) {
- hDoc->GetDocEnvironment()->SetCurrentPage(hDoc, pValue->ToInteger());
+ hDoc->SetCurrentPage(fxv8::ReentrantToInt32Helper(pIsolate, *pValue));
return;
}
- pValue->SetInteger(hDoc->GetDocEnvironment()->GetCurrentPage(hDoc));
+ *pValue = fxv8::NewNumberHelper(pIsolate, hDoc->GetCurrentPage());
}
-void CJX_HostPseudoModel::language(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::language(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -129,29 +132,33 @@
return;
if (bSetting) {
- ThrowException(WideString::FromASCII("Unable to set language value."));
+ ThrowException(pIsolate,
+ WideString::FromASCII("Unable to set language value."));
return;
}
- pValue->SetString(
- pNotify->GetAppProvider()->GetLanguage().ToUTF8().AsStringView());
+ ByteString lang = pNotify->GetAppProvider()->GetLanguage().ToUTF8();
+ *pValue = fxv8::NewStringHelper(pIsolate, lang.AsStringView());
}
-void CJX_HostPseudoModel::numPages(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::numPages(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (!pNotify)
return;
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
+ CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
if (bSetting) {
- ThrowException(WideString::FromASCII("Unable to set numPages value."));
+ ThrowException(pIsolate,
+ WideString::FromASCII("Unable to set numPages value."));
return;
}
- pValue->SetInteger(hDoc->GetDocEnvironment()->CountPages(hDoc));
+ *pValue = fxv8::NewNumberHelper(pIsolate, hDoc->CountPages());
}
-void CJX_HostPseudoModel::platform(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::platform(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -159,14 +166,16 @@
return;
if (bSetting) {
- ThrowException(WideString::FromASCII("Unable to set platform value."));
+ ThrowException(pIsolate,
+ WideString::FromASCII("Unable to set platform value."));
return;
}
- pValue->SetString(
- pNotify->GetAppProvider()->GetPlatform().ToUTF8().AsStringView());
+ ByteString plat = pNotify->GetAppProvider()->GetPlatform().ToUTF8();
+ *pValue = fxv8::NewStringHelper(pIsolate, plat.AsStringView());
}
-void CJX_HostPseudoModel::title(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::title(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (!GetDocument()->GetScriptContext()->IsRunAtClient())
@@ -176,58 +185,63 @@
if (!pNotify)
return;
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
+ CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
if (bSetting) {
- hDoc->GetDocEnvironment()->SetTitle(hDoc, pValue->ToWideString());
+ hDoc->SetTitle(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
return;
}
- WideString wsTitle;
- hDoc->GetDocEnvironment()->GetTitle(hDoc, wsTitle);
- pValue->SetString(wsTitle.ToUTF8().AsStringView());
+ ByteString bsTitle = hDoc->GetTitle().ToUTF8();
+ *pValue = fxv8::NewStringHelper(pIsolate, bsTitle.AsStringView());
}
-void CJX_HostPseudoModel::validationsEnabled(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::validationsEnabled(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (!pNotify)
return;
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
+ CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
if (bSetting) {
- hDoc->GetDocEnvironment()->SetValidationsEnabled(hDoc, pValue->ToBoolean());
+ hDoc->SetValidationsEnabled(
+ fxv8::ReentrantToBooleanHelper(pIsolate, *pValue));
return;
}
- bool bEnabled = hDoc->GetDocEnvironment()->IsValidationsEnabled(hDoc);
- pValue->SetBoolean(bEnabled);
+ *pValue = fxv8::NewBooleanHelper(pIsolate, hDoc->IsValidationsEnabled());
}
-void CJX_HostPseudoModel::variation(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::variation(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (!GetDocument()->GetScriptContext()->IsRunAtClient())
return;
if (bSetting) {
- ThrowException(WideString::FromASCII("Unable to set variation value."));
+ ThrowException(pIsolate,
+ WideString::FromASCII("Unable to set variation value."));
return;
}
- pValue->SetString("Full");
+ *pValue = fxv8::NewStringHelper(pIsolate, "Full");
}
-void CJX_HostPseudoModel::version(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::version(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowException(WideString::FromASCII("Unable to set version value."));
+ ThrowException(pIsolate,
+ WideString::FromASCII("Unable to set version value."));
return;
}
- pValue->SetString("11");
+ *pValue = fxv8::NewStringHelper(pIsolate, "11");
}
-void CJX_HostPseudoModel::name(CFXJSE_Value* pValue,
+void CJX_HostPseudoModel::name(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -235,15 +249,15 @@
return;
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- pValue->SetString(
- pNotify->GetAppProvider()->GetAppName().ToUTF8().AsStringView());
+ ByteString bsName = pNotify->GetAppProvider()->GetAppName().ToUTF8();
+ *pValue = fxv8::NewStringHelper(pIsolate, bsName.AsStringView());
}
CJS_Result CJX_HostPseudoModel::gotoURL(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!GetDocument()->GetScriptContext()->IsRunAtClient())
return CJS_Result::Success();
@@ -255,14 +269,12 @@
if (!pNotify)
return CJS_Result::Success();
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
- WideString URL = runtime->ToWideString(params[0]);
- hDoc->GetDocEnvironment()->GotoURL(hDoc, URL);
+ pNotify->GetFFDoc()->GotoURL(runtime->ToWideString(params[0]));
return CJS_Result::Success();
}
CJS_Result CJX_HostPseudoModel::openList(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!GetDocument()->GetScriptContext()->IsRunAtClient())
return CJS_Result::Success();
@@ -276,26 +288,25 @@
CXFA_Node* pNode = nullptr;
if (params[0]->IsObject()) {
- pNode =
- ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
+ pNode = ToNode(runtime->ToXFAObject(params[0]));
} else if (params[0]->IsString()) {
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
CXFA_Object* pObject = pScriptContext->GetThisObject();
if (!pObject)
return CJS_Result::Success();
- uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent |
- XFA_RESOLVENODE_Siblings;
- XFA_RESOLVENODE_RS resolveNodeRS;
- bool bRet = pScriptContext->ResolveObjects(
- pObject, runtime->ToWideString(params[0]).AsStringView(),
- &resolveNodeRS, dwFlag, nullptr);
- if (!bRet || !resolveNodeRS.objects.front()->IsNode())
+ constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
+ XFA_ResolveFlag::kParent,
+ XFA_ResolveFlag::kSiblings};
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+ pScriptContext->ResolveObjects(
+ pObject, runtime->ToWideString(params[0]).AsStringView(), kFlags);
+ if (!maybeResult.has_value() ||
+ !maybeResult.value().objects.front()->IsNode()) {
return CJS_Result::Success();
-
- pNode = resolveNodeRS.objects.front()->AsNode();
+ }
+ pNode = maybeResult.value().objects.front()->AsNode();
}
-
if (pNode)
pNotify->OpenDropDownList(pNode);
@@ -303,7 +314,7 @@
}
CJS_Result CJX_HostPseudoModel::response(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 4)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -335,13 +346,13 @@
}
CJS_Result CJX_HostPseudoModel::documentInBatch(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success(runtime->NewNumber(0));
}
CJS_Result CJX_HostPseudoModel::resetData(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() > 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -359,26 +370,27 @@
return CJS_Result::Success();
}
- int32_t iStart = 0;
WideString wsName;
CXFA_Node* pNode = nullptr;
- int32_t iExpLength = expression.GetLength();
- while (iStart < iExpLength) {
- iStart = FilterName(expression.AsStringView(), iStart, wsName);
+ size_t nStart = 0;
+ const size_t nExpLength = expression.GetLength();
+ while (nStart < nExpLength) {
+ nStart = FilterName(expression.AsStringView(), nStart, wsName);
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
CXFA_Object* pObject = pScriptContext->GetThisObject();
if (!pObject)
return CJS_Result::Success();
- uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent |
- XFA_RESOLVENODE_Siblings;
- XFA_RESOLVENODE_RS resolveNodeRS;
- bool bRet = pScriptContext->ResolveObjects(pObject, wsName.AsStringView(),
- &resolveNodeRS, dwFlag, nullptr);
- if (!bRet || !resolveNodeRS.objects.front()->IsNode())
+ constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
+ XFA_ResolveFlag::kParent,
+ XFA_ResolveFlag::kSiblings};
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+ pScriptContext->ResolveObjects(pObject, wsName.AsStringView(), kFlags);
+ if (!maybeResult.has_value() ||
+ !maybeResult.value().objects.front()->IsNode())
continue;
- pNode = resolveNodeRS.objects.front()->AsNode();
+ pNode = maybeResult.value().objects.front()->AsNode();
pNotify->ResetData(pNode->IsWidgetReady() ? pNode : nullptr);
}
if (!pNode)
@@ -388,7 +400,7 @@
}
CJS_Result CJX_HostPseudoModel::beep(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!GetDocument()->GetScriptContext()->IsRunAtClient())
return CJS_Result::Success();
@@ -409,7 +421,7 @@
}
CJS_Result CJX_HostPseudoModel::setFocus(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!GetDocument()->GetScriptContext()->IsRunAtClient())
return CJS_Result::Success();
@@ -424,24 +436,24 @@
CXFA_Node* pNode = nullptr;
if (params.size() >= 1) {
if (params[0]->IsObject()) {
- pNode =
- ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
+ pNode = ToNode(runtime->ToXFAObject(params[0]));
} else if (params[0]->IsString()) {
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
CXFA_Object* pObject = pScriptContext->GetThisObject();
if (!pObject)
return CJS_Result::Success();
- uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent |
- XFA_RESOLVENODE_Siblings;
- XFA_RESOLVENODE_RS resolveNodeRS;
- bool bRet = pScriptContext->ResolveObjects(
- pObject, runtime->ToWideString(params[0]).AsStringView(),
- &resolveNodeRS, dwFlag, nullptr);
- if (!bRet || !resolveNodeRS.objects.front()->IsNode())
+ constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
+ XFA_ResolveFlag::kParent,
+ XFA_ResolveFlag::kSiblings};
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+ pScriptContext->ResolveObjects(
+ pObject, runtime->ToWideString(params[0]).AsStringView(), kFlags);
+ if (!maybeResult.has_value() ||
+ !maybeResult.value().objects.front()->IsNode()) {
return CJS_Result::Success();
-
- pNode = resolveNodeRS.objects.front()->AsNode();
+ }
+ pNode = maybeResult.value().objects.front()->AsNode();
}
}
pNotify->SetFocusWidgetNode(pNode);
@@ -449,7 +461,7 @@
}
CJS_Result CJX_HostPseudoModel::getFocus(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (!pNotify)
@@ -459,15 +471,14 @@
if (!pNode)
return CJS_Result::Success();
- CFXJSE_Value* value =
+ v8::Local<v8::Value> value =
GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode);
- return CJS_Result::Success(
- value->DirectGetValue().Get(runtime->GetIsolate()));
+ return CJS_Result::Success(value);
}
CJS_Result CJX_HostPseudoModel::messageBox(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!GetDocument()->GetScriptContext()->IsRunAtClient())
return CJS_Result::Success();
@@ -507,13 +518,13 @@
}
CJS_Result CJX_HostPseudoModel::documentCountInBatch(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success(runtime->NewNumber(0));
}
CJS_Result CJX_HostPseudoModel::print(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!GetDocument()->GetScriptContext()->IsRunAtClient())
return CJS_Result::Success();
@@ -525,30 +536,28 @@
if (!pNotify)
return CJS_Result::Success();
- uint32_t dwOptions = 0;
+ Mask<XFA_PrintOpt> dwOptions;
if (runtime->ToBoolean(params[0]))
- dwOptions |= XFA_PRINTOPT_ShowDialog;
+ dwOptions |= XFA_PrintOpt::kShowDialog;
if (runtime->ToBoolean(params[3]))
- dwOptions |= XFA_PRINTOPT_CanCancel;
+ dwOptions |= XFA_PrintOpt::kCanCancel;
if (runtime->ToBoolean(params[4]))
- dwOptions |= XFA_PRINTOPT_ShrinkPage;
+ dwOptions |= XFA_PrintOpt::kShrinkPage;
if (runtime->ToBoolean(params[5]))
- dwOptions |= XFA_PRINTOPT_AsImage;
+ dwOptions |= XFA_PrintOpt::kAsImage;
if (runtime->ToBoolean(params[6]))
- dwOptions |= XFA_PRINTOPT_ReverseOrder;
+ dwOptions |= XFA_PrintOpt::kReverseOrder;
if (runtime->ToBoolean(params[7]))
- dwOptions |= XFA_PRINTOPT_PrintAnnot;
+ dwOptions |= XFA_PrintOpt::kPrintAnnot;
int32_t nStartPage = runtime->ToInt32(params[1]);
int32_t nEndPage = runtime->ToInt32(params[2]);
-
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
- hDoc->GetDocEnvironment()->Print(hDoc, nStartPage, nEndPage, dwOptions);
+ pNotify->GetFFDoc()->Print(nStartPage, nEndPage, dwOptions);
return CJS_Result::Success();
}
CJS_Result CJX_HostPseudoModel::importData(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -557,7 +566,7 @@
}
CJS_Result CJX_HostPseudoModel::exportData(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 2)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -574,39 +583,36 @@
if (params.size() >= 2)
XDP = runtime->ToBoolean(params[1]);
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
- hDoc->GetDocEnvironment()->ExportData(hDoc, filePath, XDP);
+ pNotify->GetFFDoc()->ExportData(filePath, XDP);
return CJS_Result::Success();
}
CJS_Result CJX_HostPseudoModel::pageUp(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (!pNotify)
return CJS_Result::Success();
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
- int32_t nCurPage = hDoc->GetDocEnvironment()->GetCurrentPage(hDoc);
- int32_t nNewPage = 0;
+ CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
+ int32_t nCurPage = hDoc->GetCurrentPage();
if (nCurPage <= 1)
return CJS_Result::Success();
- nNewPage = nCurPage - 1;
- hDoc->GetDocEnvironment()->SetCurrentPage(hDoc, nNewPage);
+ hDoc->SetCurrentPage(nCurPage - 1);
return CJS_Result::Success();
}
CJS_Result CJX_HostPseudoModel::pageDown(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (!pNotify)
return CJS_Result::Success();
- CXFA_FFDoc* hDoc = pNotify->GetHDOC();
- int32_t nCurPage = hDoc->GetDocEnvironment()->GetCurrentPage(hDoc);
- int32_t nPageCount = hDoc->GetDocEnvironment()->CountPages(hDoc);
+ CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
+ int32_t nCurPage = hDoc->GetCurrentPage();
+ int32_t nPageCount = hDoc->CountPages();
if (!nPageCount || nCurPage == nPageCount)
return CJS_Result::Success();
@@ -616,6 +622,6 @@
else
nNewPage = nCurPage + 1;
- hDoc->GetDocEnvironment()->SetCurrentPage(hDoc, nNewPage);
+ hDoc->SetCurrentPage(nNewPage);
return CJS_Result::Success();
}
diff --git a/fxjs/xfa/cjx_hostpseudomodel.h b/fxjs/xfa/cjx_hostpseudomodel.h
index cdc293d..7c1b3b5 100644
--- a/fxjs/xfa/cjx_hostpseudomodel.h
+++ b/fxjs/xfa/cjx_hostpseudomodel.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,12 +11,11 @@
#include "fxjs/xfa/jse_define.h"
#include "xfa/fxfa/fxfa_basic.h"
-class CFXJSE_Value;
class CScript_HostPseudoModel;
class CJX_HostPseudoModel final : public CJX_Object {
public:
- explicit CJX_HostPseudoModel(CScript_HostPseudoModel* model);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_HostPseudoModel() override;
// CJX_Object:
@@ -54,6 +53,8 @@
JSE_PROP(name);
private:
+ explicit CJX_HostPseudoModel(CScript_HostPseudoModel* model);
+
using Type__ = CJX_HostPseudoModel;
using ParentType__ = CJX_Object;
diff --git a/fxjs/xfa/cjx_hostpseudomodel_embeddertest.cpp b/fxjs/xfa/cjx_hostpseudomodel_embeddertest.cpp
index 1d42898..86e0902 100644
--- a/fxjs/xfa/cjx_hostpseudomodel_embeddertest.cpp
+++ b/fxjs/xfa/cjx_hostpseudomodel_embeddertest.cpp
@@ -1,4 +1,4 @@
-// Copyright 2019 PDFium Authors. All rights reserved.
+// Copyright 2019 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
diff --git a/fxjs/xfa/cjx_instancemanager.cpp b/fxjs/xfa/cjx_instancemanager.cpp
index 160c4a5..18faf93 100644
--- a/fxjs/xfa/cjx_instancemanager.cpp
+++ b/fxjs/xfa/cjx_instancemanager.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,14 +9,18 @@
#include <algorithm>
#include <vector>
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "third_party/base/notreached.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_instancemanager.h"
#include "xfa/fxfa/parser/cxfa_occur.h"
+#include "xfa/fxfa/parser/cxfa_subform.h"
const CJX_MethodSpec CJX_InstanceManager::MethodSpecs[] = {
{"addInstance", addInstance_static},
@@ -30,23 +34,24 @@
DefineMethods(MethodSpecs);
}
-CJX_InstanceManager::~CJX_InstanceManager() {}
+CJX_InstanceManager::~CJX_InstanceManager() = default;
bool CJX_InstanceManager::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-int32_t CJX_InstanceManager::SetInstances(int32_t iDesired) {
+int32_t CJX_InstanceManager::SetInstances(v8::Isolate* pIsolate,
+ int32_t iDesired) {
CXFA_Occur* occur = GetXFANode()->GetOccurIfExists();
int32_t iMin = occur ? occur->GetMin() : CXFA_Occur::kDefaultMin;
if (iDesired < iMin) {
- ThrowTooManyOccurancesException(L"min");
+ ThrowTooManyOccurrencesException(pIsolate, L"min");
return 1;
}
int32_t iMax = occur ? occur->GetMax() : CXFA_Occur::kDefaultMax;
if (iMax >= 0 && iDesired > iMax) {
- ThrowTooManyOccurancesException(L"max");
+ ThrowTooManyOccurrencesException(pIsolate, L"max");
return 2;
}
@@ -61,13 +66,13 @@
? wsInstManagerName
: wsInstManagerName.Last(wsInstManagerName.GetLength() - 1));
uint32_t dInstanceNameHash =
- FX_HashCode_GetW(wsInstanceName.AsStringView(), false);
+ FX_HashCode_GetW(wsInstanceName.AsStringView());
CXFA_Node* pPrevSibling = iDesired == 0
? GetXFANode()
: GetXFANode()->GetItemIfExists(iDesired - 1);
if (!pPrevSibling) {
// TODO(dsinclair): Better error?
- ThrowIndexOutOfBoundsException();
+ ThrowIndexOutOfBoundsException(pIsolate);
return 0;
}
@@ -102,15 +107,16 @@
pNotify->RunNodeInitialize(pNewInstance);
}
}
- GetDocument()->GetLayoutProcessor()->AddChangedContainer(
- ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form)));
+ GetDocument()->GetLayoutProcessor()->SetHasChangedContainer();
return 0;
}
-int32_t CJX_InstanceManager::MoveInstance(int32_t iTo, int32_t iFrom) {
+int32_t CJX_InstanceManager::MoveInstance(v8::Isolate* pIsolate,
+ int32_t iTo,
+ int32_t iFrom) {
int32_t iCount = GetXFANode()->GetCount();
if (iFrom > iCount || iTo > iCount - 1) {
- ThrowIndexOutOfBoundsException();
+ ThrowIndexOutOfBoundsException(pIsolate);
return 1;
}
if (iFrom < 0 || iTo < 0 || iFrom == iTo)
@@ -118,21 +124,20 @@
CXFA_Node* pMoveInstance = GetXFANode()->GetItemIfExists(iFrom);
if (!pMoveInstance) {
- ThrowIndexOutOfBoundsException();
+ ThrowIndexOutOfBoundsException(pIsolate);
return 1;
}
GetXFANode()->RemoveItem(pMoveInstance, false);
GetXFANode()->InsertItem(pMoveInstance, iTo, iCount - 1, true);
- GetDocument()->GetLayoutProcessor()->AddChangedContainer(
- ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form)));
+ GetDocument()->GetLayoutProcessor()->SetHasChangedContainer();
return 0;
}
CJS_Result CJX_InstanceManager::moveInstance(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- CXFA_Document* doc = static_cast<CFXJSE_Engine*>(runtime)->GetDocument();
+ CXFA_Document* doc = runtime->GetDocument();
if (doc->GetFormType() != FormType::kXFAFull)
return CJS_Result::Failure(JSMessage::kNotSupportedError);
@@ -141,29 +146,28 @@
int32_t iFrom = runtime->ToInt32(params[0]);
int32_t iTo = runtime->ToInt32(params[1]);
- MoveInstance(iTo, iFrom);
+ MoveInstance(runtime->GetIsolate(), iTo, iFrom);
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (!pNotify)
return CJS_Result::Success();
- CXFA_Node* pToInstance = GetXFANode()->GetItemIfExists(iTo);
- if (pToInstance && pToInstance->GetElementType() == XFA_Element::Subform)
+ CXFA_Node* pXFA = GetXFANode();
+ auto* pToInstance = CXFA_Subform::FromNode(pXFA->GetItemIfExists(iTo));
+ if (pToInstance)
pNotify->RunSubformIndexChange(pToInstance);
- CXFA_Node* pFromInstance = GetXFANode()->GetItemIfExists(iFrom);
- if (pFromInstance &&
- pFromInstance->GetElementType() == XFA_Element::Subform) {
+ auto* pFromInstance = CXFA_Subform::FromNode(pXFA->GetItemIfExists(iFrom));
+ if (pFromInstance)
pNotify->RunSubformIndexChange(pFromInstance);
- }
return CJS_Result::Success();
}
CJS_Result CJX_InstanceManager::removeInstance(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- CXFA_Document* doc = static_cast<CFXJSE_Engine*>(runtime)->GetDocument();
+ CXFA_Document* doc = runtime->GetDocument();
if (doc->GetFormType() != FormType::kXFAFull)
return CJS_Result::Failure(JSMessage::kNotSupportedError);
@@ -178,7 +182,7 @@
CXFA_Occur* occur = GetXFANode()->GetOccurIfExists();
int32_t iMin = occur ? occur->GetMin() : CXFA_Occur::kDefaultMin;
if (iCount - 1 < iMin)
- return CJS_Result::Failure(JSMessage::kTooManyOccurances);
+ return CJS_Result::Failure(JSMessage::kTooManyOccurrences);
CXFA_Node* pRemoveInstance = GetXFANode()->GetItemIfExists(iIndex);
if (!pRemoveInstance)
@@ -188,37 +192,35 @@
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (pNotify) {
+ CXFA_Node* pXFA = GetXFANode();
for (int32_t i = iIndex; i < iCount - 1; i++) {
- CXFA_Node* pSubformInstance = GetXFANode()->GetItemIfExists(i);
- if (pSubformInstance &&
- pSubformInstance->GetElementType() == XFA_Element::Subform) {
+ auto* pSubformInstance = CXFA_Subform::FromNode(pXFA->GetItemIfExists(i));
+ if (pSubformInstance)
pNotify->RunSubformIndexChange(pSubformInstance);
- }
}
}
- GetDocument()->GetLayoutProcessor()->AddChangedContainer(
- ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form)));
+ GetDocument()->GetLayoutProcessor()->SetHasChangedContainer();
return CJS_Result::Success();
}
CJS_Result CJX_InstanceManager::setInstances(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- CXFA_Document* doc = static_cast<CFXJSE_Engine*>(runtime)->GetDocument();
+ CXFA_Document* doc = runtime->GetDocument();
if (doc->GetFormType() != FormType::kXFAFull)
return CJS_Result::Failure(JSMessage::kNotSupportedError);
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- SetInstances(runtime->ToInt32(params[0]));
+ SetInstances(runtime->GetIsolate(), runtime->ToInt32(params[0]));
return CJS_Result::Success();
}
CJS_Result CJX_InstanceManager::addInstance(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- CXFA_Document* doc = static_cast<CFXJSE_Engine*>(runtime)->GetDocument();
+ CXFA_Document* doc = runtime->GetDocument();
if (doc->GetFormType() != FormType::kXFAFull)
return CJS_Result::Failure(JSMessage::kNotSupportedError);
@@ -233,7 +235,7 @@
CXFA_Occur* occur = GetXFANode()->GetOccurIfExists();
int32_t iMax = occur ? occur->GetMax() : CXFA_Occur::kDefaultMax;
if (iMax >= 0 && iCount >= iMax)
- return CJS_Result::Failure(JSMessage::kTooManyOccurances);
+ return CJS_Result::Failure(JSMessage::kTooManyOccurrences);
CXFA_Node* pNewInstance = GetXFANode()->CreateInstanceIfPossible(fFlags);
if (!pNewInstance)
@@ -244,22 +246,18 @@
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (pNotify) {
pNotify->RunNodeInitialize(pNewInstance);
- GetDocument()->GetLayoutProcessor()->AddChangedContainer(
- ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form)));
+ GetDocument()->GetLayoutProcessor()->SetHasChangedContainer();
}
- CFXJSE_Value* value =
- GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
- pNewInstance);
-
return CJS_Result::Success(
- value->DirectGetValue().Get(runtime->GetIsolate()));
+ GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+ pNewInstance));
}
CJS_Result CJX_InstanceManager::insertInstance(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- CXFA_Document* doc = static_cast<CFXJSE_Engine*>(runtime)->GetDocument();
+ CXFA_Document* doc = runtime->GetDocument();
if (doc->GetFormType() != FormType::kXFAFull)
return CJS_Result::Failure(JSMessage::kNotSupportedError);
@@ -289,46 +287,47 @@
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (pNotify) {
pNotify->RunNodeInitialize(pNewInstance);
- GetDocument()->GetLayoutProcessor()->AddChangedContainer(
- ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form)));
+ GetDocument()->GetLayoutProcessor()->SetHasChangedContainer();
}
- CFXJSE_Value* value =
- GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
- pNewInstance);
-
return CJS_Result::Success(
- value->DirectGetValue().Get(runtime->GetIsolate()));
+ GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+ pNewInstance));
}
-void CJX_InstanceManager::max(CFXJSE_Value* pValue,
+void CJX_InstanceManager::max(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
CXFA_Occur* occur = GetXFANode()->GetOccurIfExists();
- pValue->SetInteger(occur ? occur->GetMax() : CXFA_Occur::kDefaultMax);
+ *pValue = fxv8::NewNumberHelper(
+ pIsolate, occur ? occur->GetMax() : CXFA_Occur::kDefaultMax);
}
-void CJX_InstanceManager::min(CFXJSE_Value* pValue,
+void CJX_InstanceManager::min(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
CXFA_Occur* occur = GetXFANode()->GetOccurIfExists();
- pValue->SetInteger(occur ? occur->GetMin() : CXFA_Occur::kDefaultMin);
+ *pValue = fxv8::NewNumberHelper(
+ pIsolate, occur ? occur->GetMin() : CXFA_Occur::kDefaultMin);
}
-void CJX_InstanceManager::count(CFXJSE_Value* pValue,
+void CJX_InstanceManager::count(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- SetInstances(pValue->ToInteger());
+ SetInstances(pIsolate, fxv8::ReentrantToInt32Helper(pIsolate, *pValue));
return;
}
- pValue->SetInteger(GetXFANode()->GetCount());
+ *pValue = fxv8::NewNumberHelper(pIsolate, GetXFANode()->GetCount());
}
diff --git a/fxjs/xfa/cjx_instancemanager.h b/fxjs/xfa/cjx_instancemanager.h
index 3fae9ab..96210e8 100644
--- a/fxjs/xfa/cjx_instancemanager.h
+++ b/fxjs/xfa/cjx_instancemanager.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,12 +9,13 @@
#include "fxjs/xfa/cjx_node.h"
#include "fxjs/xfa/jse_define.h"
+#include "v8/include/v8-forward.h"
class CXFA_InstanceManager;
class CJX_InstanceManager final : public CJX_Node {
public:
- explicit CJX_InstanceManager(CXFA_InstanceManager* mgr);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_InstanceManager() override;
// CJX_Object:
@@ -30,16 +31,18 @@
JSE_PROP(max);
JSE_PROP(min);
- int32_t MoveInstance(int32_t iTo, int32_t iFrom);
+ int32_t MoveInstance(v8::Isolate* pIsolate, int32_t iTo, int32_t iFrom);
private:
+ explicit CJX_InstanceManager(CXFA_InstanceManager* mgr);
+
using Type__ = CJX_InstanceManager;
using ParentType__ = CJX_Node;
static const TypeTag static_type__ = TypeTag::InstanceManager;
static const CJX_MethodSpec MethodSpecs[];
- int32_t SetInstances(int32_t iDesired);
+ int32_t SetInstances(v8::Isolate* pIsolate, int32_t iDesired);
};
#endif // FXJS_XFA_CJX_INSTANCEMANAGER_H_
diff --git a/fxjs/xfa/cjx_layoutpseudomodel.cpp b/fxjs/xfa/cjx_layoutpseudomodel.cpp
index 35852a8..484d883 100644
--- a/fxjs/xfa/cjx_layoutpseudomodel.cpp
+++ b/fxjs/xfa/cjx_layoutpseudomodel.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,12 +10,13 @@
#include <utility>
#include "core/fxcrt/fx_coordinates.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_class.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
+#include "third_party/base/containers/contains.h"
+#include "v8/include/cppgc/allocation.h"
+#include "v8/include/v8-object.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/layout/cxfa_contentlayoutitem.h"
#include "xfa/fxfa/layout/cxfa_layoutitem.h"
@@ -56,36 +57,39 @@
DefineMethods(MethodSpecs);
}
-CJX_LayoutPseudoModel::~CJX_LayoutPseudoModel() {}
+CJX_LayoutPseudoModel::~CJX_LayoutPseudoModel() = default;
bool CJX_LayoutPseudoModel::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_LayoutPseudoModel::ready(CFXJSE_Value* pValue,
+void CJX_LayoutPseudoModel::ready(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (!pNotify)
return;
if (bSetting) {
- ThrowException(WideString::FromASCII("Unable to set ready value."));
+ ThrowException(pIsolate,
+ WideString::FromASCII("Unable to set ready value."));
return;
}
- int32_t iStatus = pNotify->GetLayoutStatus();
- pValue->SetBoolean(iStatus >= 2);
+ CXFA_FFDocView::LayoutStatus iStatus = pNotify->GetLayoutStatus();
+ const bool bReady = iStatus != CXFA_FFDocView::LayoutStatus::kNone &&
+ iStatus != CXFA_FFDocView::LayoutStatus::kStart;
+ *pValue = fxv8::NewBooleanHelper(pIsolate, bReady);
}
-CJS_Result CJX_LayoutPseudoModel::HWXY(
- CFX_V8* runtime,
+CJS_Result CJX_LayoutPseudoModel::DoHWXYInternal(
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params,
- XFA_LAYOUTMODEL_HWXY layoutModel) {
+ HWXY layoutModel) {
if (params.empty() || params.size() > 3)
return CJS_Result::Failure(JSMessage::kParamError);
- CXFA_Node* pNode =
- ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
+ CXFA_Node* pNode = ToNode(runtime->ToXFAObject(params[0]));
if (!pNode)
return CJS_Result::Success();
@@ -111,18 +115,18 @@
return CJS_Result::Success(runtime->NewNumber(0.0));
CXFA_Measurement measure;
- CFX_RectF rtRect = pLayoutItem->GetRect(true);
+ CFX_RectF rtRect = pLayoutItem->GetRelativeRect();
switch (layoutModel) {
- case XFA_LAYOUTMODEL_H:
+ case HWXY::kH:
measure.Set(rtRect.height, XFA_Unit::Pt);
break;
- case XFA_LAYOUTMODEL_W:
+ case HWXY::kW:
measure.Set(rtRect.width, XFA_Unit::Pt);
break;
- case XFA_LAYOUTMODEL_X:
+ case HWXY::kX:
measure.Set(rtRect.left, XFA_Unit::Pt);
break;
- case XFA_LAYOUTMODEL_Y:
+ case HWXY::kY:
measure.Set(rtRect.top, XFA_Unit::Pt);
break;
}
@@ -137,64 +141,63 @@
}
CJS_Result CJX_LayoutPseudoModel::h(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- return HWXY(runtime, params, XFA_LAYOUTMODEL_H);
+ return DoHWXYInternal(runtime, params, HWXY::kH);
}
CJS_Result CJX_LayoutPseudoModel::w(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- return HWXY(runtime, params, XFA_LAYOUTMODEL_W);
+ return DoHWXYInternal(runtime, params, HWXY::kW);
}
CJS_Result CJX_LayoutPseudoModel::x(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- return HWXY(runtime, params, XFA_LAYOUTMODEL_X);
+ return DoHWXYInternal(runtime, params, HWXY::kX);
}
CJS_Result CJX_LayoutPseudoModel::y(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- return HWXY(runtime, params, XFA_LAYOUTMODEL_Y);
+ return DoHWXYInternal(runtime, params, HWXY::kY);
}
-CJS_Result CJX_LayoutPseudoModel::NumberedPageCount(CFX_V8* runtime,
- bool bNumbered) {
+CJS_Result CJX_LayoutPseudoModel::AllPageCount(CFXJSE_Engine* runtime) {
+ auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(GetDocument());
+ return CJS_Result::Success(runtime->NewNumber(pDocLayout->CountPages()));
+}
+
+CJS_Result CJX_LayoutPseudoModel::NumberedPageCount(CFXJSE_Engine* runtime) {
auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(GetDocument());
int32_t iPageCount = 0;
int32_t iPageNum = pDocLayout->CountPages();
- if (bNumbered) {
- for (int32_t i = 0; i < iPageNum; i++) {
- CXFA_ViewLayoutItem* pLayoutPage = pDocLayout->GetPage(i);
- if (!pLayoutPage)
- continue;
+ for (int32_t i = 0; i < iPageNum; i++) {
+ CXFA_ViewLayoutItem* pLayoutPage = pDocLayout->GetPage(i);
+ if (!pLayoutPage)
+ continue;
- CXFA_Node* pMasterPage = pLayoutPage->GetMasterPage();
- if (pMasterPage->JSObject()->GetInteger(XFA_Attribute::Numbered))
- iPageCount++;
- }
- } else {
- iPageCount = iPageNum;
+ CXFA_Node* pMasterPage = pLayoutPage->GetMasterPage();
+ if (pMasterPage->JSObject()->GetInteger(XFA_Attribute::Numbered))
+ iPageCount++;
}
return CJS_Result::Success(runtime->NewNumber(iPageCount));
}
CJS_Result CJX_LayoutPseudoModel::pageCount(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- return NumberedPageCount(runtime, true);
+ return NumberedPageCount(runtime);
}
CJS_Result CJX_LayoutPseudoModel::pageSpan(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- CXFA_Node* pNode =
- ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
+ CXFA_Node* pNode = ToNode(runtime->ToXFAObject(params[0]));
if (!pNode)
return CJS_Result::Success();
@@ -211,7 +214,7 @@
}
CJS_Result CJX_LayoutPseudoModel::page(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return PageInternals(runtime, params, false);
}
@@ -261,7 +264,7 @@
eType != XFA_Element::Subform && eType != XFA_Element::Area) {
continue;
}
- if (pdfium::ContainsValue(formItems, pItemChild->GetFormNode()))
+ if (pdfium::Contains(formItems, pItemChild->GetFormNode()))
continue;
formItems.insert(pItemChild->GetFormNode());
@@ -282,7 +285,7 @@
eType != XFA_Element::Subform && eType != XFA_Element::Area) {
continue;
}
- if (pdfium::ContainsValue(formItems, pItemChild->GetFormNode()))
+ if (pdfium::Contains(formItems, pItemChild->GetFormNode()))
continue;
formItems.insert(pItemChild->GetFormNode());
@@ -317,7 +320,7 @@
continue;
if (pItemChild->GetFormNode()->GetElementType() != eType)
continue;
- if (pdfium::ContainsValue(formItems, pItemChild->GetFormNode()))
+ if (pdfium::Contains(formItems, pItemChild->GetFormNode()))
continue;
formItems.insert(pItemChild->GetFormNode());
@@ -334,7 +337,7 @@
continue;
if (pItemChild->GetFormNode()->GetElementType() != eType)
continue;
- if (pdfium::ContainsValue(formItems, pItemChild->GetFormNode()))
+ if (pdfium::Contains(formItems, pItemChild->GetFormNode()))
continue;
formItems.insert(pItemChild->GetFormNode());
@@ -348,7 +351,7 @@
}
CJS_Result CJX_LayoutPseudoModel::pageContent(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 3)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -369,59 +372,57 @@
if (!pNotify)
return CJS_Result::Success();
- auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(GetDocument());
- auto pArrayNodeList = pdfium::MakeUnique<CXFA_ArrayNodeList>(GetDocument());
+ CXFA_Document* pDoc = GetDocument();
+ auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(pDoc);
+ auto* pArrayNodeList = cppgc::MakeGarbageCollected<CXFA_ArrayNodeList>(
+ pDoc->GetHeap()->GetAllocationHandle(), pDoc);
+ pDoc->GetNodeOwner()->PersistList(pArrayNodeList);
pArrayNodeList->SetArrayNodeList(
GetObjArray(pDocLayout, iIndex, wsType, bOnPageArea));
-
- // TODO(dsinclair): Who owns the array once we release it? Won't this leak?
- return CJS_Result::Success(static_cast<CFXJSE_Engine*>(runtime)->NewXFAObject(
- pArrayNodeList.release(),
- GetDocument()->GetScriptContext()->GetJseNormalClass()->GetTemplate()));
+ return CJS_Result::Success(runtime->NewNormalXFAObject(pArrayNodeList));
}
CJS_Result CJX_LayoutPseudoModel::absPageCount(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- return NumberedPageCount(runtime, false);
+ return AllPageCount(runtime);
}
CJS_Result CJX_LayoutPseudoModel::absPageCountInBatch(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success(runtime->NewNumber(0));
}
CJS_Result CJX_LayoutPseudoModel::sheetCountInBatch(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success(runtime->NewNumber(0));
}
CJS_Result CJX_LayoutPseudoModel::relayout(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
CXFA_Node* pRootNode = GetDocument()->GetRoot();
auto* pLayoutProcessor = GetDocument()->GetLayoutProcessor();
CXFA_Form* pFormRoot =
pRootNode->GetFirstChildByClass<CXFA_Form>(XFA_Element::Form);
if (pFormRoot) {
- CXFA_Node* pContentRootNode = pFormRoot->GetFirstChild();
- if (pContentRootNode)
- pLayoutProcessor->AddChangedContainer(pContentRootNode);
+ if (pFormRoot->GetFirstChild())
+ pLayoutProcessor->SetHasChangedContainer();
}
- pLayoutProcessor->SetForceRelayout(true);
+ pLayoutProcessor->SetForceRelayout();
return CJS_Result::Success();
}
CJS_Result CJX_LayoutPseudoModel::absPageSpan(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return pageSpan(runtime, params);
}
CJS_Result CJX_LayoutPseudoModel::absPageInBatch(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -430,7 +431,7 @@
}
CJS_Result CJX_LayoutPseudoModel::sheetInBatch(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -439,38 +440,37 @@
}
CJS_Result CJX_LayoutPseudoModel::sheet(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return PageInternals(runtime, params, true);
}
CJS_Result CJX_LayoutPseudoModel::relayoutPageArea(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
CJS_Result CJX_LayoutPseudoModel::sheetCount(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
- return NumberedPageCount(runtime, false);
+ return AllPageCount(runtime);
}
CJS_Result CJX_LayoutPseudoModel::absPage(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return PageInternals(runtime, params, true);
}
CJS_Result CJX_LayoutPseudoModel::PageInternals(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params,
bool bAbsPage) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- CXFA_Node* pNode =
- ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
+ CXFA_Node* pNode = ToNode(runtime->ToXFAObject(params[0]));
if (!pNode)
return CJS_Result::Success(runtime->NewNumber(0));
diff --git a/fxjs/xfa/cjx_layoutpseudomodel.h b/fxjs/xfa/cjx_layoutpseudomodel.h
index d5f0cba..80cf310 100644
--- a/fxjs/xfa/cjx_layoutpseudomodel.h
+++ b/fxjs/xfa/cjx_layoutpseudomodel.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,21 +12,13 @@
#include "fxjs/xfa/cjx_object.h"
#include "fxjs/xfa/jse_define.h"
-enum XFA_LAYOUTMODEL_HWXY {
- XFA_LAYOUTMODEL_H,
- XFA_LAYOUTMODEL_W,
- XFA_LAYOUTMODEL_X,
- XFA_LAYOUTMODEL_Y
-};
-
-class CFXJSE_Value;
class CScript_LayoutPseudoModel;
class CXFA_LayoutProcessor;
class CXFA_Node;
class CJX_LayoutPseudoModel final : public CJX_Object {
public:
- explicit CJX_LayoutPseudoModel(CScript_LayoutPseudoModel* model);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_LayoutPseudoModel() override;
// CJX_Object:
@@ -55,21 +47,26 @@
JSE_PROP(ready);
private:
+ enum class HWXY { kH, kW, kX, kY };
+
+ explicit CJX_LayoutPseudoModel(CScript_LayoutPseudoModel* model);
+
using Type__ = CJX_LayoutPseudoModel;
using ParentType__ = CJX_Object;
static const TypeTag static_type__ = TypeTag::LayoutPseudoModel;
static const CJX_MethodSpec MethodSpecs[];
- CJS_Result NumberedPageCount(CFX_V8* runtime, bool bNumbered);
- CJS_Result HWXY(CFX_V8* runtime,
- const std::vector<v8::Local<v8::Value>>& params,
- XFA_LAYOUTMODEL_HWXY layoutModel);
+ CJS_Result AllPageCount(CFXJSE_Engine* runtime);
+ CJS_Result NumberedPageCount(CFXJSE_Engine* runtime);
+ CJS_Result DoHWXYInternal(CFXJSE_Engine* runtime,
+ const std::vector<v8::Local<v8::Value>>& params,
+ HWXY layoutModel);
std::vector<CXFA_Node*> GetObjArray(CXFA_LayoutProcessor* pDocLayout,
int32_t iPageNo,
const WideString& wsType,
bool bOnPageArea);
- CJS_Result PageInternals(CFX_V8* runtime,
+ CJS_Result PageInternals(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params,
bool bAbsPage);
};
diff --git a/fxjs/xfa/cjx_list.cpp b/fxjs/xfa/cjx_list.cpp
index 7c0cf23..8c4735d 100644
--- a/fxjs/xfa/cjx_list.cpp
+++ b/fxjs/xfa/cjx_list.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,11 +8,13 @@
#include <vector>
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_class.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
#include "third_party/base/numerics/safe_conversions.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_list.h"
#include "xfa/fxfa/parser/cxfa_node.h"
@@ -26,7 +28,7 @@
DefineMethods(MethodSpecs);
}
-CJX_List::~CJX_List() {}
+CJX_List::~CJX_List() = default;
bool CJX_List::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
@@ -36,45 +38,43 @@
return ToList(GetXFAObject());
}
-CJS_Result CJX_List::append(CFX_V8* runtime,
+CJS_Result CJX_List::append(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- auto* pNode =
- ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
+ auto* pNode = ToNode(runtime->ToXFAObject(params[0]));
if (!pNode)
return CJS_Result::Failure(JSMessage::kValueError);
- GetXFAList()->Append(pNode);
+ if (!GetXFAList()->Append(pNode))
+ return CJS_Result::Failure(JSMessage::kWouldBeCyclic);
+
return CJS_Result::Success();
}
-CJS_Result CJX_List::insert(CFX_V8* runtime,
+CJS_Result CJX_List::insert(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 2)
return CJS_Result::Failure(JSMessage::kParamError);
- auto* pNewNode =
- ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
+ auto* pNewNode = ToNode(runtime->ToXFAObject(params[0]));
if (!pNewNode)
return CJS_Result::Failure(JSMessage::kValueError);
- auto* pBeforeNode =
- ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[1]));
+ auto* pBeforeNode = ToNode(runtime->ToXFAObject(params[1]));
if (!GetXFAList()->Insert(pNewNode, pBeforeNode))
return CJS_Result::Failure(JSMessage::kValueError);
return CJS_Result::Success();
}
-CJS_Result CJX_List::remove(CFX_V8* runtime,
+CJS_Result CJX_List::remove(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- auto* pNode =
- ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
+ auto* pNode = ToNode(runtime->ToXFAObject(params[0]));
if (!pNode)
return CJS_Result::Failure(JSMessage::kValueError);
@@ -82,7 +82,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_List::item(CFX_V8* runtime,
+CJS_Result CJX_List::item(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -92,18 +92,18 @@
if (index < 0 || cast_index >= GetXFAList()->GetLength())
return CJS_Result::Failure(JSMessage::kInvalidInputError);
- return CJS_Result::Success(static_cast<CFXJSE_Engine*>(runtime)->NewXFAObject(
- GetXFAList()->Item(cast_index),
- GetDocument()->GetScriptContext()->GetJseNormalClass()->GetTemplate()));
+ return CJS_Result::Success(
+ runtime->NewNormalXFAObject(GetXFAList()->Item(cast_index)));
}
-void CJX_List::length(CFXJSE_Value* pValue,
+void CJX_List::length(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- pValue->SetInteger(
- pdfium::base::checked_cast<int32_t>(GetXFAList()->GetLength()));
+ *pValue = fxv8::NewNumberHelper(
+ pIsolate, pdfium::base::checked_cast<int32_t>(GetXFAList()->GetLength()));
}
diff --git a/fxjs/xfa/cjx_list.h b/fxjs/xfa/cjx_list.h
index 842b859..4471867 100644
--- a/fxjs/xfa/cjx_list.h
+++ b/fxjs/xfa/cjx_list.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_List : public CJX_Object {
public:
- explicit CJX_List(CXFA_List* list);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_List() override;
// CJX_Object:
@@ -27,6 +27,9 @@
JSE_PROP(length);
+ protected:
+ explicit CJX_List(CXFA_List* list);
+
private:
using Type__ = CJX_List;
using ParentType__ = CJX_Object;
diff --git a/fxjs/xfa/cjx_list_embeddertest.cpp b/fxjs/xfa/cjx_list_embeddertest.cpp
index 02450dc..17d2de4 100644
--- a/fxjs/xfa/cjx_list_embeddertest.cpp
+++ b/fxjs/xfa/cjx_list_embeddertest.cpp
@@ -1,4 +1,4 @@
-// Copyright 2019 PDFium Authors. All rights reserved.
+// Copyright 2019 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
diff --git a/fxjs/xfa/cjx_logpseudomodel.cpp b/fxjs/xfa/cjx_logpseudomodel.cpp
index 8cb9ee7..a100697 100644
--- a/fxjs/xfa/cjx_logpseudomodel.cpp
+++ b/fxjs/xfa/cjx_logpseudomodel.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -23,14 +23,14 @@
DefineMethods(MethodSpecs);
}
-CJX_LogPseudoModel::~CJX_LogPseudoModel() {}
+CJX_LogPseudoModel::~CJX_LogPseudoModel() = default;
bool CJX_LogPseudoModel::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_LogPseudoModel::message(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
// Uncomment to allow using xfa.log.message(""); from JS.
// fprintf(stderr, "LOG\n");
@@ -43,25 +43,25 @@
}
CJS_Result CJX_LogPseudoModel::traceEnabled(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
CJS_Result CJX_LogPseudoModel::traceActivate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
CJS_Result CJX_LogPseudoModel::traceDeactivate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
CJS_Result CJX_LogPseudoModel::trace(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
diff --git a/fxjs/xfa/cjx_logpseudomodel.h b/fxjs/xfa/cjx_logpseudomodel.h
index fda3bb9..030d1df 100644
--- a/fxjs/xfa/cjx_logpseudomodel.h
+++ b/fxjs/xfa/cjx_logpseudomodel.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
// xfa_basic_data_element_script is removed.
class CJX_LogPseudoModel final : public CJX_Object {
public:
- explicit CJX_LogPseudoModel(CScript_LogPseudoModel* model);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_LogPseudoModel() override;
// CJX_Object:
@@ -29,6 +29,8 @@
JSE_METHOD(trace);
private:
+ explicit CJX_LogPseudoModel(CScript_LogPseudoModel* model);
+
using Type__ = CJX_LogPseudoModel;
using ParentType__ = CJX_Object;
diff --git a/fxjs/xfa/cjx_manifest.cpp b/fxjs/xfa/cjx_manifest.cpp
index f94232e..7d4e6e6 100644
--- a/fxjs/xfa/cjx_manifest.cpp
+++ b/fxjs/xfa/cjx_manifest.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include "fxjs/cfx_v8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/parser/cxfa_manifest.h"
const CJX_MethodSpec CJX_Manifest::MethodSpecs[] = {
@@ -20,14 +21,14 @@
DefineMethods(MethodSpecs);
}
-CJX_Manifest::~CJX_Manifest() {}
+CJX_Manifest::~CJX_Manifest() = default;
bool CJX_Manifest::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_Manifest::evaluate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
diff --git a/fxjs/xfa/cjx_manifest.h b/fxjs/xfa/cjx_manifest.h
index 8380ac6..0f95648 100644
--- a/fxjs/xfa/cjx_manifest.h
+++ b/fxjs/xfa/cjx_manifest.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Manifest final : public CJX_Node {
public:
- explicit CJX_Manifest(CXFA_Manifest* manifest);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Manifest() override;
// CJX_Object:
@@ -23,6 +23,8 @@
JSE_METHOD(evaluate);
private:
+ explicit CJX_Manifest(CXFA_Manifest* manifest);
+
using Type__ = CJX_Manifest;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_model.cpp b/fxjs/xfa/cjx_model.cpp
index 4fa0a2e..21a767d 100644
--- a/fxjs/xfa/cjx_model.cpp
+++ b/fxjs/xfa/cjx_model.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_engine.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-object.h"
#include "xfa/fxfa/parser/cxfa_delta.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/xfa_basic_data.h"
@@ -24,20 +25,20 @@
DefineMethods(MethodSpecs);
}
-CJX_Model::~CJX_Model() {}
+CJX_Model::~CJX_Model() = default;
bool CJX_Model::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_Model::clearErrorList(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
return CJS_Result::Success();
}
CJS_Result CJX_Model::createNode(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 3)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -60,21 +61,19 @@
if (!pNewNode->HasAttribute(XFA_Attribute::Name))
return CJS_Result::Failure(JSMessage::kParamError);
- pNewNode->JSObject()->SetAttribute(XFA_Attribute::Name, name.AsStringView(),
- true);
+ pNewNode->JSObject()->SetAttributeByEnum(XFA_Attribute::Name, name, true);
if (pNewNode->GetPacketType() == XFA_PacketType::Datasets)
pNewNode->CreateXMLMappingNode();
}
- CFXJSE_Value* value =
+ v8::Local<v8::Value> value =
GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNewNode);
- return CJS_Result::Success(
- value->DirectGetValue().Get(runtime->GetIsolate()));
+ return CJS_Result::Success(value);
}
CJS_Result CJX_Model::isCompatibleNS(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -87,10 +86,12 @@
runtime->NewBoolean(TryNamespace().value_or(WideString()) == nameSpace));
}
-void CJX_Model::context(CFXJSE_Value* pValue,
+void CJX_Model::context(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
-void CJX_Model::aliasNode(CFXJSE_Value* pValue,
+void CJX_Model::aliasNode(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_model.h b/fxjs/xfa/cjx_model.h
index 9fd54f5..7b0e17e 100644
--- a/fxjs/xfa/cjx_model.h
+++ b/fxjs/xfa/cjx_model.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Model : public CJX_Node {
public:
- explicit CJX_Model(CXFA_Node* obj);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Model() override;
// CJX_Object:
@@ -27,6 +27,9 @@
JSE_PROP(aliasNode);
JSE_PROP(context);
+ protected:
+ explicit CJX_Model(CXFA_Node* obj);
+
private:
using Type__ = CJX_Model;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_node.cpp b/fxjs/xfa/cjx_node.cpp
index 3877f72..0685107 100644
--- a/fxjs/xfa/cjx_node.cpp
+++ b/fxjs/xfa/cjx_node.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,25 +11,27 @@
#include <vector>
#include "core/fxcrt/cfx_memorystream.h"
+#include "core/fxcrt/cfx_read_only_string_stream.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/xml/cfx_xmldocument.h"
-#include "core/fxcrt/xml/cfx_xmlnode.h"
+#include "core/fxcrt/xml/cfx_xmlelement.h"
+#include "core/fxcrt/xml/cfx_xmlparser.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
-#include "third_party/base/ptr_util.h"
+#include "v8/include/v8-object.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cxfa_document.h"
-#include "xfa/fxfa/parser/cxfa_document_parser.h"
+#include "xfa/fxfa/parser/cxfa_document_builder.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/xfa_basic_data.h"
#include "xfa/fxfa/parser/xfa_utils.h"
namespace {
-enum class EventAppliesToo : uint8_t {
+enum class EventAppliesTo : uint8_t {
kNone = 0,
kAll = 1,
kAllNonRecursive = 2,
@@ -40,90 +42,47 @@
kChoiceList = 7
};
-struct XFA_ExecEventParaInfo {
- public:
+struct ExecEventParaInfo {
uint32_t m_uHash; // hashed as wide string.
XFA_EVENTTYPE m_eventType;
- EventAppliesToo m_validFlags;
+ EventAppliesTo m_validFlags;
};
#undef PARA
-#define PARA(a, b, c, d) a, c, d
-const XFA_ExecEventParaInfo gs_eventParaInfos[] = {
- {PARA(0x109d7ce7,
- "mouseEnter",
- XFA_EVENT_MouseEnter,
- EventAppliesToo::kField)},
- {PARA(0x1bfc72d9,
- "preOpen",
- XFA_EVENT_PreOpen,
- EventAppliesToo::kChoiceList)},
- {PARA(0x2196a452,
- "initialize",
- XFA_EVENT_Initialize,
- EventAppliesToo::kAll)},
- {PARA(0x27410f03,
- "mouseExit",
- XFA_EVENT_MouseExit,
- EventAppliesToo::kField)},
- {PARA(0x36f1c6d8,
- "preSign",
- XFA_EVENT_PreSign,
- EventAppliesToo::kSignature)},
- {PARA(0x4731d6ba,
- "exit",
- XFA_EVENT_Exit,
- EventAppliesToo::kAllNonRecursive)},
- {PARA(0x7233018a, "validate", XFA_EVENT_Validate, EventAppliesToo::kAll)},
- {PARA(0x8808385e,
- "indexChange",
- XFA_EVENT_IndexChange,
- EventAppliesToo::kSubform)},
- {PARA(0x891f4606,
- "change",
- XFA_EVENT_Change,
- EventAppliesToo::kFieldOrExclusion)},
- {PARA(0x9f693b21,
- "mouseDown",
- XFA_EVENT_MouseDown,
- EventAppliesToo::kField)},
- {PARA(0xcdce56b3,
- "full",
- XFA_EVENT_Full,
- EventAppliesToo::kFieldOrExclusion)},
- {PARA(0xd576d08e, "mouseUp", XFA_EVENT_MouseUp, EventAppliesToo::kField)},
- {PARA(0xd95657a6,
- "click",
- XFA_EVENT_Click,
- EventAppliesToo::kFieldOrExclusion)},
- {PARA(0xdbfbe02e, "calculate", XFA_EVENT_Calculate, EventAppliesToo::kAll)},
- {PARA(0xe25fa7b8,
- "postOpen",
- XFA_EVENT_PostOpen,
- EventAppliesToo::kChoiceList)},
- {PARA(0xe28dce7e,
- "enter",
- XFA_EVENT_Enter,
- EventAppliesToo::kAllNonRecursive)},
- {PARA(0xfd54fbb7,
- "postSign",
- XFA_EVENT_PostSign,
- EventAppliesToo::kSignature)},
+#define PARA(a, b, c, d) a, c, EventAppliesTo::d
+const ExecEventParaInfo kExecEventParaInfoTable[] = {
+ {PARA(0x109d7ce7, "mouseEnter", XFA_EVENT_MouseEnter, kField)},
+ {PARA(0x1bfc72d9, "preOpen", XFA_EVENT_PreOpen, kChoiceList)},
+ {PARA(0x2196a452, "initialize", XFA_EVENT_Initialize, kAll)},
+ {PARA(0x27410f03, "mouseExit", XFA_EVENT_MouseExit, kField)},
+ {PARA(0x36f1c6d8, "preSign", XFA_EVENT_PreSign, kSignature)},
+ {PARA(0x4731d6ba, "exit", XFA_EVENT_Exit, kAllNonRecursive)},
+ {PARA(0x7233018a, "validate", XFA_EVENT_Validate, kAll)},
+ {PARA(0x8808385e, "indexChange", XFA_EVENT_IndexChange, kSubform)},
+ {PARA(0x891f4606, "change", XFA_EVENT_Change, kFieldOrExclusion)},
+ {PARA(0x9f693b21, "mouseDown", XFA_EVENT_MouseDown, kField)},
+ {PARA(0xcdce56b3, "full", XFA_EVENT_Full, kFieldOrExclusion)},
+ {PARA(0xd576d08e, "mouseUp", XFA_EVENT_MouseUp, kField)},
+ {PARA(0xd95657a6, "click", XFA_EVENT_Click, kFieldOrExclusion)},
+ {PARA(0xdbfbe02e, "calculate", XFA_EVENT_Calculate, kAll)},
+ {PARA(0xe25fa7b8, "postOpen", XFA_EVENT_PostOpen, kChoiceList)},
+ {PARA(0xe28dce7e, "enter", XFA_EVENT_Enter, kAllNonRecursive)},
+ {PARA(0xfd54fbb7, "postSign", XFA_EVENT_PostSign, kSignature)},
};
#undef PARA
-const XFA_ExecEventParaInfo* GetEventParaInfoByName(
+const ExecEventParaInfo* GetExecEventParaInfoByName(
WideStringView wsEventName) {
if (wsEventName.IsEmpty())
return nullptr;
- uint32_t uHash = FX_HashCode_GetW(wsEventName, false);
+ uint32_t uHash = FX_HashCode_GetW(wsEventName);
auto* result = std::lower_bound(
- std::begin(gs_eventParaInfos), std::end(gs_eventParaInfos), uHash,
- [](const XFA_ExecEventParaInfo& iter, const uint16_t& hash) {
+ std::begin(kExecEventParaInfoTable), std::end(kExecEventParaInfoTable),
+ uHash, [](const ExecEventParaInfo& iter, const uint16_t& hash) {
return iter.m_uHash < hash;
});
- if (result != std::end(gs_eventParaInfos) && result->m_uHash == uHash)
+ if (result != std::end(kExecEventParaInfoTable) && result->m_uHash == uHash)
return result;
return nullptr;
}
@@ -153,11 +112,7 @@
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-CXFA_Node* CJX_Node::GetXFANode() const {
- return ToNode(GetXFAObject());
-}
-
-CJS_Result CJX_Node::applyXSL(CFX_V8* runtime,
+CJS_Result CJX_Node::applyXSL(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -167,7 +122,7 @@
}
CJS_Result CJX_Node::assignNode(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 3)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -176,33 +131,30 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Node::clone(CFX_V8* runtime,
+CJS_Result CJX_Node::clone(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
CXFA_Node* pCloneNode = GetXFANode()->Clone(runtime->ToBoolean(params[0]));
- CFXJSE_Value* value =
- GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
- pCloneNode);
-
return CJS_Result::Success(
- value->DirectGetValue().Get(runtime->GetIsolate()));
+ GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+ pCloneNode));
}
CJS_Result CJX_Node::getAttribute(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
WideString expression = runtime->ToWideString(params[0]);
return CJS_Result::Success(runtime->NewString(
- GetAttribute(expression.AsStringView()).ToUTF8().AsStringView()));
+ GetAttributeByString(expression.AsStringView()).ToUTF8().AsStringView()));
}
CJS_Result CJX_Node::getElement(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 2)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -217,21 +169,18 @@
if (!pNode)
return CJS_Result::Success(runtime->NewNull());
- CFXJSE_Value* value =
- GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode);
-
return CJS_Result::Success(
- value->DirectGetValue().Get(runtime->GetIsolate()));
+ GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode));
}
CJS_Result CJX_Node::isPropertySpecified(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 3)
return CJS_Result::Failure(JSMessage::kParamError);
WideString expression = runtime->ToWideString(params[0]);
- Optional<XFA_ATTRIBUTEINFO> attr =
+ absl::optional<XFA_ATTRIBUTEINFO> attr =
XFA_GetAttributeByName(expression.AsStringView());
if (attr.has_value() && HasAttribute(attr.value().attribute))
return CJS_Result::Success(runtime->NewBoolean(true));
@@ -252,7 +201,7 @@
return CJS_Result::Success(runtime->NewBoolean(bHas));
}
-CJS_Result CJX_Node::loadXML(CFX_V8* runtime,
+CJS_Result CJX_Node::loadXML(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 3)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -265,18 +214,23 @@
if (params.size() >= 2)
bIgnoreRoot = runtime->ToBoolean(params[1]);
- bool bOverwrite = 0;
+ bool bOverwrite = false;
if (params.size() >= 3)
bOverwrite = runtime->ToBoolean(params[2]);
- auto pParser = pdfium::MakeUnique<CXFA_DocumentParser>(GetDocument());
- CFX_XMLNode* pXMLNode = pParser->ParseXMLData(expression);
+ auto stream =
+ pdfium::MakeRetain<CFX_ReadOnlyStringStream>(std::move(expression));
+
+ CFX_XMLParser parser(stream);
+ std::unique_ptr<CFX_XMLDocument> xml_doc = parser.Parse();
+ CXFA_DocumentBuilder builder(GetDocument());
+ CFX_XMLNode* pXMLNode = builder.Build(xml_doc.get());
if (!pXMLNode)
return CJS_Result::Success();
CFX_XMLDocument* top_xml_doc =
- GetXFANode()->GetDocument()->GetNotify()->GetHDOC()->GetXMLDocument();
- top_xml_doc->AppendNodesFrom(pParser->GetXMLDoc().get());
+ GetXFANode()->GetDocument()->GetNotify()->GetFFDoc()->GetXMLDocument();
+ top_xml_doc->AppendNodesFrom(xml_doc.get());
if (bIgnoreRoot &&
(pXMLNode->GetType() != CFX_XMLNode::Type::kElement ||
@@ -288,7 +242,7 @@
WideString wsContentType = GetCData(XFA_Attribute::ContentType);
if (!wsContentType.IsEmpty()) {
pFakeRoot->JSObject()->SetCData(XFA_Attribute::ContentType,
- WideString(wsContentType), false, false);
+ WideString(wsContentType));
}
CFX_XMLNode* pFakeXMLRoot = pFakeRoot->GetXMLMappingNode();
@@ -317,8 +271,8 @@
pFakeXMLRoot->AppendLastChild(pXMLNode);
}
- pParser->ConstructXFANode(pFakeRoot, pFakeXMLRoot);
- pFakeRoot = pParser->GetRootNode();
+ builder.ConstructXFANode(pFakeRoot, pFakeXMLRoot);
+ pFakeRoot = builder.GetRootNode();
if (!pFakeRoot)
return CJS_Result::Success();
@@ -330,7 +284,7 @@
CXFA_Node* pItem = pNewChild->GetNextSibling();
pFakeRoot->RemoveChildAndNotify(pNewChild, true);
GetXFANode()->InsertChildAndNotify(index++, pNewChild);
- pNewChild->SetFlagAndNotify(XFA_NodeFlag_Initialized);
+ pNewChild->SetInitializedFlagAndNotify();
pNewChild = pItem;
}
@@ -358,7 +312,7 @@
CXFA_Node* pItem = pChild->GetNextSibling();
pFakeRoot->RemoveChildAndNotify(pChild, true);
GetXFANode()->InsertChildAndNotify(pChild, nullptr);
- pChild->SetFlagAndNotify(XFA_NodeFlag_Initialized);
+ pChild->SetInitializedFlagAndNotify();
pChild = pItem;
}
}
@@ -366,19 +320,19 @@
if (pFakeXMLRoot) {
pFakeRoot->SetXMLMappingNode(std::move(pFakeXMLRoot));
}
- pFakeRoot->SetFlag(XFA_NodeFlag_HasRemovedChildren);
+ pFakeRoot->SetFlag(XFA_NodeFlag::kHasRemovedChildren);
return CJS_Result::Success();
}
CJS_Result CJX_Node::saveFilteredXML(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
// TODO(weili): Check whether we need to implement this, pdfium:501.
return CJS_Result::Success();
}
-CJS_Result CJX_Node::saveXML(CFX_V8* runtime,
+CJS_Result CJX_Node::saveXML(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() > 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -416,12 +370,12 @@
pElement->Save(pMemoryStream);
}
- return CJS_Result::Success(runtime->NewString(
- ByteStringView(pMemoryStream->GetBuffer(), pMemoryStream->GetSize())));
+ return CJS_Result::Success(
+ runtime->NewString(ByteStringView(pMemoryStream->GetSpan())));
}
CJS_Result CJX_Node::setAttribute(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 2)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -432,12 +386,12 @@
WideString attribute = runtime->ToWideString(params[1]);
// Pass them to our method, however, in the more usual manner.
- SetAttribute(attribute.AsStringView(), attributeValue.AsStringView(), true);
+ SetAttributeByString(attribute.AsStringView(), attributeValue);
return CJS_Result::Success();
}
CJS_Result CJX_Node::setElement(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1 && params.size() != 2)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -446,66 +400,75 @@
return CJS_Result::Success();
}
-void CJX_Node::ns(CFXJSE_Value* pValue,
+void CJX_Node::ns(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- pValue->SetString(
- TryNamespace().value_or(WideString()).ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(
+ pIsolate, TryNamespace().value_or(WideString()).ToUTF8().AsStringView());
}
-void CJX_Node::model(CFXJSE_Value* pValue,
+void CJX_Node::model(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- pValue->Assign(GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
- GetXFANode()->GetModelNode()));
+ CXFA_Node* pModel = GetXFANode()->GetModelNode();
+ if (!pModel) {
+ *pValue = fxv8::NewNullHelper(pIsolate);
+ return;
+ }
+ *pValue =
+ GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pModel);
}
-void CJX_Node::isContainer(CFXJSE_Value* pValue,
+void CJX_Node::isContainer(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- pValue->SetBoolean(GetXFANode()->IsContainerNode());
+ *pValue = fxv8::NewBooleanHelper(pIsolate, GetXFANode()->IsContainerNode());
}
-void CJX_Node::isNull(CFXJSE_Value* pValue,
+void CJX_Node::isNull(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
if (GetXFANode()->GetElementType() == XFA_Element::Subform) {
- pValue->SetBoolean(false);
+ *pValue = fxv8::NewBooleanHelper(pIsolate, false);
return;
}
- pValue->SetBoolean(GetContent(false).IsEmpty());
+ *pValue = fxv8::NewBooleanHelper(pIsolate, GetContent(false).IsEmpty());
}
-void CJX_Node::oneOfChild(CFXJSE_Value* pValue,
+void CJX_Node::oneOfChild(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
std::vector<CXFA_Node*> properties =
- GetXFANode()->GetNodeListWithFilter(XFA_NODEFILTER_OneOfProperty);
+ GetXFANode()->GetNodeListWithFilter(XFA_NodeFilter::kOneOfProperty);
if (!properties.empty()) {
- pValue->Assign(
- GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
- properties.front()));
+ *pValue = GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+ properties.front());
}
}
@@ -515,26 +478,26 @@
if (!pNotify)
return XFA_EventError::kNotExist;
- const XFA_ExecEventParaInfo* eventParaInfo =
- GetEventParaInfoByName(wsEventName);
+ const ExecEventParaInfo* eventParaInfo =
+ GetExecEventParaInfoByName(wsEventName);
if (!eventParaInfo)
return XFA_EventError::kNotExist;
switch (eventParaInfo->m_validFlags) {
- case EventAppliesToo::kNone:
+ case EventAppliesTo::kNone:
return XFA_EventError::kNotExist;
- case EventAppliesToo::kAll:
- case EventAppliesToo::kAllNonRecursive:
+ case EventAppliesTo::kAll:
+ case EventAppliesTo::kAllNonRecursive:
return pNotify->ExecEventByDeepFirst(
GetXFANode(), eventParaInfo->m_eventType, false,
- eventParaInfo->m_validFlags == EventAppliesToo::kAll);
- case EventAppliesToo::kSubform:
+ eventParaInfo->m_validFlags == EventAppliesTo::kAll);
+ case EventAppliesTo::kSubform:
if (eType != XFA_Element::Subform)
return XFA_EventError::kNotExist;
return pNotify->ExecEventByDeepFirst(
GetXFANode(), eventParaInfo->m_eventType, false, false);
- case EventAppliesToo::kFieldOrExclusion: {
+ case EventAppliesTo::kFieldOrExclusion: {
if (eType != XFA_Element::ExclGroup && eType != XFA_Element::Field)
return XFA_EventError::kNotExist;
@@ -548,13 +511,13 @@
return pNotify->ExecEventByDeepFirst(
GetXFANode(), eventParaInfo->m_eventType, false, false);
}
- case EventAppliesToo::kField:
+ case EventAppliesTo::kField:
if (eType != XFA_Element::Field)
return XFA_EventError::kNotExist;
return pNotify->ExecEventByDeepFirst(
GetXFANode(), eventParaInfo->m_eventType, false, false);
- case EventAppliesToo::kSignature: {
+ case EventAppliesTo::kSignature: {
if (!GetXFANode()->IsWidgetReady())
return XFA_EventError::kNotExist;
if (GetXFANode()->GetUIChildNode()->GetElementType() !=
@@ -564,7 +527,7 @@
return pNotify->ExecEventByDeepFirst(
GetXFANode(), eventParaInfo->m_eventType, false, false);
}
- case EventAppliesToo::kChoiceList: {
+ case EventAppliesTo::kChoiceList: {
if (!GetXFANode()->IsWidgetReady())
return XFA_EventError::kNotExist;
if (GetXFANode()->GetUIChildNode()->GetElementType() !=
diff --git a/fxjs/xfa/cjx_node.h b/fxjs/xfa/cjx_node.h
index 1cbceb6..bc8eb3f 100644
--- a/fxjs/xfa/cjx_node.h
+++ b/fxjs/xfa/cjx_node.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,7 +16,7 @@
class CJX_Node : public CJX_Tree {
public:
- explicit CJX_Node(CXFA_Node* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Node() override;
// CJX_Object:
@@ -40,9 +40,9 @@
JSE_PROP(ns);
JSE_PROP(oneOfChild);
- CXFA_Node* GetXFANode() const;
-
protected:
+ explicit CJX_Node(CXFA_Node* node);
+
XFA_EventError execSingleEventByName(WideStringView wsEventName,
XFA_Element eType);
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index 64006b3..9d6cdf9 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,20 +8,27 @@
#include <set>
#include <tuple>
+#include <utility>
#include "core/fxcrt/fx_extension.h"
+#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmltext.h"
#include "fxjs/cjs_result.h"
+#include "fxjs/fxv8.h"
+#include "fxjs/gc/container_trace.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "fxjs/xfa/cfxjse_mapmodule.h"
#include "fxjs/xfa/cjx_boolean.h"
#include "fxjs/xfa/cjx_draw.h"
#include "fxjs/xfa/cjx_field.h"
#include "fxjs/xfa/cjx_instancemanager.h"
-#include "third_party/base/compiler_specific.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
+#include "third_party/base/check.h"
+#include "third_party/base/check_op.h"
+#include "third_party/base/containers/contains.h"
+#include "v8/include/v8-forward.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fgas/crt/cfgas_decimal.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
@@ -44,33 +51,19 @@
namespace {
-void XFA_DeleteWideString(void* pData) {
- delete static_cast<WideString*>(pData);
-}
-
-void XFA_CopyWideString(void*& pData) {
- if (!pData)
- return;
- pData = new WideString(*reinterpret_cast<WideString*>(pData));
-}
-
-const XFA_MAPDATABLOCKCALLBACKINFO deleteWideStringCallBack = {
- XFA_DeleteWideString, XFA_CopyWideString};
-
enum XFA_KEYTYPE {
XFA_KEYTYPE_Custom,
XFA_KEYTYPE_Element,
};
-void* GetMapKey_Custom(WideStringView wsKey) {
- uint32_t dwKey = FX_HashCode_GetW(wsKey, false);
- return (void*)(uintptr_t)((dwKey << 1) | XFA_KEYTYPE_Custom);
+uint32_t GetMapKey_Custom(WideStringView wsKey) {
+ uint32_t dwKey = FX_HashCode_GetW(wsKey);
+ return ((dwKey << 1) | XFA_KEYTYPE_Custom);
}
-void* GetMapKey_Element(XFA_Element eType, XFA_Attribute eAttribute) {
- return (void*)(uintptr_t)((static_cast<uint32_t>(eType) << 16) |
- (static_cast<uint32_t>(eAttribute) << 8) |
- XFA_KEYTYPE_Element);
+uint32_t GetMapKey_Element(XFA_Element eType, XFA_Attribute eAttribute) {
+ return ((static_cast<uint32_t>(eType) << 16) |
+ (static_cast<uint32_t>(eAttribute) << 8) | XFA_KEYTYPE_Element);
}
std::tuple<int32_t, int32_t, int32_t> StrToRGB(const WideString& strRGB) {
@@ -106,25 +99,18 @@
} // namespace
-struct XFA_MAPDATABLOCK {
- uint8_t* GetData() const { return (uint8_t*)this + sizeof(XFA_MAPDATABLOCK); }
-
- const XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo;
- int32_t iBytes;
-};
-
-struct XFA_MAPMODULEDATA {
- XFA_MAPMODULEDATA() {}
- ~XFA_MAPMODULEDATA() {}
-
- std::map<void*, void*> m_ValueMap;
- std::map<void*, XFA_MAPDATABLOCK*> m_BufferMap;
-};
-
CJX_Object::CJX_Object(CXFA_Object* obj) : object_(obj) {}
-CJX_Object::~CJX_Object() {
- ClearMapModuleBuffer();
+CJX_Object::~CJX_Object() = default;
+
+CJX_Object* CJX_Object::AsCJXObject() {
+ return this;
+}
+
+void CJX_Object::Trace(cppgc::Visitor* visitor) const {
+ visitor->Trace(object_);
+ visitor->Trace(layout_item_);
+ visitor->Trace(calc_data_);
}
bool CJX_Object::DynamicTypeIs(TypeTag eType) const {
@@ -140,19 +126,24 @@
return object_->GetDocument();
}
-void CJX_Object::className(CFXJSE_Value* pValue,
+CXFA_Node* CJX_Object::GetXFANode() const {
+ return ToNode(GetXFAObject());
+}
+
+void CJX_Object::className(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- pValue->SetString(GetXFAObject()->GetClassName());
+ *pValue = fxv8::NewStringHelper(pIsolate, GetXFAObject()->GetClassName());
}
int32_t CJX_Object::Subform_and_SubformSet_InstanceIndex() {
int32_t index = 0;
- for (CXFA_Node* pNode = ToNode(GetXFAObject())->GetPrevSibling(); pNode;
+ for (CXFA_Node* pNode = GetXFANode()->GetPrevSibling(); pNode;
pNode = pNode->GetPrevSibling()) {
if ((pNode->GetElementType() != XFA_Element::Subform) &&
(pNode->GetElementType() != XFA_Element::SubformSet)) {
@@ -164,7 +155,7 @@
}
bool CJX_Object::HasMethod(const WideString& func) const {
- return pdfium::ContainsKey(method_specs_, func.ToUTF8());
+ return pdfium::Contains(method_specs_, func.ToUTF8());
}
CJS_Result CJX_Object::RunMethod(
@@ -178,176 +169,176 @@
params);
}
-void CJX_Object::ThrowTooManyOccurancesException(const WideString& obj) const {
- ThrowException(WideString::FromASCII("The element [") + obj +
- WideString::FromASCII(
- "] has violated its allowable number of occurrences."));
+void CJX_Object::ThrowTooManyOccurrencesException(v8::Isolate* pIsolate,
+ const WideString& obj) const {
+ ThrowException(
+ pIsolate, WideString::FromASCII("The element [") + obj +
+ WideString::FromASCII(
+ "] has violated its allowable number of occurrences."));
}
-void CJX_Object::ThrowInvalidPropertyException() const {
- ThrowException(WideString::FromASCII("Invalid property set operation."));
+void CJX_Object::ThrowInvalidPropertyException(v8::Isolate* pIsolate) const {
+ ThrowException(pIsolate,
+ WideString::FromASCII("Invalid property set operation."));
}
-void CJX_Object::ThrowIndexOutOfBoundsException() const {
- ThrowException(WideString::FromASCII("Index value is out of bounds."));
+void CJX_Object::ThrowIndexOutOfBoundsException(v8::Isolate* pIsolate) const {
+ ThrowException(pIsolate,
+ WideString::FromASCII("Index value is out of bounds."));
}
void CJX_Object::ThrowParamCountMismatchException(
+ v8::Isolate* pIsolate,
const WideString& method) const {
ThrowException(
+ pIsolate,
WideString::FromASCII("Incorrect number of parameters calling method '") +
- method + WideString::FromASCII("'."));
+ method + WideString::FromASCII("'."));
}
-void CJX_Object::ThrowArgumentMismatchException() const {
- ThrowException(WideString::FromASCII(
- "Argument mismatch in property or function argument."));
+void CJX_Object::ThrowArgumentMismatchException(v8::Isolate* pIsolate) const {
+ ThrowException(pIsolate,
+ WideString::FromASCII(
+ "Argument mismatch in property or function argument."));
}
-void CJX_Object::ThrowException(const WideString& str) const {
- ASSERT(!str.IsEmpty());
- FXJSE_ThrowMessage(str.ToUTF8().AsStringView());
+void CJX_Object::ThrowException(v8::Isolate* pIsolate,
+ const WideString& str) const {
+ DCHECK(!str.IsEmpty());
+ FXJSE_ThrowMessage(pIsolate, str.ToUTF8().AsStringView());
}
-bool CJX_Object::HasAttribute(XFA_Attribute eAttr) {
- void* pKey = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
- return HasMapModuleKey(pKey);
+bool CJX_Object::HasAttribute(XFA_Attribute eAttr) const {
+ uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
+ return HasMapModuleKey(key);
}
-void CJX_Object::SetAttribute(XFA_Attribute eAttr,
- WideStringView wsValue,
- bool bNotify) {
- switch (ToNode(GetXFAObject())->GetAttributeType(eAttr)) {
+void CJX_Object::SetAttributeByEnum(XFA_Attribute eAttr,
+ const WideString& wsValue,
+ bool bNotify) {
+ switch (GetXFANode()->GetAttributeType(eAttr)) {
case XFA_AttributeType::Enum: {
- Optional<XFA_AttributeValue> item = XFA_GetAttributeValueByName(wsValue);
+ absl::optional<XFA_AttributeValue> item =
+ XFA_GetAttributeValueByName(wsValue.AsStringView());
SetEnum(eAttr,
- item ? *item : *(ToNode(GetXFAObject())->GetDefaultEnum(eAttr)),
+ item.has_value() ? item.value()
+ : GetXFANode()->GetDefaultEnum(eAttr).value(),
bNotify);
break;
}
case XFA_AttributeType::CData:
- SetCData(eAttr, WideString(wsValue), bNotify, false);
+ SetCDataImpl(eAttr, WideString(wsValue), bNotify, false);
break;
case XFA_AttributeType::Boolean:
SetBoolean(eAttr, !wsValue.EqualsASCII("0"), bNotify);
break;
case XFA_AttributeType::Integer:
SetInteger(eAttr,
- FXSYS_roundf(FXSYS_wcstof(wsValue.unterminated_c_str(),
- wsValue.GetLength(), nullptr)),
+ FXSYS_roundf(FXSYS_wcstof(wsValue.c_str(), wsValue.GetLength(),
+ nullptr)),
bNotify);
break;
case XFA_AttributeType::Measure:
- SetMeasure(eAttr, CXFA_Measurement(wsValue), bNotify);
+ SetMeasure(eAttr, CXFA_Measurement(wsValue.AsStringView()), bNotify);
break;
default:
break;
}
}
-void CJX_Object::SetMapModuleString(void* pKey, WideStringView wsValue) {
- SetMapModuleBuffer(pKey, const_cast<wchar_t*>(wsValue.unterminated_c_str()),
- wsValue.GetLength() * sizeof(wchar_t), nullptr);
-}
-
-void CJX_Object::SetAttribute(WideStringView wsAttr,
- WideStringView wsValue,
- bool bNotify) {
- Optional<XFA_ATTRIBUTEINFO> attr = XFA_GetAttributeByName(wsAttr);
+void CJX_Object::SetAttributeByString(WideStringView wsAttr,
+ const WideString& wsValue) {
+ absl::optional<XFA_ATTRIBUTEINFO> attr = XFA_GetAttributeByName(wsAttr);
if (attr.has_value()) {
- SetAttribute(attr.value().attribute, wsValue, bNotify);
+ SetAttributeByEnum(attr.value().attribute, wsValue, true);
return;
}
- void* pKey = GetMapKey_Custom(wsAttr);
- SetMapModuleString(pKey, wsValue);
+ uint32_t key = GetMapKey_Custom(wsAttr);
+ SetMapModuleString(key, wsValue);
}
-WideString CJX_Object::GetAttribute(WideStringView attr) {
+WideString CJX_Object::GetAttributeByString(WideStringView attr) const {
+ absl::optional<WideString> result;
+ absl::optional<XFA_ATTRIBUTEINFO> enum_attr = XFA_GetAttributeByName(attr);
+ if (enum_attr.has_value())
+ result = TryAttribute(enum_attr.value().attribute, true);
+ else
+ result = GetMapModuleStringFollowingChain(GetMapKey_Custom(attr));
+ return result.value_or(WideString());
+}
+
+WideString CJX_Object::GetAttributeByEnum(XFA_Attribute attr) const {
return TryAttribute(attr, true).value_or(WideString());
}
-WideString CJX_Object::GetAttribute(XFA_Attribute attr) {
- return TryAttribute(attr, true).value_or(WideString());
-}
-
-Optional<WideString> CJX_Object::TryAttribute(XFA_Attribute eAttr,
- bool bUseDefault) {
- switch (ToNode(GetXFAObject())->GetAttributeType(eAttr)) {
+absl::optional<WideString> CJX_Object::TryAttribute(XFA_Attribute eAttr,
+ bool bUseDefault) const {
+ switch (GetXFANode()->GetAttributeType(eAttr)) {
case XFA_AttributeType::Enum: {
- Optional<XFA_AttributeValue> value = TryEnum(eAttr, bUseDefault);
- if (!value)
- return {};
- return WideString::FromASCII(XFA_AttributeValueToName(*value));
+ absl::optional<XFA_AttributeValue> value = TryEnum(eAttr, bUseDefault);
+ if (!value.has_value())
+ return absl::nullopt;
+ return WideString::FromASCII(XFA_AttributeValueToName(value.value()));
}
case XFA_AttributeType::CData:
return TryCData(eAttr, bUseDefault);
case XFA_AttributeType::Boolean: {
- Optional<bool> value = TryBoolean(eAttr, bUseDefault);
- if (!value)
- return {};
- return WideString(*value ? L"1" : L"0");
+ absl::optional<bool> value = TryBoolean(eAttr, bUseDefault);
+ if (!value.has_value())
+ return absl::nullopt;
+ return WideString(value.value() ? L"1" : L"0");
}
case XFA_AttributeType::Integer: {
- Optional<int32_t> iValue = TryInteger(eAttr, bUseDefault);
- if (!iValue)
- return {};
- return WideString::Format(L"%d", *iValue);
+ absl::optional<int32_t> iValue = TryInteger(eAttr, bUseDefault);
+ if (!iValue.has_value())
+ return absl::nullopt;
+ return WideString::FormatInteger(iValue.value());
}
case XFA_AttributeType::Measure: {
- Optional<CXFA_Measurement> value = TryMeasure(eAttr, bUseDefault);
- if (!value)
- return {};
-
+ absl::optional<CXFA_Measurement> value = TryMeasure(eAttr, bUseDefault);
+ if (!value.has_value())
+ return absl::nullopt;
return value->ToString();
}
default:
break;
}
- return {};
-}
-
-Optional<WideString> CJX_Object::TryAttribute(WideStringView wsAttr,
- bool bUseDefault) {
- Optional<XFA_ATTRIBUTEINFO> attr = XFA_GetAttributeByName(wsAttr);
- if (attr.has_value())
- return TryAttribute(attr.value().attribute, bUseDefault);
- return GetMapModuleString(GetMapKey_Custom(wsAttr));
+ return absl::nullopt;
}
void CJX_Object::RemoveAttribute(WideStringView wsAttr) {
- void* pKey = GetMapKey_Custom(wsAttr);
- if (pKey)
- RemoveMapModuleKey(pKey);
+ RemoveMapModuleKey(GetMapKey_Custom(wsAttr));
}
-Optional<bool> CJX_Object::TryBoolean(XFA_Attribute eAttr, bool bUseDefault) {
- void* pKey = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
- Optional<void*> value = GetMapModuleValue(pKey);
+absl::optional<bool> CJX_Object::TryBoolean(XFA_Attribute eAttr,
+ bool bUseDefault) const {
+ uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
+ absl::optional<int32_t> value = GetMapModuleValueFollowingChain(key);
if (value.has_value())
return !!value.value();
if (!bUseDefault)
- return {};
- return ToNode(GetXFAObject())->GetDefaultBoolean(eAttr);
+ return absl::nullopt;
+ return GetXFANode()->GetDefaultBoolean(eAttr);
}
void CJX_Object::SetBoolean(XFA_Attribute eAttr, bool bValue, bool bNotify) {
- CFX_XMLElement* elem = SetValue(eAttr, (void*)(uintptr_t)bValue, bNotify);
+ CFX_XMLElement* elem = SetValue(eAttr, static_cast<int32_t>(bValue), bNotify);
if (elem) {
elem->SetAttribute(WideString::FromASCII(XFA_AttributeToName(eAttr)),
bValue ? L"1" : L"0");
}
}
-bool CJX_Object::GetBoolean(XFA_Attribute eAttr) {
+bool CJX_Object::GetBoolean(XFA_Attribute eAttr) const {
return TryBoolean(eAttr, true).value_or(false);
}
void CJX_Object::SetInteger(XFA_Attribute eAttr, int32_t iValue, bool bNotify) {
- CFX_XMLElement* elem = SetValue(eAttr, (void*)(uintptr_t)iValue, bNotify);
+ CFX_XMLElement* elem = SetValue(eAttr, iValue, bNotify);
if (elem) {
elem->SetAttribute(WideString::FromASCII(XFA_AttributeToName(eAttr)),
- WideString::Format(L"%d", iValue));
+ WideString::FormatInteger(iValue));
}
}
@@ -355,34 +346,32 @@
return TryInteger(eAttr, true).value_or(0);
}
-Optional<int32_t> CJX_Object::TryInteger(XFA_Attribute eAttr,
- bool bUseDefault) const {
- void* pKey = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
- Optional<void*> value = GetMapModuleValue(pKey);
+absl::optional<int32_t> CJX_Object::TryInteger(XFA_Attribute eAttr,
+ bool bUseDefault) const {
+ uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
+ absl::optional<int32_t> value = GetMapModuleValueFollowingChain(key);
if (value.has_value())
- return static_cast<int32_t>(reinterpret_cast<uintptr_t>(value.value()));
+ return value.value();
if (!bUseDefault)
- return {};
- return ToNode(GetXFAObject())->GetDefaultInteger(eAttr);
+ return absl::nullopt;
+ return GetXFANode()->GetDefaultInteger(eAttr);
}
-Optional<XFA_AttributeValue> CJX_Object::TryEnum(XFA_Attribute eAttr,
- bool bUseDefault) const {
- void* pKey = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
- Optional<void*> value = GetMapModuleValue(pKey);
- if (value.has_value()) {
- return static_cast<XFA_AttributeValue>(
- reinterpret_cast<uintptr_t>(value.value()));
- }
+absl::optional<XFA_AttributeValue> CJX_Object::TryEnum(XFA_Attribute eAttr,
+ bool bUseDefault) const {
+ uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
+ absl::optional<int32_t> value = GetMapModuleValueFollowingChain(key);
+ if (value.has_value())
+ return static_cast<XFA_AttributeValue>(value.value());
if (!bUseDefault)
- return {};
- return ToNode(GetXFAObject())->GetDefaultEnum(eAttr);
+ return absl::nullopt;
+ return GetXFANode()->GetDefaultEnum(eAttr);
}
void CJX_Object::SetEnum(XFA_Attribute eAttr,
XFA_AttributeValue eValue,
bool bNotify) {
- CFX_XMLElement* elem = SetValue(eAttr, (void*)(uintptr_t)eValue, bNotify);
+ CFX_XMLElement* elem = SetValue(eAttr, static_cast<int32_t>(eValue), bNotify);
if (elem) {
elem->SetAttribute(WideString::FromASCII(XFA_AttributeToName(eAttr)),
WideString::FromASCII(XFA_AttributeValueToName(eValue)));
@@ -394,33 +383,36 @@
}
void CJX_Object::SetMeasure(XFA_Attribute eAttr,
- CXFA_Measurement mValue,
+ const CXFA_Measurement& mValue,
bool bNotify) {
- void* pKey = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
- OnChanging(eAttr, bNotify);
- SetMapModuleBuffer(pKey, &mValue, sizeof(CXFA_Measurement), nullptr);
- OnChanged(eAttr, bNotify, false);
+ // Can't short-circuit update here when the value is the same since it
+ // might have come from further up the chain from where we are setting it.
+ uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
+ if (bNotify)
+ OnChanging(eAttr);
+ SetMapModuleMeasurement(key, mValue);
+ if (bNotify)
+ OnChanged(eAttr, false);
}
-Optional<CXFA_Measurement> CJX_Object::TryMeasure(XFA_Attribute eAttr,
- bool bUseDefault) const {
- void* pKey = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
- void* pValue;
- int32_t iBytes;
- if (GetMapModuleBuffer(pKey, &pValue, &iBytes) &&
- iBytes == sizeof(CXFA_Measurement)) {
- return *static_cast<CXFA_Measurement*>(pValue);
- }
+absl::optional<CXFA_Measurement> CJX_Object::TryMeasure(
+ XFA_Attribute eAttr,
+ bool bUseDefault) const {
+ uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
+ absl::optional<CXFA_Measurement> result =
+ GetMapModuleMeasurementFollowingChain(key);
+ if (result.has_value())
+ return result.value();
if (!bUseDefault)
- return {};
- return ToNode(GetXFAObject())->GetDefaultMeasurement(eAttr);
+ return absl::nullopt;
+ return GetXFANode()->GetDefaultMeasurement(eAttr);
}
-Optional<float> CJX_Object::TryMeasureAsFloat(XFA_Attribute attr) const {
- Optional<CXFA_Measurement> measure = TryMeasure(attr, false);
- if (measure)
- return measure->ToUnit(XFA_Unit::Pt);
- return {};
+absl::optional<float> CJX_Object::TryMeasureAsFloat(XFA_Attribute attr) const {
+ absl::optional<CXFA_Measurement> measure = TryMeasure(attr, false);
+ if (!measure.has_value())
+ return absl::nullopt;
+ return measure->ToUnit(XFA_Unit::Pt);
}
CXFA_Measurement CJX_Object::GetMeasure(XFA_Attribute eAttr) const {
@@ -428,30 +420,33 @@
}
float CJX_Object::GetMeasureInUnit(XFA_Attribute eAttr, XFA_Unit unit) const {
- auto measure = TryMeasure(eAttr, true).value_or(CXFA_Measurement());
- return measure.ToUnit(unit);
+ return GetMeasure(eAttr).ToUnit(unit);
}
WideString CJX_Object::GetCData(XFA_Attribute eAttr) const {
return TryCData(eAttr, true).value_or(WideString());
}
-void CJX_Object::SetCData(XFA_Attribute eAttr,
- const WideString& wsValue,
- bool bNotify,
- bool bScriptModify) {
- CXFA_Node* xfaObj = ToNode(GetXFAObject());
- void* pKey = GetMapKey_Element(xfaObj->GetElementType(), eAttr);
- OnChanging(eAttr, bNotify);
- if (eAttr == XFA_Attribute::Value) {
- WideString* pClone = new WideString(wsValue);
- SetUserData(pKey, pClone, &deleteWideStringCallBack);
- } else {
- SetMapModuleString(pKey, wsValue.AsStringView());
+void CJX_Object::SetCData(XFA_Attribute eAttr, const WideString& wsValue) {
+ return SetCDataImpl(eAttr, wsValue, false, false);
+}
+
+void CJX_Object::SetCDataImpl(XFA_Attribute eAttr,
+ const WideString& wsValue,
+ bool bNotify,
+ bool bScriptModify) {
+ CXFA_Node* xfaObj = GetXFANode();
+ uint32_t key = GetMapKey_Element(xfaObj->GetElementType(), eAttr);
+ absl::optional<WideString> old_value = GetMapModuleString(key);
+ if (!old_value.has_value() || old_value.value() != wsValue) {
+ if (bNotify)
+ OnChanging(eAttr);
+ SetMapModuleString(key, wsValue);
if (eAttr == XFA_Attribute::Name)
xfaObj->UpdateNameHash();
+ if (bNotify)
+ OnChanged(eAttr, bScriptModify);
}
- OnChanged(eAttr, bNotify, bScriptModify);
if (!xfaObj->IsNeedSavingXMLNode() || eAttr == XFA_Attribute::QualifiedName ||
eAttr == XFA_Attribute::BindingNode) {
@@ -479,57 +474,55 @@
}
void CJX_Object::SetAttributeValue(const WideString& wsValue,
- const WideString& wsXMLValue,
- bool bNotify,
- bool bScriptModify) {
- auto* xfaObj = ToNode(GetXFAObject());
- void* pKey =
- GetMapKey_Element(xfaObj->GetElementType(), XFA_Attribute::Value);
-
- OnChanging(XFA_Attribute::Value, bNotify);
- WideString* pClone = new WideString(wsValue);
-
- SetUserData(pKey, pClone, &deleteWideStringCallBack);
- OnChanged(XFA_Attribute::Value, bNotify, bScriptModify);
-
- if (!xfaObj->IsNeedSavingXMLNode())
- return;
-
- xfaObj->SetToXML(wsXMLValue);
+ const WideString& wsXMLValue) {
+ SetAttributeValueImpl(wsValue, wsXMLValue, false, false);
}
-Optional<WideString> CJX_Object::TryCData(XFA_Attribute eAttr,
- bool bUseDefault) const {
- void* pKey = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
- if (eAttr == XFA_Attribute::Value) {
- void* pData;
- int32_t iBytes = 0;
- WideString* pStr = nullptr;
- if (GetMapModuleBuffer(pKey, &pData, &iBytes) && iBytes == sizeof(void*)) {
- memcpy(&pData, pData, iBytes);
- pStr = reinterpret_cast<WideString*>(pData);
- }
- if (pStr)
- return *pStr;
- } else {
- Optional<WideString> value = GetMapModuleString(pKey);
- if (value.has_value())
- return value;
+void CJX_Object::SetAttributeValueImpl(const WideString& wsValue,
+ const WideString& wsXMLValue,
+ bool bNotify,
+ bool bScriptModify) {
+ auto* xfaObj = GetXFANode();
+ uint32_t key =
+ GetMapKey_Element(xfaObj->GetElementType(), XFA_Attribute::Value);
+ absl::optional<WideString> old_value = GetMapModuleString(key);
+ if (!old_value.has_value() || old_value.value() != wsValue) {
+ if (bNotify)
+ OnChanging(XFA_Attribute::Value);
+ SetMapModuleString(key, wsValue);
+ if (bNotify)
+ OnChanged(XFA_Attribute::Value, bScriptModify);
+ if (xfaObj->IsNeedSavingXMLNode())
+ xfaObj->SetToXML(wsXMLValue);
}
+}
+
+absl::optional<WideString> CJX_Object::TryCData(XFA_Attribute eAttr,
+ bool bUseDefault) const {
+ uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
+ absl::optional<WideString> value = GetMapModuleStringFollowingChain(key);
+ if (value.has_value())
+ return value;
+
if (!bUseDefault)
- return {};
- return ToNode(GetXFAObject())->GetDefaultCData(eAttr);
+ return absl::nullopt;
+
+ return GetXFANode()->GetDefaultCData(eAttr);
}
CFX_XMLElement* CJX_Object::SetValue(XFA_Attribute eAttr,
- void* pValue,
+ int32_t value,
bool bNotify) {
- void* pKey = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
- OnChanging(eAttr, bNotify);
- SetMapModuleValue(pKey, pValue);
- OnChanged(eAttr, bNotify, false);
-
- CXFA_Node* pNode = ToNode(GetXFAObject());
+ uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
+ absl::optional<int32_t> old_value = GetMapModuleValue(key);
+ if (!old_value.has_value() || old_value.value() != value) {
+ if (bNotify)
+ OnChanging(eAttr);
+ SetMapModuleValue(key, value);
+ if (bNotify)
+ OnChanged(eAttr, false);
+ }
+ CXFA_Node* pNode = GetXFANode();
return pNode->IsNeedSavingXMLNode() ? ToXMLElement(pNode->GetXMLMappingNode())
: nullptr;
}
@@ -541,9 +534,9 @@
bool bSyncData) {
CXFA_Node* pNode = nullptr;
CXFA_Node* pBindNode = nullptr;
- switch (ToNode(GetXFAObject())->GetObjectType()) {
+ switch (GetXFANode()->GetObjectType()) {
case XFA_ObjectType::ContainerNode: {
- if (XFA_FieldIsMultiListBox(ToNode(GetXFAObject()))) {
+ if (XFA_FieldIsMultiListBox(GetXFANode())) {
CXFA_Value* pValue =
GetOrCreateProperty<CXFA_Value>(0, XFA_Element::Value);
if (!pValue)
@@ -551,11 +544,11 @@
CXFA_Node* pChildValue = pValue->GetFirstChild();
pChildValue->JSObject()->SetCData(XFA_Attribute::ContentType,
- L"text/xml", false, false);
+ L"text/xml");
pChildValue->JSObject()->SetContent(wsContent, wsContent, bNotify,
bScriptModify, false);
- CXFA_Node* pBind = ToNode(GetXFAObject())->GetBindData();
+ CXFA_Node* pBind = GetXFANode()->GetBindData();
if (bSyncData && pBind) {
std::vector<WideString> wsSaveTextArray =
fxcrt::Split(wsContent, L'\n');
@@ -573,8 +566,8 @@
while (iAddNodes-- > 0) {
CXFA_Node* pValueNodes =
pBind->CreateSamePacketNode(XFA_Element::DataValue);
- pValueNodes->JSObject()->SetCData(XFA_Attribute::Name, L"value",
- false, false);
+ pValueNodes->JSObject()->SetCData(XFA_Attribute::Name,
+ L"value");
pValueNodes->CreateXMLMappingNode();
pBind->InsertChildAndNotify(pValueNodes, nullptr);
}
@@ -585,15 +578,15 @@
}
valueNodes = pBind->GetNodeListForType(XFA_Element::DataValue);
}
- ASSERT(valueNodes.size() == wsSaveTextArray.size());
+ DCHECK_EQ(valueNodes.size(), wsSaveTextArray.size());
size_t i = 0;
for (CXFA_Node* pValueNode : valueNodes) {
- pValueNode->JSObject()->SetAttributeValue(
- wsSaveTextArray[i], wsSaveTextArray[i], false, false);
+ pValueNode->JSObject()->SetAttributeValue(wsSaveTextArray[i],
+ wsSaveTextArray[i]);
i++;
}
for (auto* pArrayNode : pBind->GetBindItemsCopy()) {
- if (pArrayNode != ToNode(GetXFAObject())) {
+ if (pArrayNode != GetXFANode()) {
pArrayNode->JSObject()->SetContent(wsContent, wsContent, bNotify,
bScriptModify, false);
}
@@ -601,8 +594,8 @@
}
break;
}
- if (ToNode(GetXFAObject())->GetElementType() == XFA_Element::ExclGroup) {
- pNode = ToNode(GetXFAObject());
+ if (GetXFANode()->GetElementType() == XFA_Element::ExclGroup) {
+ pNode = GetXFANode();
} else {
CXFA_Value* pValue =
GetOrCreateProperty<CXFA_Value>(0, XFA_Element::Value);
@@ -610,16 +603,17 @@
break;
CXFA_Node* pChildValue = pValue->GetFirstChild();
- ASSERT(pChildValue);
- pChildValue->JSObject()->SetContent(wsContent, wsContent, bNotify,
- bScriptModify, false);
+ if (pChildValue) {
+ pChildValue->JSObject()->SetContent(wsContent, wsContent, bNotify,
+ bScriptModify, false);
+ }
}
- pBindNode = ToNode(GetXFAObject())->GetBindData();
+ pBindNode = GetXFANode()->GetBindData();
if (pBindNode && bSyncData) {
pBindNode->JSObject()->SetContent(wsContent, wsXMLValue, bNotify,
bScriptModify, false);
for (auto* pArrayNode : pBindNode->GetBindItemsCopy()) {
- if (pArrayNode != ToNode(GetXFAObject())) {
+ if (pArrayNode != GetXFANode()) {
pArrayNode->JSObject()->SetContent(wsContent, wsContent, bNotify,
true, false);
}
@@ -630,27 +624,23 @@
}
case XFA_ObjectType::ContentNode: {
WideString wsContentType;
- if (ToNode(GetXFAObject())->GetElementType() == XFA_Element::ExData) {
- Optional<WideString> ret =
+ if (GetXFANode()->GetElementType() == XFA_Element::ExData) {
+ absl::optional<WideString> ret =
TryAttribute(XFA_Attribute::ContentType, false);
- if (ret)
- wsContentType = *ret;
+ if (ret.has_value())
+ wsContentType = ret.value();
if (wsContentType.EqualsASCII("text/html")) {
wsContentType.clear();
- SetAttribute(XFA_Attribute::ContentType, wsContentType.AsStringView(),
- false);
+ SetAttributeByEnum(XFA_Attribute::ContentType, wsContentType, false);
}
}
- CXFA_Node* pContentRawDataNode = ToNode(GetXFAObject())->GetFirstChild();
+ CXFA_Node* pContentRawDataNode = GetXFANode()->GetFirstChild();
if (!pContentRawDataNode) {
- pContentRawDataNode =
- ToNode(GetXFAObject())
- ->CreateSamePacketNode(wsContentType.EqualsASCII("text/xml")
- ? XFA_Element::Sharpxml
- : XFA_Element::Sharptext);
- ToNode(GetXFAObject())
- ->InsertChildAndNotify(pContentRawDataNode, nullptr);
+ pContentRawDataNode = GetXFANode()->CreateSamePacketNode(
+ wsContentType.EqualsASCII("text/xml") ? XFA_Element::Sharpxml
+ : XFA_Element::Sharptext);
+ GetXFANode()->InsertChildAndNotify(pContentRawDataNode, nullptr);
}
pContentRawDataNode->JSObject()->SetContent(
wsContent, wsXMLValue, bNotify, bScriptModify, bSyncData);
@@ -658,13 +648,12 @@
}
case XFA_ObjectType::NodeC:
case XFA_ObjectType::TextNode:
- pNode = ToNode(GetXFAObject());
+ pNode = GetXFANode();
break;
case XFA_ObjectType::NodeV:
- pNode = ToNode(GetXFAObject());
- if (bSyncData &&
- ToNode(GetXFAObject())->GetPacketType() == XFA_PacketType::Form) {
- CXFA_Node* pParent = ToNode(GetXFAObject())->GetParent();
+ pNode = GetXFANode();
+ if (bSyncData && GetXFANode()->GetPacketType() == XFA_PacketType::Form) {
+ CXFA_Node* pParent = GetXFANode()->GetParent();
if (pParent) {
pParent = pParent->GetParent();
}
@@ -681,16 +670,16 @@
}
break;
default:
- if (ToNode(GetXFAObject())->GetElementType() == XFA_Element::DataValue) {
- pNode = ToNode(GetXFAObject());
- pBindNode = ToNode(GetXFAObject());
+ if (GetXFANode()->GetElementType() == XFA_Element::DataValue) {
+ pNode = GetXFANode();
+ pBindNode = GetXFANode();
}
break;
}
if (!pNode)
return;
- SetAttributeValue(wsContent, wsXMLValue, bNotify, bScriptModify);
+ SetAttributeValueImpl(wsContent, wsXMLValue, bNotify, bScriptModify);
if (pBindNode && bSyncData) {
for (auto* pArrayNode : pBindNode->GetBindItemsCopy()) {
pArrayNode->JSObject()->SetContent(wsContent, wsContent, bNotify,
@@ -699,39 +688,39 @@
}
}
-WideString CJX_Object::GetContent(bool bScriptModify) {
+WideString CJX_Object::GetContent(bool bScriptModify) const {
return TryContent(bScriptModify, true).value_or(WideString());
}
-Optional<WideString> CJX_Object::TryContent(bool bScriptModify, bool bProto) {
+absl::optional<WideString> CJX_Object::TryContent(bool bScriptModify,
+ bool bProto) const {
CXFA_Node* pNode = nullptr;
- switch (ToNode(GetXFAObject())->GetObjectType()) {
+ switch (GetXFANode()->GetObjectType()) {
case XFA_ObjectType::ContainerNode:
- if (ToNode(GetXFAObject())->GetElementType() == XFA_Element::ExclGroup) {
- pNode = ToNode(GetXFAObject());
+ if (GetXFANode()->GetElementType() == XFA_Element::ExclGroup) {
+ pNode = GetXFANode();
} else {
CXFA_Value* pValue =
- ToNode(GetXFAObject())
- ->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
+ GetXFANode()->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
if (!pValue)
- return {};
+ return absl::nullopt;
CXFA_Node* pChildValue = pValue->GetFirstChild();
- if (pChildValue && XFA_FieldIsMultiListBox(ToNode(GetXFAObject()))) {
- pChildValue->JSObject()->SetAttribute(XFA_Attribute::ContentType,
- L"text/xml", false);
+ if (pChildValue && XFA_FieldIsMultiListBox(GetXFANode())) {
+ pChildValue->JSObject()->SetAttributeByEnum(
+ XFA_Attribute::ContentType, L"text/xml", false);
}
- if (pChildValue)
- return pChildValue->JSObject()->TryContent(bScriptModify, bProto);
- return {};
+ if (!pChildValue)
+ return absl::nullopt;
+ return pChildValue->JSObject()->TryContent(bScriptModify, bProto);
}
break;
case XFA_ObjectType::ContentNode: {
- CXFA_Node* pContentRawDataNode = ToNode(GetXFAObject())->GetFirstChild();
+ CXFA_Node* pContentRawDataNode = GetXFANode()->GetFirstChild();
if (!pContentRawDataNode) {
XFA_Element element = XFA_Element::Sharptext;
- if (ToNode(GetXFAObject())->GetElementType() == XFA_Element::ExData) {
- Optional<WideString> contentType =
+ if (GetXFANode()->GetElementType() == XFA_Element::ExData) {
+ absl::optional<WideString> contentType =
TryAttribute(XFA_Attribute::ContentType, false);
if (contentType.has_value()) {
if (contentType.value().EqualsASCII("text/html"))
@@ -740,349 +729,270 @@
element = XFA_Element::Sharpxml;
}
}
- pContentRawDataNode =
- ToNode(GetXFAObject())->CreateSamePacketNode(element);
- ToNode(GetXFAObject())
- ->InsertChildAndNotify(pContentRawDataNode, nullptr);
+ pContentRawDataNode = GetXFANode()->CreateSamePacketNode(element);
+ GetXFANode()->InsertChildAndNotify(pContentRawDataNode, nullptr);
}
return pContentRawDataNode->JSObject()->TryContent(bScriptModify, true);
}
case XFA_ObjectType::NodeC:
case XFA_ObjectType::NodeV:
case XFA_ObjectType::TextNode:
- pNode = ToNode(GetXFAObject());
- FALLTHROUGH;
+ pNode = GetXFANode();
+ [[fallthrough]];
default:
- if (ToNode(GetXFAObject())->GetElementType() == XFA_Element::DataValue)
- pNode = ToNode(GetXFAObject());
+ if (GetXFANode()->GetElementType() == XFA_Element::DataValue)
+ pNode = GetXFANode();
break;
}
if (pNode) {
if (bScriptModify) {
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
- pScriptContext->AddNodesOfRunScript(ToNode(GetXFAObject()));
+ pScriptContext->AddNodesOfRunScript(GetXFANode());
}
return TryCData(XFA_Attribute::Value, false);
}
- return {};
+ return absl::nullopt;
}
-Optional<WideString> CJX_Object::TryNamespace() {
- if (ToNode(GetXFAObject())->IsModelNode() ||
- ToNode(GetXFAObject())->GetElementType() == XFA_Element::Packet) {
- CFX_XMLNode* pXMLNode = ToNode(GetXFAObject())->GetXMLMappingNode();
+absl::optional<WideString> CJX_Object::TryNamespace() const {
+ if (GetXFANode()->IsModelNode() ||
+ GetXFANode()->GetElementType() == XFA_Element::Packet) {
+ CFX_XMLNode* pXMLNode = GetXFANode()->GetXMLMappingNode();
CFX_XMLElement* element = ToXMLElement(pXMLNode);
if (!element)
- return {};
+ return absl::nullopt;
return element->GetNamespaceURI();
}
- if (ToNode(GetXFAObject())->GetPacketType() != XFA_PacketType::Datasets)
- return ToNode(GetXFAObject())->GetModelNode()->JSObject()->TryNamespace();
+ if (GetXFANode()->GetPacketType() != XFA_PacketType::Datasets)
+ return GetXFANode()->GetModelNode()->JSObject()->TryNamespace();
- CFX_XMLNode* pXMLNode = ToNode(GetXFAObject())->GetXMLMappingNode();
+ CFX_XMLNode* pXMLNode = GetXFANode()->GetXMLMappingNode();
CFX_XMLElement* element = ToXMLElement(pXMLNode);
if (!element)
- return {};
+ return absl::nullopt;
- if (ToNode(GetXFAObject())->GetElementType() == XFA_Element::DataValue &&
+ if (GetXFANode()->GetElementType() == XFA_Element::DataValue &&
GetEnum(XFA_Attribute::Contains) == XFA_AttributeValue::MetaData) {
WideString wsNamespace;
if (!XFA_FDEExtension_ResolveNamespaceQualifier(
element, GetCData(XFA_Attribute::QualifiedName), &wsNamespace)) {
- return {};
+ return absl::nullopt;
}
return wsNamespace;
}
return element->GetNamespaceURI();
}
-std::pair<CXFA_Node*, int32_t> CJX_Object::GetPropertyInternal(
- int32_t index,
- XFA_Element eProperty) const {
- return ToNode(GetXFAObject())->GetProperty(index, eProperty);
+CXFA_Node* CJX_Object::GetPropertyInternal(int32_t index,
+ XFA_Element eProperty) const {
+ return GetXFANode()->GetProperty(index, eProperty).first;
}
CXFA_Node* CJX_Object::GetOrCreatePropertyInternal(int32_t index,
XFA_Element eProperty) {
- return ToNode(GetXFAObject())->GetOrCreateProperty(index, eProperty);
+ return GetXFANode()->GetOrCreateProperty(index, eProperty);
}
-void CJX_Object::SetUserData(
- void* pKey,
- void* pData,
- const XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
- ASSERT(pCallbackInfo);
- SetMapModuleBuffer(pKey, &pData, sizeof(void*), pCallbackInfo);
+CFXJSE_MapModule* CJX_Object::CreateMapModule() {
+ if (!map_module_)
+ map_module_ = std::make_unique<CFXJSE_MapModule>();
+ return map_module_.get();
}
-XFA_MAPMODULEDATA* CJX_Object::CreateMapModuleData() {
- if (!map_module_data_)
- map_module_data_ = pdfium::MakeUnique<XFA_MAPMODULEDATA>();
- return map_module_data_.get();
+CFXJSE_MapModule* CJX_Object::GetMapModule() const {
+ return map_module_.get();
}
-XFA_MAPMODULEDATA* CJX_Object::GetMapModuleData() const {
- return map_module_data_.get();
+void CJX_Object::SetMapModuleValue(uint32_t key, int32_t value) {
+ CreateMapModule()->SetValue(key, value);
}
-void CJX_Object::SetMapModuleValue(void* pKey, void* pValue) {
- CreateMapModuleData()->m_ValueMap[pKey] = pValue;
+void CJX_Object::SetMapModuleString(uint32_t key, const WideString& wsValue) {
+ CreateMapModule()->SetString(key, wsValue);
}
-Optional<void*> CJX_Object::GetMapModuleValue(void* pKey) const {
+void CJX_Object::SetMapModuleMeasurement(uint32_t key,
+ const CXFA_Measurement& value) {
+ CreateMapModule()->SetMeasurement(key, value);
+}
+
+absl::optional<int32_t> CJX_Object::GetMapModuleValue(uint32_t key) const {
+ CFXJSE_MapModule* pModule = GetMapModule();
+ if (!pModule)
+ return absl::nullopt;
+ return pModule->GetValue(key);
+}
+
+absl::optional<WideString> CJX_Object::GetMapModuleString(uint32_t key) const {
+ CFXJSE_MapModule* pModule = GetMapModule();
+ if (!pModule)
+ return absl::nullopt;
+ return pModule->GetString(key);
+}
+
+absl::optional<CXFA_Measurement> CJX_Object::GetMapModuleMeasurement(
+ uint32_t key) const {
+ CFXJSE_MapModule* pModule = GetMapModule();
+ if (!pModule)
+ return absl::nullopt;
+ return pModule->GetMeasurement(key);
+}
+
+absl::optional<int32_t> CJX_Object::GetMapModuleValueFollowingChain(
+ uint32_t key) const {
std::set<const CXFA_Node*> visited;
- for (const CXFA_Node* pNode = ToNode(GetXFAObject()); pNode;
+ for (const CXFA_Node* pNode = GetXFANode(); pNode;
pNode = pNode->GetTemplateNodeIfExists()) {
if (!visited.insert(pNode).second)
break;
- XFA_MAPMODULEDATA* pModule = pNode->JSObject()->GetMapModuleData();
- if (pModule) {
- auto it = pModule->m_ValueMap.find(pKey);
- if (it != pModule->m_ValueMap.end())
- return it->second;
- }
+ absl::optional<int32_t> result = pNode->JSObject()->GetMapModuleValue(key);
+ if (result.has_value())
+ return result;
+
if (pNode->GetPacketType() == XFA_PacketType::Datasets)
break;
}
- return {};
+ return absl::nullopt;
}
-Optional<WideString> CJX_Object::GetMapModuleString(void* pKey) const {
- void* pRawValue;
- int32_t iBytes;
- if (!GetMapModuleBuffer(pKey, &pRawValue, &iBytes))
- return {};
-
- // Defensive measure: no out-of-bounds pointers even if zero length.
- int32_t iChars = iBytes / sizeof(wchar_t);
- return WideString(iChars ? static_cast<const wchar_t*>(pRawValue) : nullptr,
- iChars);
-}
-
-void CJX_Object::SetMapModuleBuffer(
- void* pKey,
- void* pValue,
- int32_t iBytes,
- const XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
- XFA_MAPDATABLOCK*& pBuffer = CreateMapModuleData()->m_BufferMap[pKey];
- if (!pBuffer) {
- pBuffer = reinterpret_cast<XFA_MAPDATABLOCK*>(
- FX_Alloc(uint8_t, sizeof(XFA_MAPDATABLOCK) + iBytes));
- } else if (pBuffer->iBytes != iBytes) {
- if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree)
- pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
-
- pBuffer = reinterpret_cast<XFA_MAPDATABLOCK*>(
- FX_Realloc(uint8_t, pBuffer, sizeof(XFA_MAPDATABLOCK) + iBytes));
- } else if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
- pBuffer->pCallbackInfo->pFree(
- *reinterpret_cast<void**>(pBuffer->GetData()));
- }
- if (!pBuffer)
- return;
-
- pBuffer->pCallbackInfo = pCallbackInfo;
- pBuffer->iBytes = iBytes;
- memcpy(pBuffer->GetData(), pValue, iBytes);
-}
-
-bool CJX_Object::GetMapModuleBuffer(void* pKey,
- void** pValue,
- int32_t* pBytes) const {
+absl::optional<WideString> CJX_Object::GetMapModuleStringFollowingChain(
+ uint32_t key) const {
std::set<const CXFA_Node*> visited;
- XFA_MAPDATABLOCK* pBuffer = nullptr;
- for (const CXFA_Node* pNode = ToNode(GetXFAObject()); pNode;
+ for (const CXFA_Node* pNode = GetXFANode(); pNode;
pNode = pNode->GetTemplateNodeIfExists()) {
if (!visited.insert(pNode).second)
break;
- XFA_MAPMODULEDATA* pModule = pNode->JSObject()->GetMapModuleData();
- if (pModule) {
- auto it = pModule->m_BufferMap.find(pKey);
- if (it != pModule->m_BufferMap.end()) {
- pBuffer = it->second;
- break;
- }
- }
+ absl::optional<WideString> result =
+ pNode->JSObject()->GetMapModuleString(key);
+ if (result.has_value())
+ return result;
+
if (pNode->GetPacketType() == XFA_PacketType::Datasets)
break;
}
- if (!pBuffer)
- return false;
-
- *pValue = pBuffer->GetData();
- *pBytes = pBuffer->iBytes;
- return true;
+ return absl::nullopt;
}
-bool CJX_Object::HasMapModuleKey(void* pKey) {
- XFA_MAPMODULEDATA* pModule = GetMapModuleData();
- return pModule && (pdfium::ContainsKey(pModule->m_ValueMap, pKey) ||
- pdfium::ContainsKey(pModule->m_BufferMap, pKey));
-}
+absl::optional<CXFA_Measurement>
+CJX_Object::GetMapModuleMeasurementFollowingChain(uint32_t key) const {
+ std::set<const CXFA_Node*> visited;
+ for (const CXFA_Node* pNode = GetXFANode(); pNode;
+ pNode = pNode->GetTemplateNodeIfExists()) {
+ if (!visited.insert(pNode).second)
+ break;
-void CJX_Object::ClearMapModuleBuffer() {
- XFA_MAPMODULEDATA* pModule = GetMapModuleData();
- if (!pModule)
- return;
+ absl::optional<CXFA_Measurement> result =
+ pNode->JSObject()->GetMapModuleMeasurement(key);
+ if (result.has_value())
+ return result;
- for (auto& pair : pModule->m_BufferMap) {
- XFA_MAPDATABLOCK* pBuffer = pair.second;
- if (pBuffer) {
- if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree)
- pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
-
- FX_Free(pBuffer);
- }
+ if (pNode->GetPacketType() == XFA_PacketType::Datasets)
+ break;
}
- pModule->m_BufferMap.clear();
- pModule->m_ValueMap.clear();
+ return absl::nullopt;
}
-void CJX_Object::RemoveMapModuleKey(void* pKey) {
- ASSERT(pKey);
-
- XFA_MAPMODULEDATA* pModule = GetMapModuleData();
- if (!pModule)
- return;
-
- auto it = pModule->m_BufferMap.find(pKey);
- if (it != pModule->m_BufferMap.end()) {
- XFA_MAPDATABLOCK* pBuffer = it->second;
- if (pBuffer) {
- if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree)
- pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
-
- FX_Free(pBuffer);
- }
- pModule->m_BufferMap.erase(it);
- }
- pModule->m_ValueMap.erase(pKey);
- return;
+bool CJX_Object::HasMapModuleKey(uint32_t key) const {
+ CFXJSE_MapModule* pModule = GetMapModule();
+ return pModule && pModule->HasKey(key);
}
-void CJX_Object::MergeAllData(CXFA_Object* pDstModule) {
- XFA_MAPMODULEDATA* pDstModuleData =
- ToNode(pDstModule)->JSObject()->CreateMapModuleData();
- XFA_MAPMODULEDATA* pSrcModuleData = GetMapModuleData();
- if (!pSrcModuleData)
- return;
-
- for (const auto& pair : pSrcModuleData->m_ValueMap)
- pDstModuleData->m_ValueMap[pair.first] = pair.second;
-
- for (const auto& pair : pSrcModuleData->m_BufferMap) {
- XFA_MAPDATABLOCK* pSrcBuffer = pair.second;
- XFA_MAPDATABLOCK*& pDstBuffer = pDstModuleData->m_BufferMap[pair.first];
- if (pSrcBuffer->pCallbackInfo && pSrcBuffer->pCallbackInfo->pFree &&
- !pSrcBuffer->pCallbackInfo->pCopy) {
- if (pDstBuffer) {
- pDstBuffer->pCallbackInfo->pFree(*(void**)pDstBuffer->GetData());
- pDstModuleData->m_BufferMap.erase(pair.first);
- }
- continue;
- }
- if (!pDstBuffer) {
- pDstBuffer = (XFA_MAPDATABLOCK*)FX_Alloc(
- uint8_t, sizeof(XFA_MAPDATABLOCK) + pSrcBuffer->iBytes);
- } else if (pDstBuffer->iBytes != pSrcBuffer->iBytes) {
- if (pDstBuffer->pCallbackInfo && pDstBuffer->pCallbackInfo->pFree) {
- pDstBuffer->pCallbackInfo->pFree(*(void**)pDstBuffer->GetData());
- }
- pDstBuffer = (XFA_MAPDATABLOCK*)FX_Realloc(
- uint8_t, pDstBuffer, sizeof(XFA_MAPDATABLOCK) + pSrcBuffer->iBytes);
- } else if (pDstBuffer->pCallbackInfo && pDstBuffer->pCallbackInfo->pFree) {
- pDstBuffer->pCallbackInfo->pFree(*(void**)pDstBuffer->GetData());
- }
- if (!pDstBuffer)
- continue;
-
- pDstBuffer->pCallbackInfo = pSrcBuffer->pCallbackInfo;
- pDstBuffer->iBytes = pSrcBuffer->iBytes;
- memcpy(pDstBuffer->GetData(), pSrcBuffer->GetData(), pSrcBuffer->iBytes);
- if (pDstBuffer->pCallbackInfo && pDstBuffer->pCallbackInfo->pCopy) {
- pDstBuffer->pCallbackInfo->pCopy(*(void**)pDstBuffer->GetData());
- }
- }
+void CJX_Object::RemoveMapModuleKey(uint32_t key) {
+ CFXJSE_MapModule* pModule = GetMapModule();
+ if (pModule)
+ pModule->RemoveKey(key);
}
-void CJX_Object::MoveBufferMapData(CXFA_Object* pDstModule) {
- if (!pDstModule)
+void CJX_Object::MergeAllData(CXFA_Object* pDstObj) {
+ CFXJSE_MapModule* pDstModule = ToNode(pDstObj)->JSObject()->CreateMapModule();
+ CFXJSE_MapModule* pSrcModule = GetMapModule();
+ if (!pSrcModule)
return;
- bool bNeedMove = true;
- if (pDstModule->GetElementType() != GetXFAObject()->GetElementType())
- bNeedMove = false;
+ pDstModule->MergeDataFrom(pSrcModule);
+}
- if (bNeedMove)
- ToNode(pDstModule)->JSObject()->SetCalcData(ReleaseCalcData());
- if (!pDstModule->IsNodeV())
+void CJX_Object::MoveBufferMapData(CXFA_Object* pDstObj) {
+ if (!pDstObj)
return;
- WideString wsValue = ToNode(pDstModule)->JSObject()->GetContent(false);
+ if (pDstObj->GetElementType() == GetXFAObject()->GetElementType())
+ ToNode(pDstObj)->JSObject()->TakeCalcDataFrom(this);
+
+ if (!pDstObj->IsNodeV())
+ return;
+
+ WideString wsValue = ToNode(pDstObj)->JSObject()->GetContent(false);
WideString wsFormatValue(wsValue);
- CXFA_Node* pNode = ToNode(pDstModule)->GetContainerNode();
+ CXFA_Node* pNode = ToNode(pDstObj)->GetContainerNode();
if (pNode)
wsFormatValue = pNode->GetFormatDataValue(wsValue);
- ToNode(pDstModule)
- ->JSObject()
- ->SetContent(wsValue, wsFormatValue, true, true, true);
+ ToNode(pDstObj)->JSObject()->SetContent(wsValue, wsFormatValue, true, true,
+ true);
}
-void CJX_Object::MoveBufferMapData(CXFA_Object* pSrcModule,
- CXFA_Object* pDstModule) {
- if (!pSrcModule || !pDstModule)
+void CJX_Object::MoveBufferMapData(CXFA_Object* pSrcObj, CXFA_Object* pDstObj) {
+ if (!pSrcObj || !pDstObj)
return;
- CXFA_Node* pSrcChild = ToNode(pSrcModule)->GetFirstChild();
- CXFA_Node* pDstChild = ToNode(pDstModule)->GetFirstChild();
+ CXFA_Node* pSrcChild = ToNode(pSrcObj)->GetFirstChild();
+ CXFA_Node* pDstChild = ToNode(pDstObj)->GetFirstChild();
while (pSrcChild && pDstChild) {
MoveBufferMapData(pSrcChild, pDstChild);
-
pSrcChild = pSrcChild->GetNextSibling();
pDstChild = pDstChild->GetNextSibling();
}
- ToNode(pSrcModule)->JSObject()->MoveBufferMapData(pDstModule);
+ ToNode(pSrcObj)->JSObject()->MoveBufferMapData(pDstObj);
}
-void CJX_Object::OnChanging(XFA_Attribute eAttr, bool bNotify) {
- if (!bNotify || !ToNode(GetXFAObject())->IsInitialized())
+void CJX_Object::OnChanging(XFA_Attribute eAttr) {
+ if (!GetXFANode()->IsInitialized())
return;
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
- if (pNotify)
- pNotify->OnValueChanging(ToNode(GetXFAObject()), eAttr);
+ if (!pNotify)
+ return;
+
+ pNotify->OnValueChanging(GetXFANode(), eAttr);
}
-void CJX_Object::OnChanged(XFA_Attribute eAttr,
- bool bNotify,
- bool bScriptModify) {
- if (bNotify && ToNode(GetXFAObject())->IsInitialized())
- ToNode(GetXFAObject())->SendAttributeChangeMessage(eAttr, bScriptModify);
+void CJX_Object::OnChanged(XFA_Attribute eAttr, bool bScriptModify) {
+ if (!GetXFANode()->IsInitialized())
+ return;
+
+ GetXFANode()->SendAttributeChangeMessage(eAttr, bScriptModify);
}
-void CJX_Object::SetCalcData(std::unique_ptr<CXFA_CalcData> data) {
- calc_data_ = std::move(data);
+CJX_Object::CalcData* CJX_Object::GetOrCreateCalcData(cppgc::Heap* heap) {
+ if (!calc_data_) {
+ calc_data_ =
+ cppgc::MakeGarbageCollected<CalcData>(heap->GetAllocationHandle());
+ }
+ return calc_data_;
}
-std::unique_ptr<CXFA_CalcData> CJX_Object::ReleaseCalcData() {
- return std::move(calc_data_);
+void CJX_Object::TakeCalcDataFrom(CJX_Object* that) {
+ calc_data_ = that->calc_data_;
+ that->calc_data_ = nullptr;
}
-void CJX_Object::ScriptAttributeString(CFXJSE_Value* pValue,
+void CJX_Object::ScriptAttributeString(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (!bSetting) {
- pValue->SetString(GetAttribute(eAttribute).ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(
+ pIsolate, GetAttributeByEnum(eAttribute).ToUTF8().AsStringView());
return;
}
- WideString wsValue = pValue->ToWideString();
- SetAttribute(eAttribute, wsValue.AsStringView(), true);
+ WideString wsValue = fxv8::ReentrantToWideStringHelper(pIsolate, *pValue);
+ SetAttributeByEnum(eAttribute, wsValue, true);
if (eAttribute != XFA_Attribute::Use ||
GetXFAObject()->GetElementType() != XFA_Element::Desc) {
return;
@@ -1100,33 +1010,34 @@
WideString wsSOM;
if (!wsValue.IsEmpty()) {
if (wsValue[0] == '#')
- wsID = wsValue.Substr(1, wsValue.GetLength() - 1);
+ wsID = wsValue.Substr(1);
else
wsSOM = std::move(wsValue);
}
CXFA_Node* pProtoNode = nullptr;
if (!wsSOM.IsEmpty()) {
- XFA_RESOLVENODE_RS resolveNodeRS;
- bool bRet = GetDocument()->GetScriptContext()->ResolveObjects(
- pProtoRoot, wsSOM.AsStringView(), &resolveNodeRS,
- XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
- XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
- XFA_RESOLVENODE_Siblings,
- nullptr);
- if (bRet && resolveNodeRS.objects.front()->IsNode())
- pProtoNode = resolveNodeRS.objects.front()->AsNode();
-
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+ GetDocument()->GetScriptContext()->ResolveObjects(
+ pProtoRoot, wsSOM.AsStringView(),
+ Mask<XFA_ResolveFlag>{
+ XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes,
+ XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent,
+ XFA_ResolveFlag::kSiblings});
+ if (maybeResult.has_value() &&
+ maybeResult.value().objects.front()->IsNode()) {
+ pProtoNode = maybeResult.value().objects.front()->AsNode();
+ }
} else if (!wsID.IsEmpty()) {
pProtoNode = GetDocument()->GetNodeByID(pProtoRoot, wsID.AsStringView());
}
- if (!pProtoNode)
+ if (!pProtoNode || pProtoNode->GetPacketType() != XFA_PacketType::Template)
return;
- CXFA_Node* pHeadChild = ToNode(GetXFAObject())->GetFirstChild();
+ CXFA_Node* pHeadChild = GetXFANode()->GetFirstChild();
while (pHeadChild) {
CXFA_Node* pSibling = pHeadChild->GetNextSibling();
- ToNode(GetXFAObject())->RemoveChildAndNotify(pHeadChild, true);
+ GetXFANode()->RemoveChildAndNotify(pHeadChild, true);
pHeadChild = pSibling;
}
@@ -1135,32 +1046,37 @@
while (pHeadChild) {
CXFA_Node* pSibling = pHeadChild->GetNextSibling();
pProtoForm->RemoveChildAndNotify(pHeadChild, true);
- ToNode(GetXFAObject())->InsertChildAndNotify(pHeadChild, nullptr);
+ GetXFANode()->InsertChildAndNotify(pHeadChild, nullptr);
pHeadChild = pSibling;
}
}
-void CJX_Object::ScriptAttributeBool(CFXJSE_Value* pValue,
+void CJX_Object::ScriptAttributeBool(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- SetBoolean(eAttribute, pValue->ToBoolean(), true);
+ SetBoolean(eAttribute, fxv8::ReentrantToBooleanHelper(pIsolate, *pValue),
+ true);
return;
}
- pValue->SetString(GetBoolean(eAttribute) ? "1" : "0");
+ *pValue = fxv8::NewStringHelper(pIsolate, GetBoolean(eAttribute) ? "1" : "0");
}
-void CJX_Object::ScriptAttributeInteger(CFXJSE_Value* pValue,
+void CJX_Object::ScriptAttributeInteger(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- SetInteger(eAttribute, pValue->ToInteger(), true);
+ SetInteger(eAttribute, fxv8::ReentrantToInt32Helper(pIsolate, *pValue),
+ true);
return;
}
- pValue->SetInteger(GetInteger(eAttribute));
+ *pValue = fxv8::NewNumberHelper(pIsolate, GetInteger(eAttribute));
}
-void CJX_Object::ScriptSomFontColor(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomFontColor(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Font* font = ToNode(object_.Get())->GetOrCreateFontIfPossible();
@@ -1171,7 +1087,8 @@
int32_t r;
int32_t g;
int32_t b;
- std::tie(r, g, b) = StrToRGB(pValue->ToWideString());
+ std::tie(r, g, b) =
+ StrToRGB(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
FX_ARGB color = ArgbEncode(0xff, r, g, b);
font->SetColor(color);
return;
@@ -1182,10 +1099,12 @@
int32_t g;
int32_t b;
std::tie(a, r, g, b) = ArgbDecode(font->GetColor());
- pValue->SetString(ByteString::Format("%d,%d,%d", r, g, b).AsStringView());
+ *pValue = fxv8::NewStringHelper(
+ pIsolate, ByteString::Format("%d,%d,%d", r, g, b).AsStringView());
}
-void CJX_Object::ScriptSomFillColor(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomFillColor(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Border* border = ToNode(object_.Get())->GetOrCreateBorderIfPossible();
@@ -1197,23 +1116,25 @@
int32_t r;
int32_t g;
int32_t b;
- std::tie(r, g, b) = StrToRGB(pValue->ToWideString());
+ std::tie(r, g, b) =
+ StrToRGB(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
FX_ARGB color = ArgbEncode(0xff, r, g, b);
borderfill->SetColor(color);
return;
}
- FX_ARGB color = borderfill->GetColor(false);
+ FX_ARGB color = borderfill->GetFillColor();
int32_t a;
int32_t r;
int32_t g;
int32_t b;
std::tie(a, r, g, b) = ArgbDecode(color);
- pValue->SetString(
- WideString::Format(L"%d,%d,%d", r, g, b).ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(
+ pIsolate, ByteString::Format("%d,%d,%d", r, g, b).AsStringView());
}
-void CJX_Object::ScriptSomBorderColor(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomBorderColor(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Border* border = ToNode(object_.Get())->GetOrCreateBorderIfPossible();
@@ -1222,7 +1143,8 @@
int32_t r = 0;
int32_t g = 0;
int32_t b = 0;
- std::tie(r, g, b) = StrToRGB(pValue->ToWideString());
+ std::tie(r, g, b) =
+ StrToRGB(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
FX_ARGB rgb = ArgbEncode(100, r, g, b);
for (int32_t i = 0; i < iSize; ++i) {
CXFA_Edge* edge = border->GetEdgeIfExists(i);
@@ -1240,11 +1162,12 @@
int32_t g;
int32_t b;
std::tie(a, r, g, b) = ArgbDecode(color);
- pValue->SetString(
- WideString::Format(L"%d,%d,%d", r, g, b).ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(
+ pIsolate, ByteString::Format("%d,%d,%d", r, g, b).AsStringView());
}
-void CJX_Object::ScriptSomBorderWidth(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomBorderWidth(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Border* border = ToNode(object_.Get())->GetOrCreateBorderIfPossible();
@@ -1252,24 +1175,26 @@
CXFA_Edge* edge = border->GetEdgeIfExists(0);
CXFA_Measurement thickness =
edge ? edge->GetMSThickness() : CXFA_Measurement(0.5, XFA_Unit::Pt);
- pValue->SetString(thickness.ToString().ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(
+ pIsolate, thickness.ToString().ToUTF8().AsStringView());
return;
}
if (pValue->IsEmpty())
return;
- WideString wsThickness = pValue->ToWideString();
- for (int32_t i = 0; i < border->CountEdges(); ++i) {
+ WideString wsThickness = fxv8::ReentrantToWideStringHelper(pIsolate, *pValue);
+ for (size_t i = 0; i < border->CountEdges(); ++i) {
CXFA_Edge* edge = border->GetEdgeIfExists(i);
if (edge)
edge->SetMSThickness(CXFA_Measurement(wsThickness.AsStringView()));
}
}
-void CJX_Object::ScriptSomMessage(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomMessage(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
- XFA_SOM_MESSAGETYPE iMessageType) {
+ SOMMessageType iMessageType) {
bool bNew = false;
CXFA_Validate* validate = ToNode(object_.Get())->GetValidateIfExists();
if (!validate) {
@@ -1280,16 +1205,17 @@
if (bSetting) {
if (validate) {
switch (iMessageType) {
- case XFA_SOM_ValidationMessage:
- validate->SetScriptMessageText(pValue->ToWideString());
+ case SOMMessageType::kValidationMessage:
+ validate->SetScriptMessageText(
+ fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
break;
- case XFA_SOM_FormatMessage:
- validate->SetFormatMessageText(pValue->ToWideString());
+ case SOMMessageType::kFormatMessage:
+ validate->SetFormatMessageText(
+ fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
break;
- case XFA_SOM_MandatoryMessage:
- validate->SetNullMessageText(pValue->ToWideString());
- break;
- default:
+ case SOMMessageType::kMandatoryMessage:
+ validate->SetNullMessageText(
+ fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
break;
}
}
@@ -1299,98 +1225,100 @@
if (!pNotify)
return;
- pNotify->AddCalcValidate(ToNode(GetXFAObject()));
+ pNotify->AddCalcValidate(GetXFANode());
}
return;
}
if (!validate) {
// TODO(dsinclair): Better error message?
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
WideString wsMessage;
switch (iMessageType) {
- case XFA_SOM_ValidationMessage:
+ case SOMMessageType::kValidationMessage:
wsMessage = validate->GetScriptMessageText();
break;
- case XFA_SOM_FormatMessage:
+ case SOMMessageType::kFormatMessage:
wsMessage = validate->GetFormatMessageText();
break;
- case XFA_SOM_MandatoryMessage:
+ case SOMMessageType::kMandatoryMessage:
wsMessage = validate->GetNullMessageText();
break;
- default:
- break;
}
- pValue->SetString(wsMessage.ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(pIsolate, wsMessage.ToUTF8().AsStringView());
}
-void CJX_Object::ScriptSomValidationMessage(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomValidationMessage(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- ScriptSomMessage(pValue, bSetting, XFA_SOM_ValidationMessage);
+ ScriptSomMessage(pIsolate, pValue, bSetting,
+ SOMMessageType::kValidationMessage);
}
-void CJX_Object::ScriptSomMandatoryMessage(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomMandatoryMessage(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
- ScriptSomMessage(pValue, bSetting, XFA_SOM_MandatoryMessage);
+ ScriptSomMessage(pIsolate, pValue, bSetting,
+ SOMMessageType::kMandatoryMessage);
}
-void CJX_Object::ScriptSomDefaultValue(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomDefaultValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute /* unused */) {
- XFA_Element eType = ToNode(GetXFAObject())->GetElementType();
+ XFA_Element eType = GetXFANode()->GetElementType();
// TODO(dsinclair): This should look through the properties on the node to see
// if defaultValue is defined and, if so, call that one. Just have to make
// sure that those defaultValue calls don't call back to this one ....
if (eType == XFA_Element::Field) {
- static_cast<CJX_Field*>(this)->defaultValue(pValue, bSetting,
+ static_cast<CJX_Field*>(this)->defaultValue(pIsolate, pValue, bSetting,
XFA_Attribute::Unknown);
return;
}
if (eType == XFA_Element::Draw) {
- static_cast<CJX_Draw*>(this)->defaultValue(pValue, bSetting,
+ static_cast<CJX_Draw*>(this)->defaultValue(pIsolate, pValue, bSetting,
XFA_Attribute::Unknown);
return;
}
if (eType == XFA_Element::Boolean) {
- static_cast<CJX_Boolean*>(this)->defaultValue(pValue, bSetting,
+ static_cast<CJX_Boolean*>(this)->defaultValue(pIsolate, pValue, bSetting,
XFA_Attribute::Unknown);
return;
}
if (bSetting) {
WideString wsNewValue;
- if (pValue &&
- !(pValue->IsEmpty() || pValue->IsNull() || pValue->IsUndefined())) {
- wsNewValue = pValue->ToWideString();
+ if (pValue && !(pValue->IsEmpty() || fxv8::IsNull(*pValue) ||
+ fxv8::IsUndefined(*pValue))) {
+ wsNewValue = fxv8::ReentrantToWideStringHelper(pIsolate, *pValue);
}
- WideString wsFormatValue(wsNewValue);
+ WideString wsFormatValue = wsNewValue;
CXFA_Node* pContainerNode = nullptr;
- if (ToNode(GetXFAObject())->GetPacketType() == XFA_PacketType::Datasets) {
+ if (GetXFANode()->GetPacketType() == XFA_PacketType::Datasets) {
WideString wsPicture;
- for (auto* pFormNode : ToNode(GetXFAObject())->GetBindItemsCopy()) {
+ for (auto* pFormNode : GetXFANode()->GetBindItemsCopy()) {
if (!pFormNode || pFormNode->HasRemovedChildren())
continue;
pContainerNode = pFormNode->GetContainerNode();
if (pContainerNode) {
wsPicture =
- pContainerNode->GetPictureContent(XFA_VALUEPICTURE_DataBind);
+ pContainerNode->GetPictureContent(XFA_ValuePicture::kDataBind);
}
if (!wsPicture.IsEmpty())
break;
pContainerNode = nullptr;
}
- } else if (ToNode(GetXFAObject())->GetPacketType() ==
- XFA_PacketType::Form) {
- pContainerNode = ToNode(GetXFAObject())->GetContainerNode();
+ } else if (GetXFANode()->GetPacketType() == XFA_PacketType::Form) {
+ pContainerNode = GetXFANode()->GetContainerNode();
}
if (pContainerNode)
@@ -1403,52 +1331,55 @@
WideString content = GetContent(true);
if (content.IsEmpty() && eType != XFA_Element::Text &&
eType != XFA_Element::SubmitUrl) {
- pValue->SetNull();
+ *pValue = fxv8::NewNullHelper(pIsolate);
} else if (eType == XFA_Element::Integer) {
- pValue->SetInteger(FXSYS_wtoi(content.c_str()));
+ *pValue = fxv8::NewNumberHelper(pIsolate, FXSYS_wtoi(content.c_str()));
} else if (eType == XFA_Element::Float || eType == XFA_Element::Decimal) {
CFGAS_Decimal decimal(content.AsStringView());
- pValue->SetFloat(decimal.ToFloat());
+ *pValue = fxv8::NewNumberHelper(pIsolate, decimal.ToFloat());
} else {
- pValue->SetString(content.ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(pIsolate, content.ToUTF8().AsStringView());
}
}
-void CJX_Object::ScriptSomDefaultValue_Read(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomDefaultValue_Read(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
WideString content = GetContent(true);
if (content.IsEmpty()) {
- pValue->SetNull();
+ *pValue = fxv8::NewNullHelper(pIsolate);
return;
}
- pValue->SetString(content.ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(pIsolate, content.ToUTF8().AsStringView());
}
-void CJX_Object::ScriptSomDataNode(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomDataNode(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- CXFA_Node* pDataNode = ToNode(GetXFAObject())->GetBindData();
+ CXFA_Node* pDataNode = GetXFANode()->GetBindData();
if (!pDataNode) {
- pValue->SetNull();
+ *pValue = fxv8::NewNullHelper(pIsolate);
return;
}
- pValue->Assign(GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
- pDataNode));
+ *pValue =
+ GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pDataNode);
}
-void CJX_Object::ScriptSomMandatory(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomMandatory(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Validate* validate =
@@ -1457,25 +1388,28 @@
return;
if (bSetting) {
- validate->SetNullTest(pValue->ToWideString());
+ validate->SetNullTest(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
return;
}
- pValue->SetString(XFA_AttributeValueToName(validate->GetNullTest()));
+ *pValue = fxv8::NewStringHelper(
+ pIsolate, XFA_AttributeValueToName(validate->GetNullTest()));
}
-void CJX_Object::ScriptSomInstanceIndex(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSomInstanceIndex(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (!bSetting) {
- pValue->SetInteger(Subform_and_SubformSet_InstanceIndex());
+ *pValue =
+ fxv8::NewNumberHelper(pIsolate, Subform_and_SubformSet_InstanceIndex());
return;
}
- int32_t iTo = pValue->ToInteger();
+ int32_t iTo = fxv8::ReentrantToInt32Helper(pIsolate, *pValue);
int32_t iFrom = Subform_and_SubformSet_InstanceIndex();
CXFA_Node* pManagerNode = nullptr;
- for (CXFA_Node* pNode = ToNode(GetXFAObject())->GetPrevSibling(); pNode;
+ for (CXFA_Node* pNode = GetXFANode()->GetPrevSibling(); pNode;
pNode = pNode->GetPrevSibling()) {
if (pNode->GetElementType() == XFA_Element::InstanceManager) {
pManagerNode = pNode;
@@ -1486,23 +1420,31 @@
return;
auto* mgr = static_cast<CJX_InstanceManager*>(pManagerNode->JSObject());
- mgr->MoveInstance(iTo, iFrom);
+ mgr->MoveInstance(pIsolate, iTo, iFrom);
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
if (!pNotify)
return;
- CXFA_Node* pToInstance = pManagerNode->GetItemIfExists(iTo);
- if (pToInstance && pToInstance->GetElementType() == XFA_Element::Subform) {
+ auto* pToInstance =
+ CXFA_Subform::FromNode(pManagerNode->GetItemIfExists(iTo));
+ if (pToInstance)
pNotify->RunSubformIndexChange(pToInstance);
- }
- CXFA_Node* pFromInstance = pManagerNode->GetItemIfExists(iFrom);
- if (pFromInstance &&
- pFromInstance->GetElementType() == XFA_Element::Subform) {
+ auto* pFromInstance =
+ CXFA_Subform::FromNode(pManagerNode->GetItemIfExists(iFrom));
+ if (pFromInstance)
pNotify->RunSubformIndexChange(pFromInstance);
- }
}
-void CJX_Object::ScriptSubmitFormatMode(CFXJSE_Value* pValue,
+void CJX_Object::ScriptSubmitFormatMode(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
+
+CJX_Object::CalcData::CalcData() = default;
+
+CJX_Object::CalcData::~CalcData() = default;
+
+void CJX_Object::CalcData::Trace(cppgc::Visitor* visitor) const {
+ ContainerTrace(visitor, m_Globals);
+}
diff --git a/fxjs/xfa/cjx_object.h b/fxjs/xfa/cjx_object.h
index 0633b5f..caa1a5e 100644
--- a/fxjs/xfa/cjx_object.h
+++ b/fxjs/xfa/cjx_object.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,53 +9,41 @@
#include <map>
#include <memory>
-#include <utility>
#include <vector>
-#include "core/fxcrt/unowned_ptr.h"
#include "core/fxcrt/widestring.h"
+#include "fxjs/gc/heap.h"
+#include "fxjs/xfa/fxjse.h"
#include "fxjs/xfa/jse_define.h"
-#include "third_party/base/optional.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/base/span.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/v8-forward.h"
#include "xfa/fxfa/fxfa_basic.h"
-#include "xfa/fxfa/parser/cxfa_measurement.h"
+class CFXJSE_Engine;
+class CFXJSE_MapModule;
class CFX_XMLElement;
-class CFXJSE_Value;
-class CFX_V8;
class CJX_Object;
-class CXFA_CalcData;
class CXFA_Document;
class CXFA_LayoutItem;
+class CXFA_Measurement;
class CXFA_Node;
class CXFA_Object;
-struct XFA_MAPMODULEDATA;
-typedef CJS_Result (*CJX_MethodCall)(
- CJX_Object* obj,
- CFX_V8* runtime,
- const std::vector<v8::Local<v8::Value>>& params);
+using CJX_MethodCall =
+ CJS_Result (*)(CJX_Object* obj,
+ CFXJSE_Engine* runtime,
+ const std::vector<v8::Local<v8::Value>>& params);
struct CJX_MethodSpec {
const char* pName;
CJX_MethodCall pMethodCall;
};
-typedef void (*PD_CALLBACK_FREEDATA)(void* pData);
-typedef void (*PD_CALLBACK_DUPLICATEDATA)(void*& pData);
-
-struct XFA_MAPDATABLOCKCALLBACKINFO {
- PD_CALLBACK_FREEDATA pFree;
- PD_CALLBACK_DUPLICATEDATA pCopy;
-};
-
-enum XFA_SOM_MESSAGETYPE {
- XFA_SOM_ValidationMessage,
- XFA_SOM_FormatMessage,
- XFA_SOM_MandatoryMessage
-};
-
-class CJX_Object {
+class CJX_Object : public cppgc::GarbageCollected<CJX_Object>,
+ public CFXJSE_HostObject {
public:
// Corresponds 1:1 with CJX_ subclasses.
enum class TypeTag {
@@ -96,51 +84,66 @@
Xfa,
};
- explicit CJX_Object(CXFA_Object* obj);
- virtual ~CJX_Object();
+ class CalcData : public cppgc::GarbageCollected<CalcData> {
+ public:
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
+ ~CalcData();
+ void Trace(cppgc::Visitor* visitor) const;
+
+ std::vector<cppgc::Member<CXFA_Node>> m_Globals;
+
+ private:
+ CalcData();
+ };
+
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
+ ~CJX_Object() override;
+
+ // CFXJSE_HostObject:
+ CJX_Object* AsCJXObject() override;
+
+ virtual void Trace(cppgc::Visitor* visitor) const;
virtual bool DynamicTypeIs(TypeTag eType) const;
JSE_PROP(className);
CXFA_Document* GetDocument() const;
- CXFA_Object* GetXFAObject() const { return object_.Get(); }
+ CXFA_Node* GetXFANode() const;
+ CXFA_Object* GetXFAObject() const { return object_; }
void SetCalcRecursionCount(size_t count) { calc_recursion_count_ = count; }
size_t GetCalcRecursionCount() const { return calc_recursion_count_; }
- void SetLayoutItem(CXFA_LayoutItem* item) { layout_item_.Reset(item); }
- CXFA_LayoutItem* GetLayoutItem() const { return layout_item_.Get(); }
+ void SetLayoutItem(CXFA_LayoutItem* item) { layout_item_ = item; }
+ CXFA_LayoutItem* GetLayoutItem() const { return layout_item_; }
bool HasMethod(const WideString& func) const;
CJS_Result RunMethod(const WideString& func,
const std::vector<v8::Local<v8::Value>>& params);
- bool HasAttribute(XFA_Attribute eAttr);
- void SetAttribute(XFA_Attribute eAttr, WideStringView wsValue, bool bNotify);
- void SetAttribute(WideStringView wsAttr,
- WideStringView wsValue,
- bool bNotify);
+ bool HasAttribute(XFA_Attribute eAttr) const;
+ WideString GetAttributeByString(WideStringView attr) const;
+ WideString GetAttributeByEnum(XFA_Attribute attr) const;
+ absl::optional<WideString> TryAttribute(XFA_Attribute eAttr,
+ bool bUseDefault) const;
+ void SetAttributeByEnum(XFA_Attribute eAttr,
+ const WideString& wsValue,
+ bool bNotify);
+ void SetAttributeByString(WideStringView wsAttr, const WideString& wsValue);
void RemoveAttribute(WideStringView wsAttr);
- WideString GetAttribute(WideStringView attr);
- WideString GetAttribute(XFA_Attribute attr);
- Optional<WideString> TryAttribute(WideStringView wsAttr, bool bUseDefault);
- Optional<WideString> TryAttribute(XFA_Attribute eAttr, bool bUseDefault);
- Optional<WideString> TryContent(bool bScriptModify, bool bProto);
+ WideString GetContent(bool bScriptModify) const;
+ absl::optional<WideString> TryContent(bool bScriptModify, bool bProto) const;
void SetContent(const WideString& wsContent,
const WideString& wsXMLValue,
bool bNotify,
bool bScriptModify,
bool bSyncData);
- WideString GetContent(bool bScriptModify);
template <typename T>
T* GetProperty(int32_t index, XFA_Element eType) const {
- CXFA_Node* node;
- int32_t count;
- std::tie(node, count) = GetPropertyInternal(index, eType);
- return static_cast<T*>(node);
+ return static_cast<T*>(GetPropertyInternal(index, eType));
}
template <typename T>
T* GetOrCreateProperty(int32_t index, XFA_Element eType) {
@@ -148,9 +151,7 @@
}
void SetAttributeValue(const WideString& wsValue,
- const WideString& wsXMLValue,
- bool bNotify,
- bool bScriptModify);
+ const WideString& wsXMLValue);
// Not actual properties, but invoked as property handlers to cover
// a broad range of underlying properties.
@@ -170,105 +171,113 @@
JSE_PROP(ScriptSomInstanceIndex);
JSE_PROP(ScriptSubmitFormatMode);
- void ScriptSomMessage(CFXJSE_Value* pValue,
- bool bSetting,
- XFA_SOM_MESSAGETYPE iMessageType);
+ absl::optional<WideString> TryNamespace() const;
- Optional<WideString> TryNamespace();
-
- Optional<int32_t> TryInteger(XFA_Attribute eAttr, bool bUseDefault) const;
- void SetInteger(XFA_Attribute eAttr, int32_t iValue, bool bNotify);
int32_t GetInteger(XFA_Attribute eAttr) const;
+ absl::optional<int32_t> TryInteger(XFA_Attribute eAttr,
+ bool bUseDefault) const;
+ void SetInteger(XFA_Attribute eAttr, int32_t iValue, bool bNotify);
- Optional<WideString> TryCData(XFA_Attribute eAttr, bool bUseDefault) const;
- void SetCData(XFA_Attribute eAttr,
- const WideString& wsValue,
- bool bNotify,
- bool bScriptModify);
WideString GetCData(XFA_Attribute eAttr) const;
+ absl::optional<WideString> TryCData(XFA_Attribute eAttr,
+ bool bUseDefault) const;
+ void SetCData(XFA_Attribute eAttr, const WideString& wsValue);
- Optional<XFA_AttributeValue> TryEnum(XFA_Attribute eAttr,
- bool bUseDefault) const;
- void SetEnum(XFA_Attribute eAttr, XFA_AttributeValue eValue, bool bNotify);
XFA_AttributeValue GetEnum(XFA_Attribute eAttr) const;
+ absl::optional<XFA_AttributeValue> TryEnum(XFA_Attribute eAttr,
+ bool bUseDefault) const;
+ void SetEnum(XFA_Attribute eAttr, XFA_AttributeValue eValue, bool bNotify);
- Optional<bool> TryBoolean(XFA_Attribute eAttr, bool bUseDefault);
+ bool GetBoolean(XFA_Attribute eAttr) const;
+ absl::optional<bool> TryBoolean(XFA_Attribute eAttr, bool bUseDefault) const;
void SetBoolean(XFA_Attribute eAttr, bool bValue, bool bNotify);
- bool GetBoolean(XFA_Attribute eAttr);
- Optional<CXFA_Measurement> TryMeasure(XFA_Attribute eAttr,
- bool bUseDefault) const;
- Optional<float> TryMeasureAsFloat(XFA_Attribute attr) const;
- void SetMeasure(XFA_Attribute eAttr, CXFA_Measurement mValue, bool bNotify);
CXFA_Measurement GetMeasure(XFA_Attribute eAttr) const;
float GetMeasureInUnit(XFA_Attribute eAttr, XFA_Unit unit) const;
+ absl::optional<CXFA_Measurement> TryMeasure(XFA_Attribute eAttr,
+ bool bUseDefault) const;
+ absl::optional<float> TryMeasureAsFloat(XFA_Attribute attr) const;
+ void SetMeasure(XFA_Attribute eAttr,
+ const CXFA_Measurement& mValue,
+ bool bNotify);
- void MergeAllData(CXFA_Object* pDstModule);
+ void MergeAllData(CXFA_Object* pDstObj);
- void SetCalcData(std::unique_ptr<CXFA_CalcData> data);
- CXFA_CalcData* GetCalcData() const { return calc_data_.get(); }
- std::unique_ptr<CXFA_CalcData> ReleaseCalcData();
+ CalcData* GetCalcData() const { return calc_data_; }
+ CalcData* GetOrCreateCalcData(cppgc::Heap* heap);
+ void TakeCalcDataFrom(CJX_Object* that);
- int32_t InstanceManager_SetInstances(int32_t iDesired);
- int32_t InstanceManager_MoveInstance(int32_t iTo, int32_t iFrom);
-
- void ThrowInvalidPropertyException() const;
- void ThrowArgumentMismatchException() const;
- void ThrowIndexOutOfBoundsException() const;
- void ThrowParamCountMismatchException(const WideString& method) const;
- void ThrowTooManyOccurancesException(const WideString& obj) const;
+ void ThrowInvalidPropertyException(v8::Isolate* pIsolate) const;
+ void ThrowArgumentMismatchException(v8::Isolate* pIsolate) const;
+ void ThrowIndexOutOfBoundsException(v8::Isolate* pIsolate) const;
+ void ThrowParamCountMismatchException(v8::Isolate* pIsolate,
+ const WideString& method) const;
+ void ThrowTooManyOccurrencesException(v8::Isolate* pIsolate,
+ const WideString& obj) const;
protected:
+ enum class SOMMessageType {
+ kValidationMessage,
+ kFormatMessage,
+ kMandatoryMessage
+ };
+
+ explicit CJX_Object(CXFA_Object* obj);
+
+ void ScriptSomMessage(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
+ bool bSetting,
+ SOMMessageType iMessageType);
+ void SetAttributeValueImpl(const WideString& wsValue,
+ const WideString& wsXMLValue,
+ bool bNotify,
+ bool bScriptModify);
+ void SetCDataImpl(XFA_Attribute eAttr,
+ const WideString& wsValue,
+ bool bNotify,
+ bool bScriptModify);
void DefineMethods(pdfium::span<const CJX_MethodSpec> methods);
- void MoveBufferMapData(CXFA_Object* pSrcModule, CXFA_Object* pDstModule);
- void SetMapModuleString(void* pKey, WideStringView wsValue);
- void ThrowException(const WideString& str) const;
+ void MoveBufferMapData(CXFA_Object* pSrcObj, CXFA_Object* pDstObj);
+ void ThrowException(v8::Isolate* pIsolate, const WideString& str) const;
private:
using Type__ = CJX_Object;
static const TypeTag static_type__ = TypeTag::Object;
- std::pair<CXFA_Node*, int32_t> GetPropertyInternal(int32_t index,
- XFA_Element eType) const;
+ CXFA_Node* GetPropertyInternal(int32_t index, XFA_Element eType) const;
CXFA_Node* GetOrCreatePropertyInternal(int32_t index, XFA_Element eType);
- void OnChanged(XFA_Attribute eAttr, bool bNotify, bool bScriptModify);
- void OnChanging(XFA_Attribute eAttr, bool bNotify);
- void SetUserData(void* pKey,
- void* pData,
- const XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo);
+ void OnChanging(XFA_Attribute eAttr);
+ void OnChanged(XFA_Attribute eAttr, bool bScriptModify);
// Returns a pointer to the XML node that needs to be updated with the new
// attribute value. |nullptr| if no update is needed.
- CFX_XMLElement* SetValue(XFA_Attribute eAttr, void* pValue, bool bNotify);
+ CFX_XMLElement* SetValue(XFA_Attribute eAttr, int32_t value, bool bNotify);
int32_t Subform_and_SubformSet_InstanceIndex();
- XFA_MAPMODULEDATA* CreateMapModuleData();
- XFA_MAPMODULEDATA* GetMapModuleData() const;
- void SetMapModuleValue(void* pKey, void* pValue);
- Optional<void*> GetMapModuleValue(void* pKey) const;
- Optional<WideString> GetMapModuleString(void* pKey) const;
- void SetMapModuleBuffer(void* pKey,
- void* pValue,
- int32_t iBytes,
- const XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo);
- bool GetMapModuleBuffer(void* pKey, void** pValue, int32_t* pBytes) const;
- bool HasMapModuleKey(void* pKey);
- void ClearMapModuleBuffer();
- void RemoveMapModuleKey(void* pKey);
- void MoveBufferMapData(CXFA_Object* pDstModule);
+ CFXJSE_MapModule* CreateMapModule();
+ CFXJSE_MapModule* GetMapModule() const;
+ void SetMapModuleValue(uint32_t key, int32_t value);
+ void SetMapModuleString(uint32_t key, const WideString& wsValue);
+ void SetMapModuleMeasurement(uint32_t key, const CXFA_Measurement& value);
+ absl::optional<int32_t> GetMapModuleValue(uint32_t key) const;
+ absl::optional<WideString> GetMapModuleString(uint32_t key) const;
+ absl::optional<CXFA_Measurement> GetMapModuleMeasurement(uint32_t key) const;
+ absl::optional<int32_t> GetMapModuleValueFollowingChain(uint32_t key) const;
+ absl::optional<WideString> GetMapModuleStringFollowingChain(
+ uint32_t key) const;
+ absl::optional<CXFA_Measurement> GetMapModuleMeasurementFollowingChain(
+ uint32_t key) const;
+ bool HasMapModuleKey(uint32_t key) const;
+ void RemoveMapModuleKey(uint32_t key);
+ void MoveBufferMapData(CXFA_Object* pDstObj);
- UnownedPtr<CXFA_Object> object_;
- UnownedPtr<CXFA_LayoutItem> layout_item_;
- std::unique_ptr<XFA_MAPMODULEDATA> map_module_data_;
- std::unique_ptr<CXFA_CalcData> calc_data_;
+ cppgc::Member<CXFA_Object> object_;
+ cppgc::Member<CXFA_LayoutItem> layout_item_;
+ cppgc::Member<CalcData> calc_data_;
+ std::unique_ptr<CFXJSE_MapModule> map_module_;
std::map<ByteString, CJX_MethodCall> method_specs_;
size_t calc_recursion_count_ = 0;
};
-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_object_embeddertest.cpp b/fxjs/xfa/cjx_object_embeddertest.cpp
new file mode 100644
index 0000000..b433665
--- /dev/null
+++ b/fxjs/xfa/cjx_object_embeddertest.cpp
@@ -0,0 +1,20 @@
+// Copyright 2022 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fxjs/xfa/cjx_object.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/xfa_js_embedder_test.h"
+
+class CJX_ObjectEmbedderTest : public XFAJSEmbedderTest {};
+
+// Should not crash, but document is not valid.
+TEST_F(CJX_ObjectEmbedderTest, Bug1327884) {
+ ASSERT_FALSE(OpenDocument("bug_1327884.pdf"));
+}
+
+// Should not CHECK(), but document is uninteresting.
+TEST_F(CJX_ObjectEmbedderTest, Bug1333298) {
+ ASSERT_TRUE(OpenDocument("bug_1333298.pdf"));
+}
diff --git a/fxjs/xfa/cjx_occur.cpp b/fxjs/xfa/cjx_occur.cpp
index de8942d..657b230 100644
--- a/fxjs/xfa/cjx_occur.cpp
+++ b/fxjs/xfa/cjx_occur.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,9 +6,9 @@
#include "fxjs/xfa/cjx_occur.h"
-#include <algorithm>
-
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/parser/cxfa_occur.h"
CJX_Occur::CJX_Occur(CXFA_Occur* node) : CJX_Node(node) {}
@@ -19,24 +19,27 @@
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_Occur::max(CFXJSE_Value* pValue,
+void CJX_Occur::max(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Occur* occur = static_cast<CXFA_Occur*>(GetXFANode());
if (!bSetting) {
- pValue->SetInteger(occur->GetMax());
+ *pValue = fxv8::NewNumberHelper(pIsolate, occur->GetMax());
return;
}
- occur->SetMax(pValue->ToInteger());
+ occur->SetMax(fxv8::ReentrantToInt32Helper(pIsolate, *pValue));
}
-void CJX_Occur::min(CFXJSE_Value* pValue,
+// NOLINTNEXTLINE(build/include_what_you_use)
+void CJX_Occur::min(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CXFA_Occur* occur = static_cast<CXFA_Occur*>(GetXFANode());
if (!bSetting) {
- pValue->SetInteger(occur->GetMin());
+ *pValue = fxv8::NewNumberHelper(pIsolate, occur->GetMin());
return;
}
- occur->SetMin(pValue->ToInteger());
+ occur->SetMin(fxv8::ReentrantToInt32Helper(pIsolate, *pValue));
}
diff --git a/fxjs/xfa/cjx_occur.h b/fxjs/xfa/cjx_occur.h
index 8b912b6..06887dd 100644
--- a/fxjs/xfa/cjx_occur.h
+++ b/fxjs/xfa/cjx_occur.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Occur final : public CJX_Node {
public:
- explicit CJX_Occur(CXFA_Occur* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Occur() override;
// CJX_Object:
@@ -24,6 +24,8 @@
JSE_PROP(min);
private:
+ explicit CJX_Occur(CXFA_Occur* node);
+
using Type__ = CJX_Occur;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_packet.cpp b/fxjs/xfa/cjx_packet.cpp
index 2c8b67d..e77f165 100644
--- a/fxjs/xfa/cjx_packet.cpp
+++ b/fxjs/xfa/cjx_packet.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,10 +10,12 @@
#include <vector>
#include "core/fxcrt/xml/cfx_xmldocument.h"
+#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmltext.h"
#include "fxjs/cfx_v8.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cxfa_packet.h"
@@ -27,14 +29,14 @@
DefineMethods(MethodSpecs);
}
-CJX_Packet::~CJX_Packet() {}
+CJX_Packet::~CJX_Packet() = default;
bool CJX_Packet::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_Packet::getAttribute(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -49,7 +51,7 @@
}
CJS_Result CJX_Packet::setAttribute(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 2)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -63,21 +65,20 @@
}
CJS_Result CJX_Packet::removeAttribute(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
CFX_XMLElement* pElement = ToXMLElement(GetXFANode()->GetXMLMappingNode());
- if (pElement) {
- WideString name = runtime->ToWideString(params[0]);
- if (pElement->HasAttribute(name))
- pElement->RemoveAttribute(name);
- }
+ if (pElement)
+ pElement->RemoveAttribute(runtime->ToWideString(params[0]));
+
return CJS_Result::Success(runtime->NewNull());
}
-void CJX_Packet::content(CFXJSE_Value* pValue,
+void CJX_Packet::content(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
CFX_XMLElement* element = ToXMLElement(GetXFANode()->GetXMLMappingNode());
@@ -87,9 +88,10 @@
GetXFANode()
->GetDocument()
->GetNotify()
- ->GetHDOC()
+ ->GetFFDoc()
->GetXMLDocument()
- ->CreateNode<CFX_XMLText>(pValue->ToWideString()));
+ ->CreateNode<CFX_XMLText>(
+ fxv8::ReentrantToWideStringHelper(pIsolate, *pValue)));
}
return;
}
@@ -98,5 +100,5 @@
if (element)
wsTextData = element->GetTextData();
- pValue->SetString(wsTextData.ToUTF8().AsStringView());
+ *pValue = fxv8::NewStringHelper(pIsolate, wsTextData.ToUTF8().AsStringView());
}
diff --git a/fxjs/xfa/cjx_packet.h b/fxjs/xfa/cjx_packet.h
index df4a987..4b4687c 100644
--- a/fxjs/xfa/cjx_packet.h
+++ b/fxjs/xfa/cjx_packet.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Packet final : public CJX_Node {
public:
- explicit CJX_Packet(CXFA_Packet* packet);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Packet() override;
// CJX_Object:
@@ -27,6 +27,8 @@
JSE_PROP(content);
private:
+ explicit CJX_Packet(CXFA_Packet* packet);
+
using Type__ = CJX_Packet;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_script.cpp b/fxjs/xfa/cjx_script.cpp
index 482a57e..2c02b2b 100644
--- a/fxjs/xfa/cjx_script.cpp
+++ b/fxjs/xfa/cjx_script.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,7 +6,8 @@
#include "fxjs/xfa/cjx_script.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "fxjs/fxv8.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/parser/cxfa_script.h"
CJX_Script::CJX_Script(CXFA_Script* node) : CJX_Node(node) {}
@@ -17,12 +18,13 @@
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_Script::stateless(CFXJSE_Value* pValue,
+void CJX_Script::stateless(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- pValue->SetString(FX_UTF8Encode(WideStringView(L"0", 1)).AsStringView());
+ *pValue = fxv8::NewStringHelper(pIsolate, "0");
}
diff --git a/fxjs/xfa/cjx_script.h b/fxjs/xfa/cjx_script.h
index af7c985..272ec2a 100644
--- a/fxjs/xfa/cjx_script.h
+++ b/fxjs/xfa/cjx_script.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Script final : public CJX_Node {
public:
- explicit CJX_Script(CXFA_Script* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Script() override;
// CJX_Object:
@@ -23,6 +23,8 @@
JSE_PROP(stateless);
private:
+ explicit CJX_Script(CXFA_Script* node);
+
using Type__ = CJX_Script;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_signaturepseudomodel.cpp b/fxjs/xfa/cjx_signaturepseudomodel.cpp
index 97ecd6e..a740cb8 100644
--- a/fxjs/xfa/cjx_signaturepseudomodel.cpp
+++ b/fxjs/xfa/cjx_signaturepseudomodel.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,9 +8,10 @@
#include <vector>
-#include "fxjs/cfx_v8.h"
#include "fxjs/js_resources.h"
+#include "fxjs/xfa/cfxjse_engine.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/parser/cscript_signaturepseudomodel.h"
const CJX_MethodSpec CJX_SignaturePseudoModel::MethodSpecs[] = {
@@ -25,14 +26,14 @@
DefineMethods(MethodSpecs);
}
-CJX_SignaturePseudoModel::~CJX_SignaturePseudoModel() {}
+CJX_SignaturePseudoModel::~CJX_SignaturePseudoModel() = default;
bool CJX_SignaturePseudoModel::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_SignaturePseudoModel::verifySignature(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 4)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -41,7 +42,7 @@
}
CJS_Result CJX_SignaturePseudoModel::sign(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() < 3 || params.size() > 7)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -50,7 +51,7 @@
}
CJS_Result CJX_SignaturePseudoModel::enumerate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -59,7 +60,7 @@
}
CJS_Result CJX_SignaturePseudoModel::clear(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.empty() || params.size() > 2)
return CJS_Result::Failure(JSMessage::kParamError);
diff --git a/fxjs/xfa/cjx_signaturepseudomodel.h b/fxjs/xfa/cjx_signaturepseudomodel.h
index ed77238..6cf3460 100644
--- a/fxjs/xfa/cjx_signaturepseudomodel.h
+++ b/fxjs/xfa/cjx_signaturepseudomodel.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_SignaturePseudoModel final : public CJX_Object {
public:
- explicit CJX_SignaturePseudoModel(CScript_SignaturePseudoModel* model);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_SignaturePseudoModel() override;
// CJX_Object:
@@ -26,6 +26,8 @@
JSE_METHOD(clear);
private:
+ explicit CJX_SignaturePseudoModel(CScript_SignaturePseudoModel* model);
+
using Type__ = CJX_SignaturePseudoModel;
using ParentType__ = CJX_Object;
diff --git a/fxjs/xfa/cjx_source.cpp b/fxjs/xfa/cjx_source.cpp
index f6d3187..33a11ff 100644
--- a/fxjs/xfa/cjx_source.cpp
+++ b/fxjs/xfa/cjx_source.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -35,13 +35,13 @@
DefineMethods(MethodSpecs);
}
-CJX_Source::~CJX_Source() {}
+CJX_Source::~CJX_Source() = default;
bool CJX_Source::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-CJS_Result CJX_Source::next(CFX_V8* runtime,
+CJS_Result CJX_Source::next(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -50,7 +50,7 @@
}
CJS_Result CJX_Source::cancelBatch(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -58,7 +58,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Source::first(CFX_V8* runtime,
+CJS_Result CJX_Source::first(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -67,7 +67,7 @@
}
CJS_Result CJX_Source::updateBatch(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -76,7 +76,7 @@
}
CJS_Result CJX_Source::previous(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -84,7 +84,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Source::isBOF(CFX_V8* runtime,
+CJS_Result CJX_Source::isBOF(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -92,7 +92,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Source::isEOF(CFX_V8* runtime,
+CJS_Result CJX_Source::isEOF(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -100,7 +100,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Source::cancel(CFX_V8* runtime,
+CJS_Result CJX_Source::cancel(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -108,7 +108,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Source::update(CFX_V8* runtime,
+CJS_Result CJX_Source::update(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -116,7 +116,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Source::open(CFX_V8* runtime,
+CJS_Result CJX_Source::open(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -125,7 +125,7 @@
}
CJS_Result CJX_Source::deleteItem(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -133,7 +133,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Source::addNew(CFX_V8* runtime,
+CJS_Result CJX_Source::addNew(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -142,7 +142,7 @@
}
CJS_Result CJX_Source::requery(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -150,7 +150,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Source::resync(CFX_V8* runtime,
+CJS_Result CJX_Source::resync(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -158,7 +158,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Source::close(CFX_V8* runtime,
+CJS_Result CJX_Source::close(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -166,7 +166,7 @@
return CJS_Result::Success();
}
-CJS_Result CJX_Source::last(CFX_V8* runtime,
+CJS_Result CJX_Source::last(CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -175,7 +175,7 @@
}
CJS_Result CJX_Source::hasDataChanged(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -183,6 +183,7 @@
return CJS_Result::Success();
}
-void CJX_Source::db(CFXJSE_Value* pValue,
+void CJX_Source::db(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_source.h b/fxjs/xfa/cjx_source.h
index cd70601..a3e7fda 100644
--- a/fxjs/xfa/cjx_source.h
+++ b/fxjs/xfa/cjx_source.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Source final : public CJX_Node {
public:
- explicit CJX_Source(CXFA_Source* src);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Source() override;
// CJX_Object:
@@ -41,6 +41,8 @@
JSE_PROP(db);
private:
+ explicit CJX_Source(CXFA_Source* src);
+
using Type__ = CJX_Source;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_subform.cpp b/fxjs/xfa/cjx_subform.cpp
index 8a72b5b..5a4efc0 100644
--- a/fxjs/xfa/cjx_subform.cpp
+++ b/fxjs/xfa/cjx_subform.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,9 +9,10 @@
#include <vector>
#include "fxjs/cfx_v8.h"
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-object.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/fxfa.h"
@@ -28,14 +29,14 @@
DefineMethods(MethodSpecs);
}
-CJX_Subform::~CJX_Subform() {}
+CJX_Subform::~CJX_Subform() = default;
bool CJX_Subform::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_Subform::execEvent(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -46,7 +47,7 @@
}
CJS_Result CJX_Subform::execInitialize(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -59,7 +60,7 @@
}
CJS_Result CJX_Subform::execCalculate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -72,7 +73,7 @@
}
CJS_Result CJX_Subform::execValidate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -87,29 +88,34 @@
runtime->NewBoolean(iRet != XFA_EventError::kError));
}
-void CJX_Subform::locale(CFXJSE_Value* pValue,
+void CJX_Subform::locale(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- SetCData(XFA_Attribute::Locale, pValue->ToWideString(), true, true);
+ SetCDataImpl(XFA_Attribute::Locale,
+ fxv8::ReentrantToWideStringHelper(pIsolate, *pValue), true,
+ true);
return;
}
WideString wsLocaleName = GetXFANode()->GetLocaleName().value_or(L"");
- pValue->SetString(wsLocaleName.ToUTF8().AsStringView());
+ *pValue =
+ fxv8::NewStringHelper(pIsolate, wsLocaleName.ToUTF8().AsStringView());
}
-void CJX_Subform::instanceManager(CFXJSE_Value* pValue,
+void CJX_Subform::instanceManager(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
WideString wsName = GetCData(XFA_Attribute::Name);
CXFA_Node* pInstanceMgr = nullptr;
- for (CXFA_Node* pNode = ToNode(GetXFAObject())->GetPrevSibling(); pNode;
+ for (CXFA_Node* pNode = GetXFANode()->GetPrevSibling(); pNode;
pNode = pNode->GetPrevSibling()) {
if (pNode->GetElementType() == XFA_Element::InstanceManager) {
WideString wsInstMgrName =
@@ -121,11 +127,9 @@
break;
}
}
- if (!pInstanceMgr) {
- pValue->SetNull();
- return;
- }
-
- pValue->Assign(GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
- pInstanceMgr));
+ *pValue = pInstanceMgr ? GetDocument()
+ ->GetScriptContext()
+ ->GetOrCreateJSBindingFromMap(pInstanceMgr)
+ .As<v8::Value>()
+ : fxv8::NewNullHelper(pIsolate).As<v8::Value>();
}
diff --git a/fxjs/xfa/cjx_subform.h b/fxjs/xfa/cjx_subform.h
index 83ac66e..c33712f 100644
--- a/fxjs/xfa/cjx_subform.h
+++ b/fxjs/xfa/cjx_subform.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,11 +10,11 @@
#include "fxjs/xfa/cjx_container.h"
#include "fxjs/xfa/jse_define.h"
-class CXFA_Delta;
+class CXFA_Node;
class CJX_Subform final : public CJX_Container {
public:
- explicit CJX_Subform(CXFA_Node* container);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Subform() override;
// CJX_Object:
@@ -29,6 +29,8 @@
JSE_PROP(locale);
private:
+ explicit CJX_Subform(CXFA_Node* container);
+
using Type__ = CJX_Subform;
using ParentType__ = CJX_Container;
diff --git a/fxjs/xfa/cjx_template.cpp b/fxjs/xfa/cjx_template.cpp
index b3d9d90..e3779e3 100644
--- a/fxjs/xfa/cjx_template.cpp
+++ b/fxjs/xfa/cjx_template.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include "fxjs/cfx_v8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_template.h"
@@ -26,14 +27,14 @@
DefineMethods(MethodSpecs);
}
-CJX_Template::~CJX_Template() {}
+CJX_Template::~CJX_Template() = default;
bool CJX_Template::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_Template::formNodes(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -42,17 +43,17 @@
}
CJS_Result CJX_Template::remerge(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
- GetDocument()->DoDataRemerge(true);
+ GetDocument()->DoDataRemerge();
return CJS_Result::Success();
}
CJS_Result CJX_Template::execInitialize(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -62,7 +63,7 @@
}
CJS_Result CJX_Template::recalculate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -71,7 +72,7 @@
}
CJS_Result CJX_Template::execCalculate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
@@ -81,7 +82,7 @@
}
CJS_Result CJX_Template::execValidate(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty())
return CJS_Result::Failure(JSMessage::kParamError);
diff --git a/fxjs/xfa/cjx_template.h b/fxjs/xfa/cjx_template.h
index d396459..caf1b74 100644
--- a/fxjs/xfa/cjx_template.h
+++ b/fxjs/xfa/cjx_template.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Template final : public CJX_Model {
public:
- explicit CJX_Template(CXFA_Template* tmpl);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Template() override;
// CJX_Object:
@@ -31,6 +31,8 @@
JSE_METHOD(remerge);
private:
+ explicit CJX_Template(CXFA_Template* tmpl);
+
using Type__ = CJX_Template;
using ParentType__ = CJX_Model;
diff --git a/fxjs/xfa/cjx_textnode.cpp b/fxjs/xfa/cjx_textnode.cpp
index 756a71d..2bdb414 100644
--- a/fxjs/xfa/cjx_textnode.cpp
+++ b/fxjs/xfa/cjx_textnode.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,20 +11,22 @@
CJX_TextNode::CJX_TextNode(CXFA_Node* node) : CJX_Node(node) {}
-CJX_TextNode::~CJX_TextNode() {}
+CJX_TextNode::~CJX_TextNode() = default;
bool CJX_TextNode::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_TextNode::defaultValue(CFXJSE_Value* pValue,
+void CJX_TextNode::defaultValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute attr) {
- ScriptSomDefaultValue(pValue, bSetting, attr);
+ ScriptSomDefaultValue(pIsolate, pValue, bSetting, attr);
}
-void CJX_TextNode::value(CFXJSE_Value* pValue,
+void CJX_TextNode::value(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute attr) {
- ScriptSomDefaultValue(pValue, bSetting, attr);
+ ScriptSomDefaultValue(pIsolate, pValue, bSetting, attr);
}
diff --git a/fxjs/xfa/cjx_textnode.h b/fxjs/xfa/cjx_textnode.h
index 6d74658..dbef713 100644
--- a/fxjs/xfa/cjx_textnode.h
+++ b/fxjs/xfa/cjx_textnode.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_TextNode : public CJX_Node {
public:
- explicit CJX_TextNode(CXFA_Node* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_TextNode() override;
// CJX_Object:
@@ -23,6 +23,9 @@
JSE_PROP(defaultValue); /* {default} */
JSE_PROP(value);
+ protected:
+ explicit CJX_TextNode(CXFA_Node* node);
+
private:
using Type__ = CJX_TextNode;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp
index cc13b7a..ec562ce 100644
--- a/fxjs/xfa/cjx_tree.cpp
+++ b/fxjs/xfa/cjx_tree.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,16 +8,19 @@
#include <vector>
+#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
+#include "fxjs/xfa/cfxjse_class.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
-#include "third_party/base/ptr_util.h"
+#include "third_party/base/numerics/safe_conversions.h"
+#include "v8/include/cppgc/allocation.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/parser/cxfa_arraynodelist.h"
#include "xfa/fxfa/parser/cxfa_attachnodelist.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_object.h"
-#include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
const CJX_MethodSpec CJX_Tree::MethodSpecs[] = {
{"resolveNode", resolveNode_static},
@@ -27,58 +30,56 @@
DefineMethods(MethodSpecs);
}
-CJX_Tree::~CJX_Tree() {}
+CJX_Tree::~CJX_Tree() = default;
bool CJX_Tree::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_Tree::resolveNode(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
- WideString expression = runtime->ToWideString(params[0]);
+ WideString wsExpression = runtime->ToWideString(params[0]);
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
- CXFA_Object* refNode = GetXFAObject();
- if (refNode->GetElementType() == XFA_Element::Xfa)
- refNode = pScriptContext->GetThisObject();
+ CXFA_Object* pRefNode = GetXFAObject();
+ if (pRefNode->GetElementType() == XFA_Element::Xfa)
+ pRefNode = pScriptContext->GetThisObject();
- uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
- XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
- XFA_RESOLVENODE_Siblings;
- XFA_RESOLVENODE_RS resolveNodeRS;
- if (!pScriptContext->ResolveObjects(ToNode(refNode),
- expression.AsStringView(), &resolveNodeRS,
- dwFlag, nullptr)) {
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+ pScriptContext->ResolveObjects(
+ ToNode(pRefNode), wsExpression.AsStringView(),
+ Mask<XFA_ResolveFlag>{
+ XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes,
+ XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent,
+ XFA_ResolveFlag::kSiblings});
+ if (!maybeResult.has_value())
return CJS_Result::Success(runtime->NewNull());
- }
- if (resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) {
- CXFA_Object* pObject = resolveNodeRS.objects.front().Get();
- CFXJSE_Value* value =
- GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pObject);
-
+ if (maybeResult.value().type == CFXJSE_Engine::ResolveResult::Type::kNodes) {
return CJS_Result::Success(
- value->DirectGetValue().Get(runtime->GetIsolate()));
+ GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+ maybeResult.value().objects.front().Get()));
}
- if (!resolveNodeRS.script_attribute.callback ||
- resolveNodeRS.script_attribute.eValueType != XFA_ScriptType::Object) {
+ if (!maybeResult.value().script_attribute.callback ||
+ maybeResult.value().script_attribute.eValueType !=
+ XFA_ScriptType::Object) {
return CJS_Result::Success(runtime->NewNull());
}
- auto pValue = pdfium::MakeUnique<CFXJSE_Value>(pScriptContext->GetIsolate());
- CJX_Object* jsObject = resolveNodeRS.objects.front()->JSObject();
- (*resolveNodeRS.script_attribute.callback)(
- jsObject, pValue.get(), false, resolveNodeRS.script_attribute.attribute);
- return CJS_Result::Success(
- pValue->DirectGetValue().Get(runtime->GetIsolate()));
+ v8::Local<v8::Value> pValue;
+ CJX_Object* jsObject = maybeResult.value().objects.front()->JSObject();
+ (*maybeResult.value().script_attribute.callback)(
+ runtime->GetIsolate(), jsObject, &pValue, false,
+ maybeResult.value().script_attribute.attribute);
+ return CJS_Result::Success(pValue);
}
CJS_Result CJX_Tree::resolveNodes(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -88,146 +89,166 @@
refNode = GetDocument()->GetScriptContext()->GetThisObject();
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
- auto pValue = pdfium::MakeUnique<CFXJSE_Value>(pScriptContext->GetIsolate());
- ResolveNodeList(pValue.get(), runtime->ToWideString(params[0]),
- XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
- XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
- XFA_RESOLVENODE_Siblings,
- ToNode(refNode));
- return CJS_Result::Success(
- pValue->DirectGetValue().Get(runtime->GetIsolate()));
+ const Mask<XFA_ResolveFlag> kFlags = {
+ XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes,
+ XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent,
+ XFA_ResolveFlag::kSiblings};
+ return CJS_Result::Success(ResolveNodeList(pScriptContext->GetIsolate(),
+ runtime->ToWideString(params[0]),
+ kFlags, ToNode(refNode)));
}
-void CJX_Tree::all(CFXJSE_Value* pValue,
+void CJX_Tree::all(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
-
- uint32_t dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
- WideString wsExpression = GetAttribute(XFA_Attribute::Name) + L"[*]";
- ResolveNodeList(pValue, wsExpression, dwFlag, nullptr);
+ const Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kSiblings,
+ XFA_ResolveFlag::kALL};
+ WideString wsExpression = GetAttributeByEnum(XFA_Attribute::Name) + L"[*]";
+ *pValue = ResolveNodeList(pIsolate, wsExpression, kFlags, nullptr);
}
-void CJX_Tree::classAll(CFXJSE_Value* pValue,
+void CJX_Tree::classAll(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
-
+ const Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kSiblings,
+ XFA_ResolveFlag::kALL};
WideString wsExpression =
L"#" + WideString::FromASCII(GetXFAObject()->GetClassName()) + L"[*]";
- ResolveNodeList(pValue, wsExpression,
- XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL, nullptr);
+ *pValue = ResolveNodeList(pIsolate, wsExpression, kFlags, nullptr);
}
-void CJX_Tree::nodes(CFXJSE_Value* pValue,
+void CJX_Tree::nodes(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
WideString wsMessage = L"Unable to set ";
- FXJSE_ThrowMessage(wsMessage.ToUTF8().AsStringView());
+ FXJSE_ThrowMessage(pIsolate, wsMessage.ToUTF8().AsStringView());
return;
}
- CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
- CXFA_AttachNodeList* pNodeList =
- new CXFA_AttachNodeList(GetDocument(), ToNode(GetXFAObject()));
- pValue->SetHostObject(pNodeList, pScriptContext->GetJseNormalClass());
+ CXFA_Document* pDoc = GetDocument();
+ auto* pNodeList = cppgc::MakeGarbageCollected<CXFA_AttachNodeList>(
+ pDoc->GetHeap()->GetAllocationHandle(), pDoc, GetXFANode());
+ pDoc->GetNodeOwner()->PersistList(pNodeList);
+
+ CFXJSE_Engine* pEngine = pDoc->GetScriptContext();
+ *pValue = pNodeList->JSObject()->NewBoundV8Object(
+ pIsolate, pEngine->GetJseNormalClass()->GetTemplate(pIsolate));
}
-void CJX_Tree::parent(CFXJSE_Value* pValue,
+void CJX_Tree::parent(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- CXFA_Node* pParent = ToNode(GetXFAObject())->GetParent();
- if (!pParent) {
- pValue->SetNull();
- return;
- }
-
- pValue->Assign(
- GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pParent));
+ CXFA_Node* pParent = GetXFANode()->GetParent();
+ *pValue = pParent ? GetDocument()
+ ->GetScriptContext()
+ ->GetOrCreateJSBindingFromMap(pParent)
+ .As<v8::Value>()
+ : fxv8::NewNullHelper(pIsolate).As<v8::Value>();
}
-void CJX_Tree::index(CFXJSE_Value* pValue,
+void CJX_Tree::index(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- CXFA_Node* pNode = ToNode(GetXFAObject());
+ CXFA_Node* pNode = GetXFANode();
size_t iIndex = pNode ? pNode->GetIndexByName() : 0;
- pValue->SetInteger(pdfium::base::checked_cast<int32_t>(iIndex));
+ *pValue = fxv8::NewNumberHelper(pIsolate,
+ pdfium::base::checked_cast<int32_t>(iIndex));
}
-void CJX_Tree::classIndex(CFXJSE_Value* pValue,
+void CJX_Tree::classIndex(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- CXFA_Node* pNode = ToNode(GetXFAObject());
+ CXFA_Node* pNode = GetXFANode();
size_t iIndex = pNode ? pNode->GetIndexByClassName() : 0;
- pValue->SetInteger(pdfium::base::checked_cast<int32_t>(iIndex));
+ *pValue = fxv8::NewNumberHelper(pIsolate,
+ pdfium::base::checked_cast<int32_t>(iIndex));
}
-void CJX_Tree::somExpression(CFXJSE_Value* pValue,
+void CJX_Tree::somExpression(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting) {
- ThrowInvalidPropertyException();
+ ThrowInvalidPropertyException(pIsolate);
return;
}
- WideString wsSOMExpression = GetXFAObject()->GetSOMExpression();
- pValue->SetString(wsSOMExpression.ToUTF8().AsStringView());
+ ByteString bsSOMExpression = GetXFAObject()->GetSOMExpression().ToUTF8();
+ *pValue = fxv8::NewStringHelper(pIsolate, bsSOMExpression.AsStringView());
}
-void CJX_Tree::ResolveNodeList(CFXJSE_Value* pValue,
- WideString wsExpression,
- uint32_t dwFlag,
- CXFA_Node* refNode) {
+v8::Local<v8::Value> CJX_Tree::ResolveNodeList(v8::Isolate* pIsolate,
+ WideString wsExpression,
+ Mask<XFA_ResolveFlag> dwFlag,
+ CXFA_Node* refNode) {
if (!refNode)
- refNode = ToNode(GetXFAObject());
+ refNode = GetXFANode();
- XFA_RESOLVENODE_RS resolveNodeRS;
- CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
- pScriptContext->ResolveObjects(refNode, wsExpression.AsStringView(),
- &resolveNodeRS, dwFlag, nullptr);
- CXFA_ArrayNodeList* pNodeList = new CXFA_ArrayNodeList(GetDocument());
- if (resolveNodeRS.dwFlags == XFA_ResolveNode_RSType_Nodes) {
- for (auto& pObject : resolveNodeRS.objects) {
- if (pObject->IsNode())
- pNodeList->Append(pObject->AsNode());
- }
- } else {
- if (resolveNodeRS.script_attribute.callback &&
- resolveNodeRS.script_attribute.eValueType == XFA_ScriptType::Object) {
- for (auto& pObject : resolveNodeRS.objects) {
- auto innerValue =
- pdfium::MakeUnique<CFXJSE_Value>(pScriptContext->GetIsolate());
- CJX_Object* jsObject = pObject->JSObject();
- (*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());
+ CXFA_Document* pDoc = GetDocument();
+ auto* pNodeList = cppgc::MakeGarbageCollected<CXFA_ArrayNodeList>(
+ pDoc->GetHeap()->GetAllocationHandle(), pDoc);
+ pDoc->GetNodeOwner()->PersistList(pNodeList);
+
+ CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
+ absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+ pScriptContext->ResolveObjects(refNode, wsExpression.AsStringView(),
+ dwFlag);
+
+ if (maybeResult.has_value()) {
+ if (maybeResult.value().type ==
+ CFXJSE_Engine::ResolveResult::Type::kNodes) {
+ for (auto& pObject : maybeResult.value().objects) {
+ if (pObject->IsNode())
+ pNodeList->Append(pObject->AsNode());
+ }
+ } else {
+ if (maybeResult.value().script_attribute.callback &&
+ maybeResult.value().script_attribute.eValueType ==
+ XFA_ScriptType::Object) {
+ for (auto& pObject : maybeResult.value().objects) {
+ v8::Local<v8::Value> innerValue;
+ CJX_Object* jsObject = pObject->JSObject();
+ (*maybeResult.value().script_attribute.callback)(
+ pIsolate, jsObject, &innerValue, false,
+ maybeResult.value().script_attribute.attribute);
+ CXFA_Object* obj =
+ CFXJSE_Engine::ToObject(pScriptContext->GetIsolate(), innerValue);
+ if (obj->IsNode())
+ pNodeList->Append(obj->AsNode());
+ }
}
}
}
- pValue->SetHostObject(pNodeList, pScriptContext->GetJseNormalClass());
+ return pNodeList->JSObject()->NewBoundV8Object(
+ pIsolate, pScriptContext->GetJseNormalClass()->GetTemplate(pIsolate));
}
diff --git a/fxjs/xfa/cjx_tree.h b/fxjs/xfa/cjx_tree.h
index cbef888..42c522e 100644
--- a/fxjs/xfa/cjx_tree.h
+++ b/fxjs/xfa/cjx_tree.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,6 +7,7 @@
#ifndef FXJS_XFA_CJX_TREE_H_
#define FXJS_XFA_CJX_TREE_H_
+#include "fxjs/xfa/cfxjse_engine.h"
#include "fxjs/xfa/cjx_object.h"
#include "fxjs/xfa/jse_define.h"
@@ -15,7 +16,7 @@
class CJX_Tree : public CJX_Object {
public:
- explicit CJX_Tree(CXFA_Object* obj);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Tree() override;
// CJX_Object:
@@ -32,6 +33,9 @@
JSE_PROP(parent);
JSE_PROP(somExpression);
+ protected:
+ explicit CJX_Tree(CXFA_Object* obj);
+
private:
using Type__ = CJX_Tree;
using ParentType__ = CJX_Object;
@@ -39,10 +43,10 @@
static const TypeTag static_type__ = TypeTag::Tree;
static const CJX_MethodSpec MethodSpecs[];
- void ResolveNodeList(CFXJSE_Value* pValue,
- WideString wsExpression,
- uint32_t dwFlag,
- CXFA_Node* refNode);
+ v8::Local<v8::Value> ResolveNodeList(v8::Isolate* pIsolate,
+ WideString wsExpression,
+ Mask<XFA_ResolveFlag> dwFlag,
+ CXFA_Node* refNode);
};
#endif // FXJS_XFA_CJX_TREE_H_
diff --git a/fxjs/xfa/cjx_treelist.cpp b/fxjs/xfa/cjx_treelist.cpp
index 51bbb0a..e2e4a21 100644
--- a/fxjs/xfa/cjx_treelist.cpp
+++ b/fxjs/xfa/cjx_treelist.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_engine.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-object.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_treelist.h"
@@ -22,7 +23,7 @@
DefineMethods(MethodSpecs);
}
-CJX_TreeList::~CJX_TreeList() {}
+CJX_TreeList::~CJX_TreeList() = default;
bool CJX_TreeList::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
@@ -33,7 +34,7 @@
}
CJS_Result CJX_TreeList::namedItem(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
@@ -43,9 +44,6 @@
if (!pNode)
return CJS_Result::Success();
- CFXJSE_Value* value =
- GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode);
-
return CJS_Result::Success(
- value->DirectGetValue().Get(runtime->GetIsolate()));
+ GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode));
}
diff --git a/fxjs/xfa/cjx_treelist.h b/fxjs/xfa/cjx_treelist.h
index 294ab26..a5dbaaa 100644
--- a/fxjs/xfa/cjx_treelist.h
+++ b/fxjs/xfa/cjx_treelist.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_TreeList final : public CJX_List {
public:
- explicit CJX_TreeList(CXFA_TreeList* list);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_TreeList() override;
// CJX_Object:
@@ -23,6 +23,8 @@
JSE_METHOD(namedItem);
private:
+ explicit CJX_TreeList(CXFA_TreeList* list);
+
using Type__ = CJX_TreeList;
using ParentType__ = CJX_List;
diff --git a/fxjs/xfa/cjx_wsdlconnection.cpp b/fxjs/xfa/cjx_wsdlconnection.cpp
index 7821232..1f7f45e 100644
--- a/fxjs/xfa/cjx_wsdlconnection.cpp
+++ b/fxjs/xfa/cjx_wsdlconnection.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include "fxjs/cfx_v8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-primitive.h"
#include "xfa/fxfa/parser/cxfa_wsdlconnection.h"
const CJX_MethodSpec CJX_WsdlConnection::MethodSpecs[] = {
@@ -21,14 +22,14 @@
DefineMethods(MethodSpecs);
}
-CJX_WsdlConnection::~CJX_WsdlConnection() {}
+CJX_WsdlConnection::~CJX_WsdlConnection() = default;
bool CJX_WsdlConnection::DynamicTypeIs(TypeTag eType) const {
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
CJS_Result CJX_WsdlConnection::execute(
- CFX_V8* runtime,
+ CFXJSE_Engine* runtime,
const std::vector<v8::Local<v8::Value>>& params) {
if (!params.empty() && params.size() != 1)
return CJS_Result::Failure(JSMessage::kParamError);
diff --git a/fxjs/xfa/cjx_wsdlconnection.h b/fxjs/xfa/cjx_wsdlconnection.h
index bd5db40..8706695 100644
--- a/fxjs/xfa/cjx_wsdlconnection.h
+++ b/fxjs/xfa/cjx_wsdlconnection.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_WsdlConnection final : public CJX_Node {
public:
- explicit CJX_WsdlConnection(CXFA_WsdlConnection* connection);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_WsdlConnection() override;
// CJX_Object:
@@ -23,6 +23,8 @@
JSE_METHOD(execute);
private:
+ explicit CJX_WsdlConnection(CXFA_WsdlConnection* connection);
+
using Type__ = CJX_WsdlConnection;
using ParentType__ = CJX_Node;
diff --git a/fxjs/xfa/cjx_xfa.cpp b/fxjs/xfa/cjx_xfa.cpp
index 08c6a80..5248693 100644
--- a/fxjs/xfa/cjx_xfa.cpp
+++ b/fxjs/xfa/cjx_xfa.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,8 +6,9 @@
#include "fxjs/xfa/cjx_xfa.h"
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
+#include "v8/include/v8-object.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_xfa.h"
@@ -19,7 +20,8 @@
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}
-void CJX_Xfa::thisValue(CFXJSE_Value* pValue,
+void CJX_Xfa::thisValue(v8::Isolate* pIsolate,
+ v8::Local<v8::Value>* pValue,
bool bSetting,
XFA_Attribute eAttribute) {
if (bSetting)
@@ -27,9 +29,7 @@
auto* pScriptContext = GetDocument()->GetScriptContext();
CXFA_Object* pThis = pScriptContext->GetThisObject();
- if (!pThis) {
- pValue->SetNull();
- return;
- }
- pValue->Assign(pScriptContext->GetOrCreateJSBindingFromMap(pThis));
+ *pValue =
+ pThis ? pScriptContext->GetOrCreateJSBindingFromMap(pThis).As<v8::Value>()
+ : fxv8::NewNullHelper(pIsolate);
}
diff --git a/fxjs/xfa/cjx_xfa.h b/fxjs/xfa/cjx_xfa.h
index 63b0f5f..031425d 100644
--- a/fxjs/xfa/cjx_xfa.h
+++ b/fxjs/xfa/cjx_xfa.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@
class CJX_Xfa final : public CJX_Model {
public:
- explicit CJX_Xfa(CXFA_Xfa* node);
+ CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
~CJX_Xfa() override;
// CJX_Object:
@@ -23,6 +23,8 @@
JSE_PROP(thisValue); /* this */
private:
+ explicit CJX_Xfa(CXFA_Xfa* node);
+
using Type__ = CJX_Xfa;
using ParentType__ = CJX_Model;
diff --git a/fxjs/xfa/fxjse.cpp b/fxjs/xfa/fxjse.cpp
index ff6176b..d03ca7e 100644
--- a/fxjs/xfa/fxjse.cpp
+++ b/fxjs/xfa/fxjse.cpp
@@ -1,4 +1,4 @@
-// Copyright 2018 PDFium Authors. All rights reserved.
+// Copyright 2018 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,12 @@
#include "fxjs/xfa/fxjse.h"
+#include "fxjs/fxv8.h"
+#include "fxjs/xfa/cfxjse_context.h"
+#include "v8/include/v8-isolate.h"
+#include "v8/include/v8-object.h"
+#include "v8/include/v8-template.h"
+
namespace pdfium {
namespace fxjse {
@@ -15,6 +21,14 @@
} // namespace fxjse
} // namespace pdfium
+// static
+CFXJSE_HostObject* CFXJSE_HostObject::FromV8(v8::Local<v8::Value> arg) {
+ if (!fxv8::IsObject(arg))
+ return nullptr;
+
+ return FXJSE_RetrieveObjectBinding(arg.As<v8::Object>());
+}
+
CFXJSE_HostObject::CFXJSE_HostObject() = default;
CFXJSE_HostObject::~CFXJSE_HostObject() = default;
@@ -23,6 +37,17 @@
return nullptr;
}
-CXFA_Object* CFXJSE_HostObject::AsCXFAObject() {
+CJX_Object* CFXJSE_HostObject::AsCJXObject() {
return nullptr;
}
+
+v8::Local<v8::Object> CFXJSE_HostObject::NewBoundV8Object(
+ v8::Isolate* pIsolate,
+ v8::Local<v8::FunctionTemplate> tmpl) {
+ v8::Local<v8::Object> hObject =
+ tmpl->InstanceTemplate()
+ ->NewInstance(pIsolate->GetCurrentContext())
+ .ToLocalChecked();
+ FXJSE_UpdateObjectBinding(hObject, this);
+ return hObject;
+}
diff --git a/fxjs/xfa/fxjse.h b/fxjs/xfa/fxjse.h
index 5aa6b39..b020ce6 100644
--- a/fxjs/xfa/fxjse.h
+++ b/fxjs/xfa/fxjse.h
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,79 +7,90 @@
#ifndef FXJS_XFA_FXJSE_H_
#define FXJS_XFA_FXJSE_H_
+#include <stdint.h>
+
#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-#include "v8/include/v8.h"
+#include "v8/include/v8-forward.h"
namespace pdfium {
namespace fxjse {
+// These are strings by design. With ASLR, their addresses should be random, so
+// it should be very unlikely for an object to accidentally have the same tag.
extern const char kFuncTag[];
extern const char kClassTag[];
} // namespace fxjse
} // namespace pdfium
-class CFXJSE_Arguments;
class CFXJSE_FormCalcContext;
-class CFXJSE_Value;
class CJS_Result;
-class CXFA_Object;
+class CJX_Object;
+
+enum class FXJSE_ClassPropType {
+ kNone,
+ kProperty,
+ kMethod,
+};
// C++ object which is retrieved from v8 object's slot.
class CFXJSE_HostObject {
public:
+ static CFXJSE_HostObject* FromV8(v8::Local<v8::Value> arg);
virtual ~CFXJSE_HostObject();
// Two subclasses.
virtual CFXJSE_FormCalcContext* AsFormCalcContext();
- virtual CXFA_Object* AsCXFAObject();
+ virtual CJX_Object* AsCJXObject();
+
+ v8::Local<v8::Object> NewBoundV8Object(v8::Isolate* pIsolate,
+ v8::Local<v8::FunctionTemplate> tmpl);
protected:
CFXJSE_HostObject();
};
-typedef CJS_Result (*FXJSE_MethodCallback)(
- const v8::FunctionCallbackInfo<v8::Value>& info,
- const WideString& functionName);
-typedef void (*FXJSE_FuncCallback)(CFXJSE_Value* pThis,
- ByteStringView szFuncName,
- CFXJSE_Arguments& args);
-typedef void (*FXJSE_PropAccessor)(CFXJSE_Value* pObject,
- ByteStringView szPropName,
- CFXJSE_Value* pValue);
-typedef int32_t (*FXJSE_PropTypeGetter)(CFXJSE_Value* pObject,
- ByteStringView szPropName,
- bool bQueryIn);
-
-enum FXJSE_ClassPropTypes {
- FXJSE_ClassPropType_None,
- FXJSE_ClassPropType_Property,
- FXJSE_ClassPropType_Method
-};
+using FXJSE_MethodCallback =
+ CJS_Result (*)(const v8::FunctionCallbackInfo<v8::Value>& info,
+ const WideString& functionName);
+using FXJSE_FuncCallback =
+ void (*)(CFXJSE_HostObject* pThis,
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+using FXJSE_PropGetter = v8::Local<v8::Value> (*)(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
+ ByteStringView szPropName);
+using FXJSE_PropSetter = void (*)(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
+ ByteStringView szPropName,
+ v8::Local<v8::Value> pValue);
+using FXJSE_PropTypeGetter =
+ FXJSE_ClassPropType (*)(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObject,
+ ByteStringView szPropName,
+ bool bQueryIn);
struct FXJSE_FUNCTION_DESCRIPTOR {
- const char* tag; // pdfium::kFuncTag always.
+ const char* tag; // `pdfium::fxjse::kFuncTag` always.
const char* name;
FXJSE_FuncCallback callbackProc;
};
struct FXJSE_CLASS_DESCRIPTOR {
- const char* tag; // pdfium::kClassTag always.
+ const char* tag; // `pdfium::fxjse::kClassTag` always.
const char* name;
const FXJSE_FUNCTION_DESCRIPTOR* methods;
int32_t methNum;
FXJSE_PropTypeGetter dynPropTypeGetter;
- FXJSE_PropAccessor dynPropGetter;
- FXJSE_PropAccessor dynPropSetter;
+ FXJSE_PropGetter dynPropGetter;
+ FXJSE_PropSetter dynPropSetter;
FXJSE_MethodCallback dynMethodCall;
};
-extern const FXJSE_CLASS_DESCRIPTOR GlobalClassDescriptor;
-extern const FXJSE_CLASS_DESCRIPTOR NormalClassDescriptor;
-extern const FXJSE_CLASS_DESCRIPTOR VariablesClassDescriptor;
-extern const FXJSE_CLASS_DESCRIPTOR kFormCalcFM2JSDescriptor;
+extern const FXJSE_CLASS_DESCRIPTOR kGlobalClassDescriptor;
+extern const FXJSE_CLASS_DESCRIPTOR kNormalClassDescriptor;
+extern const FXJSE_CLASS_DESCRIPTOR kVariablesClassDescriptor;
+extern const FXJSE_CLASS_DESCRIPTOR kFormCalcDescriptor;
-void FXJSE_ThrowMessage(ByteStringView utf8Message);
+void FXJSE_ThrowMessage(v8::Isolate* pIsolate, ByteStringView utf8Message);
#endif // FXJS_XFA_FXJSE_H_
diff --git a/fxjs/xfa/jse_define.h b/fxjs/xfa/jse_define.h
index 26405c9..0800601 100644
--- a/fxjs/xfa/jse_define.h
+++ b/fxjs/xfa/jse_define.h
@@ -1,4 +1,4 @@
-// Copyright 2017 PDFium Authors. All rights reserved.
+// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,25 +11,28 @@
#include "fxjs/cjs_result.h"
-class CFX_V8;
+class CFXJSE_Engine;
#define JSE_METHOD(method_name) \
static CJS_Result method_name##_static( \
- CJX_Object* node, CFX_V8* runtime, \
+ CJX_Object* node, CFXJSE_Engine* runtime, \
const std::vector<v8::Local<v8::Value>>& params) { \
if (!node->DynamicTypeIs(static_type__)) \
return CJS_Result::Failure(JSMessage::kBadObjectError); \
return static_cast<Type__*>(node)->method_name(runtime, params); \
} \
- CJS_Result method_name(CFX_V8* runtime, \
+ CJS_Result method_name(CFXJSE_Engine* runtime, \
const std::vector<v8::Local<v8::Value>>& params)
-#define JSE_PROP(prop_name) \
- static void prop_name##_static(CJX_Object* node, CFXJSE_Value* value, \
- bool setting, XFA_Attribute attribute) { \
- if (node->DynamicTypeIs(static_type__)) \
- static_cast<Type__*>(node)->prop_name(value, setting, attribute); \
- } \
- void prop_name(CFXJSE_Value* pValue, bool bSetting, XFA_Attribute eAttribute)
+#define JSE_PROP(prop_name) \
+ static void prop_name##_static(v8::Isolate* pIsolate, CJX_Object* node, \
+ v8::Local<v8::Value>* value, bool setting, \
+ XFA_Attribute attribute) { \
+ if (node->DynamicTypeIs(static_type__)) \
+ static_cast<Type__*>(node)->prop_name(pIsolate, value, setting, \
+ attribute); \
+ } \
+ void prop_name(v8::Isolate* pIsolate, v8::Local<v8::Value>* pValue, \
+ bool bSetting, XFA_Attribute eAttribute)
#endif // FXJS_XFA_JSE_DEFINE_H_