summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2015-03-02 12:18:50 -0800
committerTom Sepez <tsepez@chromium.org>2015-03-02 12:18:50 -0800
commitb720d0a14601f1496ef15297bc46d401f5a2a890 (patch)
treed19c5604c1528646d992ffcd1beabe8279d5d4b3
parent944ccad72d028ed5e37f53c5c8c0888866905bc3 (diff)
downloadpdfium-b720d0a14601f1496ef15297bc46d401f5a2a890.tar.xz
Return error information from pdfium to JS.
This implements the previously unimplemented JS_Error() function. Along the way: - fix some IWYU when the include order in global.cpp was perturbed. - remove some uses of JS_ErrorString, to increase transparency. - use vp.IsSetting() in place of !vp.IsGetting() for clarity. - specify an error string on several error return paths. - add an error string for writing readonly properties. - rename an error string constant to reflect the actual message. - replace calls to variadic Format() with a function doing string appends. - remove unused JS_GetClassName() R=thestig@chromium.org Review URL: https://codereview.chromium.org/963193003
-rw-r--r--fpdfsdk/include/javascript/IJavaScript.h7
-rw-r--r--fpdfsdk/include/javascript/JS_Define.h58
-rw-r--r--fpdfsdk/include/javascript/JS_Object.h5
-rw-r--r--fpdfsdk/include/javascript/resource.h6
-rw-r--r--fpdfsdk/include/jsapi/fxjs_v8.h4
-rw-r--r--fpdfsdk/src/javascript/Document.cpp64
-rw-r--r--fpdfsdk/src/javascript/console.cpp2
-rw-r--r--fpdfsdk/src/javascript/global.cpp14
-rw-r--r--fpdfsdk/src/javascript/resource.cpp17
-rw-r--r--fpdfsdk/src/jsapi/fxjs_v8.cpp14
-rw-r--r--testing/resources/javascript/document_props.in30
-rw-r--r--testing/resources/javascript/document_props_expected.txt12
-rw-r--r--testing/resources/javascript/globals.in44
-rw-r--r--testing/resources/javascript/globals_expected.txt10
14 files changed, 173 insertions, 114 deletions
diff --git a/fpdfsdk/include/javascript/IJavaScript.h b/fpdfsdk/include/javascript/IJavaScript.h
index a05d4436e0..4db1bc6e27 100644
--- a/fpdfsdk/include/javascript/IJavaScript.h
+++ b/fpdfsdk/include/javascript/IJavaScript.h
@@ -7,6 +7,13 @@
#ifndef _IJAVASCRIPT_H_
#define _IJAVASCRIPT_H_
+#include "../../../core/include/fxcrt/fx_basic.h"
+
+class CPDF_Bookmark;
+class CPDF_FormField;
+class CPDFSDK_Annot;
+class CPDFSDK_Document;
+
class IFXJS_Context
{
public:
diff --git a/fpdfsdk/include/javascript/JS_Define.h b/fpdfsdk/include/javascript/JS_Define.h
index 4246e01964..6edcc97aff 100644
--- a/fpdfsdk/include/javascript/JS_Define.h
+++ b/fpdfsdk/include/javascript/JS_Define.h
@@ -7,6 +7,9 @@
#ifndef _JS_DEFINE_H_
#define _JS_DEFINE_H_
+#include "../jsapi/fxjs_v8.h"
+#include "resource.h"
+
typedef v8::Value JSValue;
typedef v8::Handle<v8::Object> JSObject;
typedef v8::Handle<v8::Object> JSFXObject;
@@ -37,11 +40,10 @@ struct JSMethodSpec
unsigned nParamNum;
};
-typedef CFX_WideString JS_ErrorString;
-
#define JS_TRUE (unsigned)1
#define JS_FALSE (unsigned)0
+typedef CFX_WideString JS_ErrorString;
typedef CFX_ArrayTemplate<float> CJS_PointsArray;
typedef CFX_ArrayTemplate<int> CJS_IntArray;
@@ -63,7 +65,7 @@ typedef CFX_ArrayTemplate<int> CJS_IntArray;
/* ======================================== PROP CALLBACK ============================================ */
-template <class C, FX_BOOL (C::*M)(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)>
+template <class C, FX_BOOL (C::*M)(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)>
void JSPropGetter(const char* prop_name_string,
const char* class_name_string,
v8::Local<v8::String> property,
@@ -76,19 +78,17 @@ void JSPropGetter(const char* prop_name_string,
IFXJS_Context* pContext = pRuntime->GetCurrentContext();
CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());
C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
- JS_ErrorString sError;
+ CFX_WideString sError;
CJS_PropValue value(isolate);
value.StartGetting();
if (!(pObj->*M)(pContext, value, sError)) {
- CFX_ByteString cbName;
- cbName.Format("%s.%s", class_name_string, prop_name_string);
- JS_Error(NULL, CFX_WideString::FromLocal(cbName), sError);
+ JS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string, sError));
return;
}
info.GetReturnValue().Set((v8::Handle<v8::Value>)value);
}
-template <class C, FX_BOOL (C::*M)(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)>
+template <class C, FX_BOOL (C::*M)(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)>
void JSPropSetter(const char* prop_name_string,
const char* class_name_string,
v8::Local<v8::String> property,
@@ -102,13 +102,11 @@ void JSPropSetter(const char* prop_name_string,
IFXJS_Context* pContext = pRuntime->GetCurrentContext();
CJS_Object* pJSObj = (CJS_Object*)JS_GetPrivate(isolate,info.Holder());
C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
- JS_ErrorString sError;
+ CFX_WideString sError;
CJS_PropValue propValue(CJS_Value(isolate, value, VT_unknown));
propValue.StartSetting();
if (!(pObj->*M)(pContext, propValue, sError)) {
- CFX_ByteString cbName;
- cbName.Format("%s.%s", class_name_string, prop_name_string);
- JS_Error(NULL, CFX_WideString::FromLocal(cbName), sError);
+ JS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string, sError));
}
}
@@ -129,7 +127,7 @@ void JSPropSetter(const char* prop_name_string,
/* ========================================= METHOD CALLBACK =========================================== */
-template <class C, FX_BOOL (C::*M)(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)>
+template <class C, FX_BOOL (C::*M)(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)>
void JSMethod(const char* method_name_string,
const char* class_name_string,
const v8::FunctionCallbackInfo<v8::Value>& info) {
@@ -146,11 +144,9 @@ void JSMethod(const char* method_name_string,
CJS_Value valueRes(isolate);
CJS_Object* pJSObj = (CJS_Object *)JS_GetPrivate(isolate,info.Holder());
C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
- JS_ErrorString sError;
+ CFX_WideString sError;
if (!(pObj->*M)(cc, parameters, valueRes, sError)) {
- CFX_ByteString cbName;
- cbName.Format("%s.%s", class_name_string, method_name_string);
- JS_Error(NULL, CFX_WideString::FromLocal(cbName), sError);
+ JS_Error(isolate, JSFormatErrorString(class_name_string, method_name_string, sError));
return;
}
info.GetReturnValue().Set(valueRes.ToJSValue());
@@ -160,14 +156,14 @@ void JSMethod(const char* method_name_string,
static void method_name##_static( \
const v8::FunctionCallbackInfo<v8::Value>& info) { \
JSMethod<class_name, &class_name::method_name>( \
- #class_name, #method_name, info); \
+ #method_name, #class_name, info); \
}
#define JS_SPECIAL_STATIC_METHOD(method_name, class_alternate, class_name) \
static void method_name##_static( \
const v8::FunctionCallbackInfo<v8::Value>& info) { \
JSMethod<class_alternate, &class_alternate::method_name>( \
- #class_name, #method_name, info); \
+ #method_name, #class_name, info); \
}
/* ===================================== JS CLASS =============================================== */
@@ -278,14 +274,12 @@ void JSSpecialPropGet(const char* class_name,
Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
v8::String::Utf8Value utf8_value(property);
CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
- JS_ErrorString sError;
+ CFX_WideString sError;
CJS_PropValue value(isolate);
value.StartGetting();
if (!pObj->DoProperty(pRuntimeContext, propname.c_str(), value, sError)) {
- CFX_ByteString cbName;
- cbName.Format("%s.%s", class_name, L"GetProperty");
- JS_Error(NULL,CFX_WideString::FromLocal(cbName), sError);
- return;
+ JS_Error(isolate, JSFormatErrorString(class_name, "GetProperty", sError));
+ return;
}
info.GetReturnValue().Set((v8::Handle<v8::Value>)value);
}
@@ -305,13 +299,11 @@ void JSSpecialPropPut(const char* class_name,
Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
v8::String::Utf8Value utf8_value(property);
CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
- JS_ErrorString sError;
+ CFX_WideString sError;
CJS_PropValue PropValue(CJS_Value(isolate,value,VT_unknown));
PropValue.StartSetting();
if (!pObj->DoProperty(pRuntimeContext, propname.c_str(), PropValue, sError)) {
- CFX_ByteString cbName;
- cbName.Format("%s.%s", class_name, "PutProperty");
- JS_Error(NULL,CFX_WideString::FromLocal(cbName), sError);
+ JS_Error(isolate, JSFormatErrorString(class_name, "PutProperty", sError));
}
}
@@ -329,7 +321,7 @@ void JSSpecialPropDel(const char* class_name,
Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
v8::String::Utf8Value utf8_value(property);
CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
- JS_ErrorString sError;
+ CFX_WideString sError;
if (!pObj->DelProperty(pRuntimeContext, propname.c_str(), sError)) {
CFX_ByteString cbName;
cbName.Format("%s.%s", class_name, "DelProperty");
@@ -408,9 +400,9 @@ int js_class_name::Init(IJS_Runtime* pRuntime, FXJSOBJTYPE eObjType)\
/* ======================================== GLOBAL METHODS ============================================ */
-template <FX_BOOL (*F)(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)>
+template <FX_BOOL (*F)(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)>
void JSGlobalFunc(const char *func_name_string,
- const v8::FunctionCallbackInfo<v8::Value>& info) {
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
v8::Isolate* isolate = info.GetIsolate();
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::Local<v8::Value> v = context->GetEmbedderData(1);
@@ -422,10 +414,10 @@ void JSGlobalFunc(const char *func_name_string,
parameters.push_back(CJS_Value(isolate, info[i], VT_unknown));
}
CJS_Value valueRes(isolate);
- JS_ErrorString sError;
+ CFX_WideString sError;
if (!(*F)(cc, parameters, valueRes, sError))
{
- JS_Error(NULL, JS_WIDESTRING(fun_name), sError);
+ JS_Error(isolate, JSFormatErrorString(func_name_string, nullptr, sError));
return;
}
info.GetReturnValue().Set(valueRes.ToJSValue());
diff --git a/fpdfsdk/include/javascript/JS_Object.h b/fpdfsdk/include/javascript/JS_Object.h
index dbf7da68a4..86ae14f3d0 100644
--- a/fpdfsdk/include/javascript/JS_Object.h
+++ b/fpdfsdk/include/javascript/JS_Object.h
@@ -7,6 +7,11 @@
#ifndef _JS_OBJECT_H_
#define _JS_OBJECT_H_
+#include "../fsdk_define.h" // For FX_UINT
+#include "../fsdk_mgr.h" // For CPDFDoc_Environment
+#include "../fx_systemhandler.h" // For IFX_SystemHandler
+
+class CPDFSDK_PageView;
class CJS_Object;
class CJS_Timer;
class CJS_Context;
diff --git a/fpdfsdk/include/javascript/resource.h b/fpdfsdk/include/javascript/resource.h
index 058b5fd893..8f0a25061e 100644
--- a/fpdfsdk/include/javascript/resource.h
+++ b/fpdfsdk/include/javascript/resource.h
@@ -26,8 +26,12 @@ class CJS_Context;
#define IDS_STRING_RUN 25630
#define IDS_STRING_JSPRINT1 25632
#define IDS_STRING_JSPRINT2 25633
-#define IDS_JSPARAM_INCORRECT 25635
+#define IDS_STRING_JSNOGLOBAL 25635
+#define IDS_STRING_JSREADONLY 25636
CFX_WideString JSGetStringFromID(CJS_Context* pContext, FX_UINT id);
+CFX_WideString JSFormatErrorString(const char* class_name,
+ const char* property_name,
+ const CFX_WideString& details);
#endif // FPDFSDK_INCLUDE_JAVASCRIPT_RESOURCE_H_
diff --git a/fpdfsdk/include/jsapi/fxjs_v8.h b/fpdfsdk/include/jsapi/fxjs_v8.h
index b6ea60be13..c7fdf87747 100644
--- a/fpdfsdk/include/jsapi/fxjs_v8.h
+++ b/fpdfsdk/include/jsapi/fxjs_v8.h
@@ -8,6 +8,7 @@
#define FXJSAPI_H
#include <v8.h>
+#include "../../core/include/fxcrt/fx_string.h" // For CFX_WideString
enum FXJSOBJTYPE
{
@@ -66,11 +67,10 @@ v8::Handle<v8::Object> JS_GetThisObj(IJS_Runtime * pJSRuntime);
int JS_GetObjDefnID(v8::Handle<v8::Object> pObj);
IJS_Runtime* JS_GetRuntime(v8::Handle<v8::Object> pObj);
int JS_GetObjDefnID(IJS_Runtime * pJSRuntime, const wchar_t* pObjName);
-void JS_Error(v8::Value * pError,const wchar_t * main,const wchar_t * sub);
+void JS_Error(v8::Isolate* isolate, const CFX_WideString& message);
unsigned JS_CalcHash(const wchar_t* main, unsigned nLen);
unsigned JS_CalcHash(const wchar_t* main);
const wchar_t* JS_GetTypeof(v8::Handle<v8::Value> pObj);
-const wchar_t* JS_GetClassname(v8::Handle<v8::Object> pObj);
void JS_SetPrivate(IJS_Runtime* pJSRuntime, v8::Handle<v8::Object> pObj, void* p);
void* JS_GetPrivate(IJS_Runtime* pJSRuntime, v8::Handle<v8::Object> pObj);
void JS_SetPrivate(v8::Handle<v8::Object> pObj, void* p);
diff --git a/fpdfsdk/src/javascript/Document.cpp b/fpdfsdk/src/javascript/Document.cpp
index c9f17ba75c..404e1df146 100644
--- a/fpdfsdk/src/javascript/Document.cpp
+++ b/fpdfsdk/src/javascript/Document.cpp
@@ -16,7 +16,7 @@
#include "../../include/javascript/app.h"
#include "../../include/javascript/Field.h"
#include "../../include/javascript/Icon.h"
-#include "../../include/javascript/Field.h"
+#include "../../include/javascript/resource.h"
#include "../../../third_party/base/numerics/safe_math.h"
@@ -192,18 +192,14 @@ Document::~Document()
//the total number of fileds in document.
FX_BOOL Document::numFields(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
{
- if (!vp.IsGetting()) return FALSE;
-
- ASSERT(m_pDocument != NULL);
-
+ if (vp.IsSetting()) {
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
+ return FALSE;
+ }
CPDFSDK_InterForm *pInterForm = m_pDocument->GetInterForm();
- ASSERT(pInterForm != NULL);
-
CPDF_InterForm *pPDFForm = pInterForm->GetInterForm();
- ASSERT(pPDFForm != NULL);
-
vp << (int)pPDFForm->CountFields();
-
return TRUE;
}
@@ -878,7 +874,7 @@ FX_BOOL Document::info(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sEr
CFX_WideString cwTrapped = pDictionary->GetUnicodeText("Trapped");
v8::Isolate* isolate = GetIsolate(cc);
- if (!vp.IsSetting())
+ if (vp.IsGetting())
{
CJS_Context* pContext = (CJS_Context *)cc;
CJS_Runtime* pRuntime = pContext->GetJSRuntime();
@@ -1135,16 +1131,13 @@ FX_BOOL Document::title(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sE
FX_BOOL Document::numPages(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
{
- if (vp.IsGetting())
- {
- ASSERT(m_pDocument != NULL);
- vp << m_pDocument->GetPageCount();
- return TRUE;
- }
- else
- {
+ if (vp.IsSetting()) {
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
return FALSE;
}
+ vp << m_pDocument->GetPageCount();
+ return TRUE;
}
FX_BOOL Document::external(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
@@ -1156,8 +1149,11 @@ FX_BOOL Document::external(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString&
FX_BOOL Document::filesize(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
{
- if (!vp.IsGetting())return FALSE;
-
+ if (vp.IsSetting()) {
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
+ return FALSE;
+ }
vp << 0;
return TRUE;
}
@@ -1213,11 +1209,12 @@ FX_BOOL Document::calculate(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString
FX_BOOL Document::documentFileName(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
{
- if (!vp.IsGetting())
+ if (vp.IsSetting()) {
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
return FALSE;
-
+ }
CFX_WideString wsFilePath = m_pDocument->GetPath();
-
FX_INT32 i = wsFilePath.GetLength() - 1;
for ( ; i >= 0; i-- )
{
@@ -1282,10 +1279,12 @@ CFX_WideString Document::CutString(CFX_WideString cbFrom)
FX_BOOL Document::path(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
{
- if (!vp.IsGetting()) return FALSE;
-
+ if (vp.IsSetting()) {
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
+ return FALSE;
+ }
vp << app::SysPathToPDFPath(m_pDocument->GetPath());
-
return TRUE;
}
@@ -1491,8 +1490,11 @@ FX_BOOL Document::addIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_V
FX_BOOL Document::icons(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
{
- if (vp.IsSetting())
+ if (vp.IsSetting()) {
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
return FALSE;
+ }
if (!m_pIconTree)
{
@@ -1619,7 +1621,8 @@ FX_BOOL Document::getPageNthWord(IFXJS_Context* cc, const CJS_Parameters& params
if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
{
- //sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
return FALSE;
}
@@ -1688,7 +1691,8 @@ FX_BOOL Document::getPageNumWords(IFXJS_Context* cc, const CJS_Parameters& param
if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
{
- //sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
return FALSE;
}
diff --git a/fpdfsdk/src/javascript/console.cpp b/fpdfsdk/src/javascript/console.cpp
index d79ac3405d..e8a2c4c4a0 100644
--- a/fpdfsdk/src/javascript/console.cpp
+++ b/fpdfsdk/src/javascript/console.cpp
@@ -10,9 +10,7 @@
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
#include "../../include/javascript/console.h"
-//#include "../../include/javascript/JS_Module.h"
#include "../../include/javascript/JS_EventHandler.h"
-//#include "../../include/javascript/JS_ResMgr.h"
#include "../../include/javascript/JS_Context.h"
/* ------------------------ console ------------------------ */
diff --git a/fpdfsdk/src/javascript/global.cpp b/fpdfsdk/src/javascript/global.cpp
index 587ba85219..cc18b2906c 100644
--- a/fpdfsdk/src/javascript/global.cpp
+++ b/fpdfsdk/src/javascript/global.cpp
@@ -4,15 +4,16 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#include "../../include/javascript/JavaScript.h"
#include "../../include/javascript/IJavaScript.h"
+#include "../../include/javascript/JS_Context.h"
#include "../../include/javascript/JS_Define.h"
+#include "../../include/javascript/JS_EventHandler.h"
+#include "../../include/javascript/JS_GlobalData.h"
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/JS_GlobalData.h"
+#include "../../include/javascript/JavaScript.h"
#include "../../include/javascript/global.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_Context.h"
+#include "../../include/javascript/resource.h"
/* ---------------------------- global ---------------------------- */
@@ -270,9 +271,10 @@ FX_BOOL global_alternate::DoProperty(IFXJS_Context* cc, FX_LPCWSTR propname, CJS
FX_BOOL global_alternate::setPersistent(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
{
+ CJS_Context* pContext = static_cast<CJS_Context*>(cc);
if (params.size() != 2)
{
- //sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
return FALSE;
}
@@ -288,7 +290,7 @@ FX_BOOL global_alternate::setPersistent(IFXJS_Context* cc, const CJS_Parameters&
}
}
- //sError = JSGetStringFromID(IDS_JSPARAM_INCORRECT);
+ sError = JSGetStringFromID(pContext, IDS_STRING_JSNOGLOBAL);
return FALSE;
}
diff --git a/fpdfsdk/src/javascript/resource.cpp b/fpdfsdk/src/javascript/resource.cpp
index 1c453dcda7..be24ccd66c 100644
--- a/fpdfsdk/src/javascript/resource.cpp
+++ b/fpdfsdk/src/javascript/resource.cpp
@@ -39,9 +39,24 @@ CFX_WideString JSGetStringFromID(CJS_Context* pContext, FX_UINT id)
return L"The second parameter can't be converted to a Date.";
case IDS_STRING_JSPRINT2:
return L"The second parameter is an invalid Date!";
- case IDS_JSPARAM_INCORRECT:
+ case IDS_STRING_JSNOGLOBAL:
return L"Global value not found.";
+ case IDS_STRING_JSREADONLY:
+ return L"Cannot assign to readonly property.";
default:
return L"";
}
}
+
+CFX_WideString JSFormatErrorString(const char* class_name,
+ const char* property_name,
+ const CFX_WideString& details) {
+ CFX_WideString result = CFX_WideString::FromLocal(class_name);
+ if (property_name) {
+ result += L".";
+ result += CFX_WideString::FromLocal(property_name);
+ }
+ result += L": ";
+ result += details;
+ return result;
+}
diff --git a/fpdfsdk/src/jsapi/fxjs_v8.cpp b/fpdfsdk/src/jsapi/fxjs_v8.cpp
index a3f7b6ddd3..edade5fb94 100644
--- a/fpdfsdk/src/jsapi/fxjs_v8.cpp
+++ b/fpdfsdk/src/jsapi/fxjs_v8.cpp
@@ -457,9 +457,14 @@ int JS_GetObjDefnID(IJS_Runtime * pJSRuntime, const wchar_t* pObjName)
return -1;
}
-void JS_Error(v8::Value * pError,const wchar_t * main,const wchar_t * sub)
+void JS_Error(v8::Isolate* isolate, const CFX_WideString& message)
{
-
+ // Conversion from pdfium's wchar_t wide-strings to v8's uint16_t
+ // wide-strings isn't handled by v8, so use UTF8 as a common
+ // intermediate format.
+ CFX_ByteString utf8_message = message.UTF8Encode();
+ isolate->ThrowException(v8::String::NewFromUtf8(isolate,
+ utf8_message.c_str()));
}
unsigned JS_CalcHash(const wchar_t* main, unsigned nLen)
@@ -491,11 +496,6 @@ const wchar_t* JS_GetTypeof(v8::Handle<v8::Value> pObj)
return NULL;
}
-const wchar_t* JS_GetClassname(v8::Handle<v8::Object> pObj)
-{
- return NULL;
-}
-
void JS_SetPrivate(v8::Handle<v8::Object> pObj, void* p)
{
JS_SetPrivate(NULL, pObj, p);
diff --git a/testing/resources/javascript/document_props.in b/testing/resources/javascript/document_props.in
index 8ab7e3d566..c628fafad2 100644
--- a/testing/resources/javascript/document_props.in
+++ b/testing/resources/javascript/document_props.in
@@ -105,27 +105,27 @@ var document_props = [
];
function testGetProps(props) {
- try {
- app.alert('*** Getting properties ***');
- for (var i = 0; i < props.length; ++i) {
- var expr1 = "this." + props[i];
- var expr2 = "typeof " + expr1;
- app.alert(expr1 + " is " + eval(expr2) + ' ' + eval(expr1));
+ app.alert('*** Getting properties ***');
+ for (var i = 0; i < props.length; ++i) {
+ try {
+ var expr1 = "this." + props[i];
+ var expr2 = "typeof " + expr1;
+ app.alert(expr1 + " is " + eval(expr2) + ' ' + eval(expr1));
+ } catch (e) {
+ app.alert("ERROR: " + e.toString());
}
- } catch (e) {
- app.alert("ERROR: " + e.toString());
}
}
function testSetProps(props) {
- try {
- app.alert('*** Setting properties ***');
- for (var i = 0; i < props.length; ++i) {
- var expr1 = "this." + props[i] + ' = 3;'
- app.alert(expr1 + " yields " + eval(expr1));
+ app.alert('*** Setting properties ***');
+ for (var i = 0; i < props.length; ++i) {
+ try {
+ var expr1 = "this." + props[i] + ' = 3;'
+ app.alert(expr1 + " yields " + eval(expr1));
+ } catch (e) {
+ app.alert("ERROR: " + e.toString());
}
- } catch (e) {
- app.alert("ERROR: " + e.toString());
}
}
diff --git a/testing/resources/javascript/document_props_expected.txt b/testing/resources/javascript/document_props_expected.txt
index 38bea97acb..728d2455e1 100644
--- a/testing/resources/javascript/document_props_expected.txt
+++ b/testing/resources/javascript/document_props_expected.txt
@@ -41,10 +41,10 @@ Alert: this.creationDate = 3; yields 3
Alert: this.creator = 3; yields 3
Alert: this.delay = 3; yields 3
Alert: this.dirty = 3; yields 3
-Alert: this.documentFileName = 3; yields 3
+Alert: ERROR: Document.documentFileName: Cannot assign to readonly property.
Alert: this.external = 3; yields 3
-Alert: this.filesize = 3; yields 3
-Alert: this.icons = 3; yields 3
+Alert: ERROR: Document.filesize: Cannot assign to readonly property.
+Alert: ERROR: Document.icons: Cannot assign to readonly property.
Alert: this.info = 3; yields 3
Alert: this.keywords = 3; yields 3
Alert: this.layout = 3; yields 3
@@ -52,12 +52,12 @@ Alert: this.media = 3; yields 3
Alert: this.modDate = 3; yields 3
Alert: this.mouseX = 3; yields 3
Alert: this.mouseY = 3; yields 3
-Alert: this.numFields = 3; yields 3
-Alert: this.numPages = 3; yields 3
+Alert: ERROR: Document.numFields: Cannot assign to readonly property.
+Alert: ERROR: Document.numPages: Cannot assign to readonly property.
Goto Page: 3
Alert: this.pageNum = 3; yields 3
Alert: this.pageWindowRect = 3; yields 3
-Alert: this.path = 3; yields 3
+Alert: ERROR: Document.path: Cannot assign to readonly property.
Alert: this.producer = 3; yields 3
Alert: this.subject = 3; yields 3
Alert: this.title = 3; yields 3
diff --git a/testing/resources/javascript/globals.in b/testing/resources/javascript/globals.in
index 6d2f3ca241..4812101e7a 100644
--- a/testing/resources/javascript/globals.in
+++ b/testing/resources/javascript/globals.in
@@ -63,21 +63,34 @@ var props_to_test = [
function setup_global() {
for (var i = 0; i < props_to_test.length; ++i) {
var prop = props_to_test[i];
- global[prop.name] = prop.value;
+ try {
+ global[prop.name] = prop.value;
+ } catch (e) {
+ app.alert("For " + prop.name + ": Setup: ERROR: " + e.toString());
+ }
}
}
function delete_global() {
for (var i = 0; i < props_to_test.length; ++i) {
var prop = props_to_test[i];
- delete global[prop.name];
+ try {
+ delete global[prop.name];
+ } catch (e) {
+ app.alert("For " + prop.name + ": Delete: ERROR: " + e.toString());
+ }
}
}
function persist_global(should_persist) {
for (var i = 0; i < props_to_test.length; ++i) {
var prop = props_to_test[i];
- global.setPersistent(prop.name, should_persist);
+ try {
+ global.setPersistent(prop.name, should_persist);
+ } catch (e) {
+ app.alert("For " + prop.name +
+ ": Set Persistent: ERROR: " + e.toString());
+ }
}
}
@@ -85,18 +98,27 @@ function dump_global(msg) {
app.alert("************ " + msg + " ************");
app.alert("Enumerable Globals:");
for (var name in global) {
- app.alert(" " + name + " = " + global[name] +
- ", own property = " + global.hasOwnProperty(name));
+ try {
+ app.alert(" " + name + " = " + global[name] +
+ ", own property = " + global.hasOwnProperty(name));
+ } catch (e) {
+ app.alert("For " + name + ": Dump: ERROR: " + e.toString());
+ }
}
app.alert("Expected Globals:");
for (var i = 0; i < props_to_test.length; ++i) {
var prop = props_to_test[i];
- var actual = global[prop.name];
- app.alert(" " + prop.name + " = " + actual);
- if (actual != null && typeof actual == "object") {
- app.alert(" " + actual.colors[0]);
- app.alert(" " + actual.colors[1]);
- app.alert(" " + actual.colors[2]);
+ try {
+ var actual = global[prop.name];
+ app.alert(" " + prop.name + " = " + actual);
+ if (actual != null && typeof actual == "object") {
+ app.alert(" " + actual.colors[0]);
+ app.alert(" " + actual.colors[1]);
+ app.alert(" " + actual.colors[2]);
+ }
+ } catch (e) {
+ app.alert("For " + prop.name +
+ ": Dump Expected: ERROR: " + e.toString());
}
}
}
diff --git a/testing/resources/javascript/globals_expected.txt b/testing/resources/javascript/globals_expected.txt
index ddaa00cd09..fcebd70466 100644
--- a/testing/resources/javascript/globals_expected.txt
+++ b/testing/resources/javascript/globals_expected.txt
@@ -45,6 +45,7 @@ Alert: string_var = undefined
Alert: object_var = undefined
Alert: null_var = undefined
Alert: undefined_var = undefined
+Alert: For undefined_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
Alert: ************ After Setup and Persist false ************
Alert: Enumerable Globals:
Alert: setPersistent = function setPersistent() { [native code] }, own property = true
@@ -68,6 +69,14 @@ Alert: green
Alert: blue
Alert: null_var = null
Alert: undefined_var = undefined
+Alert: For true_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
+Alert: For false_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
+Alert: For zero_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
+Alert: For number_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
+Alert: For string_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
+Alert: For object_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
+Alert: For null_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
+Alert: For undefined_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
Alert: ************ After Delete and Persist ************
Alert: Enumerable Globals:
Alert: setPersistent = function setPersistent() { [native code] }, own property = true
@@ -80,6 +89,7 @@ Alert: string_var = undefined
Alert: object_var = undefined
Alert: null_var = undefined
Alert: undefined_var = undefined
+Alert: For undefined_var: Set Persistent: ERROR: global.setPersistent: Global value not found.
Alert: ************ After Setup and Persist true ************
Alert: Enumerable Globals:
Alert: setPersistent = function setPersistent() { [native code] }, own property = true