Make CJS_Global V8 callbacks conform to V8 API.
Several of these were not in strict conformance with the API
in v8/include/v8-template.h (see bug for specifics).
-- sort expected results file as these are now coming out in
C++ map order, not JS object order.
Bug: pdfium:1835, v8:12806
Change-Id: I9f38674520361b90df0f3a80b2cfc87730d7ebad
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/93670
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/cfxjs_engine.cpp b/fxjs/cfxjs_engine.cpp
index 6335c2a..ce15bf8 100644
--- a/fxjs/cfxjs_engine.cpp
+++ b/fxjs/cfxjs_engine.cpp
@@ -205,12 +205,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));
}
@@ -429,12 +431,14 @@
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(uint32_t nObjDefnID,
diff --git a/fxjs/cfxjs_engine.h b/fxjs/cfxjs_engine.h
index 304b4d3..56c9ad6 100644
--- a/fxjs/cfxjs_engine.h
+++ b/fxjs/cfxjs_engine.h
@@ -103,11 +103,13 @@
const char* sPropName,
v8::AccessorGetterCallback pPropGet,
v8::AccessorSetterCallback pPropPut);
- void DefineObjAllProperties(uint32_t nObjDefnID,
- v8::GenericNamedPropertyQueryCallback pPropQurey,
- v8::GenericNamedPropertyGetterCallback pPropGet,
- v8::GenericNamedPropertySetterCallback pPropPut,
- v8::GenericNamedPropertyDeleterCallback pPropDel);
+ 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);
diff --git a/fxjs/cjs_global.cpp b/fxjs/cjs_global.cpp
index 21814e3..216b548 100644
--- a/fxjs/cjs_global.cpp
+++ b/fxjs/cjs_global.cpp
@@ -19,6 +19,7 @@
#include "fxjs/js_define.h"
#include "fxjs/js_resources.h"
#include "third_party/base/check.h"
+#include "third_party/base/containers/contains.h"
#include "v8/include/v8-isolate.h"
namespace {
@@ -34,12 +35,8 @@
return;
WideString wsProp = fxv8::ToWideString(info.GetIsolate(), property);
- CJS_Result result = pObj->QueryProperty(wsProp);
- v8::PropertyAttribute attr = !result.HasError()
- ? v8::PropertyAttribute::DontDelete
- : v8::PropertyAttribute::None;
-
- info.GetReturnValue().Set(static_cast<int>(attr));
+ if (pObj->HasProperty(wsProp))
+ info.GetReturnValue().Set(static_cast<int>(v8::PropertyAttribute::None));
}
void JSSpecialPropGet(v8::Local<v8::String> property,
@@ -79,7 +76,9 @@
if (result.HasError()) {
pRuntime->Error(
JSFormatErrorString("global", "PutProperty", result.Error()));
+ return;
}
+ info.GetReturnValue().Set(value);
}
void JSSpecialPropDel(v8::Local<v8::String> property,
@@ -93,7 +92,20 @@
return;
WideString wsProp = fxv8::ToWideString(info.GetIsolate(), property);
- pObj->DelProperty(pRuntime, wsProp); // Silently ignore error.
+ if (pObj->DelProperty(pRuntime, wsProp))
+ info.GetReturnValue().Set(true);
+}
+
+void JSSpecialPropEnum(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);
}
v8::Local<v8::String> GetV8StringFromName(v8::Isolate* pIsolate,
@@ -153,11 +165,17 @@
JSSpecialPropDel(GetV8StringFromName(info.GetIsolate(), property), info);
}
+void CJS_Global::enumprop_static(
+ const v8::PropertyCallbackInfo<v8::Array>& info) {
+ JSSpecialPropEnum(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
@@ -184,21 +202,18 @@
m_pGlobalData.Release()->Release();
}
-CJS_Result CJS_Global::QueryProperty(const WideString& propname) {
- if (propname.EqualsASCII("setPersistent"))
- return CJS_Result::Success();
-
- return CJS_Result::Failure(JSMessage::kUnknownProperty);
+bool CJS_Global::HasProperty(const WideString& propname) {
+ return pdfium::Contains(m_MapGlobal, propname.ToDefANSI());
}
-CJS_Result CJS_Global::DelProperty(CJS_Runtime* pRuntime,
- const WideString& propname) {
+bool CJS_Global::DelProperty(CJS_Runtime* pRuntime,
+ const WideString& propname) {
auto it = m_MapGlobal.find(propname.ToDefANSI());
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,
@@ -264,6 +279,21 @@
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) {
diff --git a/fxjs/cjs_global.h b/fxjs/cjs_global.h
index 994589f..47a43ce 100644
--- a/fxjs/cjs_global.h
+++ b/fxjs/cjs_global.h
@@ -44,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);
@@ -53,12 +54,14 @@
CJS_Result setPersistent(CJS_Runtime* pRuntime,
const std::vector<v8::Local<v8::Value>>& params);
- CJS_Result QueryProperty(const WideString& propname);
- CJS_Result DelProperty(CJS_Runtime* pRuntime, const WideString& propname);
+ bool HasProperty(const WideString& propname);
+ bool DelProperty(CJS_Runtime* pRuntime, const WideString& propname);
CJS_Result GetProperty(CJS_Runtime* pRuntime, const WideString& propname);
CJS_Result SetProperty(CJS_Runtime* pRuntime,
const WideString& propname,
v8::Local<v8::Value> vp);
+ void EnumProperties(CJS_Runtime* pRuntime,
+ const v8::PropertyCallbackInfo<v8::Array>& info);
private:
struct JSGlobalData : public CFX_Value {
diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS
index 6151eaa..bac9e2d 100644
--- a/testing/SUPPRESSIONS
+++ b/testing/SUPPRESSIONS
@@ -314,9 +314,6 @@
bug_679643.in * * noxfa *
bug_735912.in * * noxfa *
-# TODO(v8:12806) Fix regression and remove this suppression.
-globals.in * * * *
-
# JS tests in nov8 mode expect empty results. This one will
# not be empty as the callback is not js-based.
named_action.in * nov8 * *
diff --git a/testing/resources/javascript/globals_expected.txt b/testing/resources/javascript/globals_expected.txt
index fcebd70..26c878b 100644
--- a/testing/resources/javascript/globals_expected.txt
+++ b/testing/resources/javascript/globals_expected.txt
@@ -13,14 +13,13 @@
Alert: ************ After Setup ************
Alert: Enumerable Globals:
Alert: setPersistent = function setPersistent() { [native code] }, own property = true
-Alert: true_var = true, own property = true
Alert: false_var = false, own property = true
-Alert: zero_var = 0, own property = true
-Alert: number_var = -3.918, own property = true
-Alert: string_var = This is a string, own property = true
-Alert: object_var = [object Object], own property = true
Alert: null_var = null, own property = true
-Alert: undefined_var = undefined, own property = true
+Alert: number_var = -3.918, own property = true
+Alert: object_var = [object Object], own property = true
+Alert: string_var = This is a string, own property = true
+Alert: true_var = true, own property = true
+Alert: zero_var = 0, own property = true
Alert: Expected Globals:
Alert: true_var = true
Alert: false_var = false
@@ -49,14 +48,13 @@
Alert: ************ After Setup and Persist false ************
Alert: Enumerable Globals:
Alert: setPersistent = function setPersistent() { [native code] }, own property = true
-Alert: true_var = true, own property = true
Alert: false_var = false, own property = true
-Alert: zero_var = 0, own property = true
-Alert: number_var = -3.918, own property = true
-Alert: string_var = This is a string, own property = true
-Alert: object_var = [object Object], own property = true
Alert: null_var = null, own property = true
-Alert: undefined_var = undefined, own property = true
+Alert: number_var = -3.918, own property = true
+Alert: object_var = [object Object], own property = true
+Alert: string_var = This is a string, own property = true
+Alert: true_var = true, own property = true
+Alert: zero_var = 0, own property = true
Alert: Expected Globals:
Alert: true_var = true
Alert: false_var = false
@@ -93,14 +91,13 @@
Alert: ************ After Setup and Persist true ************
Alert: Enumerable Globals:
Alert: setPersistent = function setPersistent() { [native code] }, own property = true
-Alert: true_var = true, own property = true
Alert: false_var = false, own property = true
-Alert: zero_var = 0, own property = true
-Alert: number_var = -3.918, own property = true
-Alert: string_var = This is a string, own property = true
-Alert: object_var = [object Object], own property = true
Alert: null_var = null, own property = true
-Alert: undefined_var = undefined, own property = true
+Alert: number_var = -3.918, own property = true
+Alert: object_var = [object Object], own property = true
+Alert: string_var = This is a string, own property = true
+Alert: true_var = true, own property = true
+Alert: zero_var = 0, own property = true
Alert: Expected Globals:
Alert: true_var = true
Alert: false_var = false