From 0e5bab1b8402b65fa09a36a2b141bbf22291f822 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Thu, 18 Oct 2018 21:39:40 +0000 Subject: Remove PrintParams object. The only way to theoretically get one is via doc.getPrintParams(), and it always returns in error. Even if one were returend to JS, there aren't any methods/callbacks to change its properties. Even if there were methods to change its properties, the information it stores doesn't align with what is in the JS spec for this object. Even if it were aligned with the JS spec, the way we check for its presence as the ninth parameter in CJS_Document::print() doesn't match the way its use is documented in the spec as the sole first parameter. Instead implement the older, simpler behaviour as spec'd prior to 6.0, and toss this enhancement altogether. Move function to check the result of ExpandKeywordParams() to js_define.h so other files can use it. Update comment in that file to remove reference to deprecated enum. Expand test for API and introduce callback to log parameters. Change-Id: I047e2be0d2afbad91d6b58c6c74bbea083fed330 Reviewed-on: https://pdfium-review.googlesource.com/c/44271 Commit-Queue: Tom Sepez Reviewed-by: Lei Zhang --- fxjs/BUILD.gn | 2 - fxjs/cjs_app.cpp | 43 ++++++-------- fxjs/cjs_document.cpp | 67 +++++++++------------- fxjs/cjs_printparamsobj.cpp | 29 ---------- fxjs/cjs_printparamsobj.h | 42 -------------- fxjs/cjs_runtime.cpp | 4 +- fxjs/js_define.cpp | 7 +++ fxjs/js_define.h | 6 +- samples/pdfium_test.cc | 14 +++++ testing/resources/javascript/document_methods.in | 6 ++ .../javascript/document_methods_expected.txt | 8 +++ 11 files changed, 82 insertions(+), 146 deletions(-) delete mode 100644 fxjs/cjs_printparamsobj.cpp delete mode 100644 fxjs/cjs_printparamsobj.h diff --git a/fxjs/BUILD.gn b/fxjs/BUILD.gn index 2022d3b735..5f475edd7a 100644 --- a/fxjs/BUILD.gn +++ b/fxjs/BUILD.gn @@ -74,8 +74,6 @@ jumbo_source_set("fxjs") { "cjs_object.h", "cjs_position.cpp", "cjs_position.h", - "cjs_printparamsobj.cpp", - "cjs_printparamsobj.h", "cjs_publicmethods.cpp", "cjs_publicmethods.h", "cjs_report.cpp", diff --git a/fxjs/cjs_app.cpp b/fxjs/cjs_app.cpp index e217753062..f279250fb0 100644 --- a/fxjs/cjs_app.cpp +++ b/fxjs/cjs_app.cpp @@ -21,17 +21,6 @@ #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h" #endif // PDF_ENABLE_XFA -namespace { - -bool IsTypeKnown(v8::Local value) { - return !value.IsEmpty() && - (value->IsString() || value->IsNumber() || value->IsBoolean() || - value->IsDate() || value->IsObject() || value->IsNull() || - value->IsUndefined()); -} - -} // namespace - #define JS_STR_VIEWERTYPE L"pdfium" #define JS_STR_VIEWERVARIATION L"Full" #define JS_STR_PLATFORM L"WIN" @@ -237,7 +226,7 @@ CJS_Result CJS_App::alert(CJS_Runtime* pRuntime, std::vector> newParams = ExpandKeywordParams( pRuntime, params, 4, L"cMsg", L"nIcon", L"nType", L"cTitle"); - if (!IsTypeKnown(newParams[0])) + if (!IsExpandedParamKnown(newParams[0])) return CJS_Result::Failure(JSMessage::kParamError); CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv(); @@ -260,15 +249,15 @@ CJS_Result CJS_App::alert(CJS_Runtime* pRuntime, } int iIcon = JSPLATFORM_ALERT_ICON_DEFAULT; - if (IsTypeKnown(newParams[1])) + if (IsExpandedParamKnown(newParams[1])) iIcon = pRuntime->ToInt32(newParams[1]); int iType = JSPLATFORM_ALERT_BUTTON_DEFAULT; - if (IsTypeKnown(newParams[2])) + if (IsExpandedParamKnown(newParams[2])) iType = pRuntime->ToInt32(newParams[2]); WideString swTitle; - if (IsTypeKnown(newParams[3])) + if (IsExpandedParamKnown(newParams[3])) swTitle = pRuntime->ToWideString(newParams[3]); else swTitle = JSGetStringFromID(JSMessage::kAlert); @@ -288,7 +277,7 @@ CJS_Result CJS_App::beep(CJS_Runtime* pRuntime, return CJS_Result::Failure(JSMessage::kParamError); int type = JSPLATFORM_BEEP_DEFAULT; - if (IsTypeKnown(params[0])) + if (IsExpandedParamKnown(params[0])) type = pRuntime->ToInt32(params[0]); pRuntime->GetFormFillEnv()->JS_appBeep(type); @@ -448,12 +437,12 @@ CJS_Result CJS_App::mailMsg(CJS_Runtime* pRuntime, ExpandKeywordParams(pRuntime, params, 6, L"bUI", L"cTo", L"cCc", L"cBcc", L"cSubject", L"cMsg"); - if (!IsTypeKnown(newParams[0])) + if (!IsExpandedParamKnown(newParams[0])) return CJS_Result::Failure(JSMessage::kParamError); bool bUI = pRuntime->ToBoolean(newParams[0]); WideString cTo; - if (IsTypeKnown(newParams[1])) { + if (IsExpandedParamKnown(newParams[1])) { cTo = pRuntime->ToWideString(newParams[1]); } else { // cTo parameter required when UI not invoked. @@ -462,19 +451,19 @@ CJS_Result CJS_App::mailMsg(CJS_Runtime* pRuntime, } WideString cCc; - if (IsTypeKnown(newParams[2])) + if (IsExpandedParamKnown(newParams[2])) cCc = pRuntime->ToWideString(newParams[2]); WideString cBcc; - if (IsTypeKnown(newParams[3])) + if (IsExpandedParamKnown(newParams[3])) cBcc = pRuntime->ToWideString(newParams[3]); WideString cSubject; - if (IsTypeKnown(newParams[4])) + if (IsExpandedParamKnown(newParams[4])) cSubject = pRuntime->ToWideString(newParams[4]); WideString cMsg; - if (IsTypeKnown(newParams[5])) + if (IsExpandedParamKnown(newParams[5])) cMsg = pRuntime->ToWideString(newParams[5]); pRuntime->BeginBlock(); @@ -546,24 +535,24 @@ CJS_Result CJS_App::response(CJS_Runtime* pRuntime, ExpandKeywordParams(pRuntime, params, 5, L"cQuestion", L"cTitle", L"cDefault", L"bPassword", L"cLabel"); - if (!IsTypeKnown(newParams[0])) + if (!IsExpandedParamKnown(newParams[0])) return CJS_Result::Failure(JSMessage::kParamError); WideString swQuestion = pRuntime->ToWideString(newParams[0]); WideString swTitle = L"PDF"; - if (IsTypeKnown(newParams[1])) + if (IsExpandedParamKnown(newParams[1])) swTitle = pRuntime->ToWideString(newParams[1]); WideString swDefault; - if (IsTypeKnown(newParams[2])) + if (IsExpandedParamKnown(newParams[2])) swDefault = pRuntime->ToWideString(newParams[2]); bool bPassword = false; - if (IsTypeKnown(newParams[3])) + if (IsExpandedParamKnown(newParams[3])) bPassword = pRuntime->ToBoolean(newParams[3]); WideString swLabel; - if (IsTypeKnown(newParams[4])) + if (IsExpandedParamKnown(newParams[4])) swLabel = pRuntime->ToWideString(newParams[4]); const int MAX_INPUT_BYTES = 2048; diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp index 2ecfd424d2..a0dd2ece91 100644 --- a/fxjs/cjs_document.cpp +++ b/fxjs/cjs_document.cpp @@ -25,7 +25,6 @@ #include "fxjs/cjs_delaydata.h" #include "fxjs/cjs_field.h" #include "fxjs/cjs_icon.h" -#include "fxjs/cjs_printparamsobj.h" #include "fxjs/js_resources.h" namespace { @@ -454,51 +453,41 @@ CJS_Result CJS_Document::mailForm( CJS_Result CJS_Document::print( CJS_Runtime* pRuntime, const std::vector>& params) { - if (!m_pFormFillEnv) - return CJS_Result::Failure(JSMessage::kBadObjectError); + std::vector> newParams = ExpandKeywordParams( + pRuntime, params, 8, L"bUI", L"nStart", L"nEnd", L"bSilent", + L"bShrinkToFit", L"bPrintAsImage", L"bReverse", L"bAnnotations"); bool bUI = true; + if (IsExpandedParamKnown(newParams[0])) + bUI = pRuntime->ToBoolean(newParams[0]); + int nStart = 0; + if (IsExpandedParamKnown(newParams[1])) + nStart = pRuntime->ToInt32(newParams[1]); + int nEnd = 0; + if (IsExpandedParamKnown(newParams[2])) + nEnd = pRuntime->ToInt32(newParams[2]); + bool bSilent = false; + if (IsExpandedParamKnown(newParams[3])) + bSilent = pRuntime->ToBoolean(newParams[3]); + bool bShrinkToFit = false; + if (IsExpandedParamKnown(newParams[4])) + bShrinkToFit = pRuntime->ToBoolean(newParams[4]); + bool bPrintAsImage = false; + if (IsExpandedParamKnown(newParams[5])) + bPrintAsImage = pRuntime->ToBoolean(newParams[5]); + bool bReverse = false; + if (IsExpandedParamKnown(newParams[6])) + bReverse = pRuntime->ToBoolean(newParams[6]); + bool bAnnotations = false; - size_t nLength = params.size(); - if (nLength == 9) { - if (params[8]->IsObject()) { - v8::Local pObj = pRuntime->ToObject(params[8]); - auto pPrintObj = JSGetObject(pObj); - if (pPrintObj) { - bUI = pPrintObj->GetUI(); - nStart = pPrintObj->GetStart(); - nEnd = pPrintObj->GetEnd(); - bSilent = pPrintObj->GetSilent(); - bShrinkToFit = pPrintObj->GetShrinkToFit(); - bPrintAsImage = pPrintObj->GetPrintAsImage(); - bReverse = pPrintObj->GetReverse(); - bAnnotations = pPrintObj->GetAnnotations(); - } - } - } else { - if (nLength > 0) - bUI = pRuntime->ToBoolean(params[0]); - if (nLength > 1) - nStart = pRuntime->ToInt32(params[1]); - if (nLength > 2) - nEnd = pRuntime->ToInt32(params[2]); - if (nLength > 3) - bSilent = pRuntime->ToBoolean(params[3]); - if (nLength > 4) - bShrinkToFit = pRuntime->ToBoolean(params[4]); - if (nLength > 5) - bPrintAsImage = pRuntime->ToBoolean(params[5]); - if (nLength > 6) - bReverse = pRuntime->ToBoolean(params[6]); - if (nLength > 7) - bAnnotations = pRuntime->ToBoolean(params[7]); - } + if (IsExpandedParamKnown(newParams[7])) + bAnnotations = pRuntime->ToBoolean(newParams[7]); if (!m_pFormFillEnv) return CJS_Result::Failure(JSMessage::kBadObjectError); @@ -1362,10 +1351,6 @@ CJS_Result CJS_Document::getPageNumWords( CJS_Result CJS_Document::getPrintParams( CJS_Runtime* pRuntime, const std::vector>& params) { - v8::Local pRetObj = pRuntime->NewFXJSBoundObject( - CJS_PrintParamsObj::GetObjDefnID(), FXJSOBJTYPE_DYNAMIC); - if (pRetObj.IsEmpty()) - return CJS_Result::Failure(JSMessage::kBadObjectError); return CJS_Result::Failure(JSMessage::kNotSupportedError); } diff --git a/fxjs/cjs_printparamsobj.cpp b/fxjs/cjs_printparamsobj.cpp deleted file mode 100644 index 37ff956f74..0000000000 --- a/fxjs/cjs_printparamsobj.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 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_printparamsobj.h" - -#include "fxjs/js_define.h" - -int CJS_PrintParamsObj::ObjDefnID = -1; - -// static -int CJS_PrintParamsObj::GetObjDefnID() { - return ObjDefnID; -} - -// static -void CJS_PrintParamsObj::DefineJSObjects(CFXJS_Engine* pEngine) { - ObjDefnID = - pEngine->DefineObj("PrintParamsObj", FXJSOBJTYPE_DYNAMIC, - JSConstructor, JSDestructor); -} - -CJS_PrintParamsObj::CJS_PrintParamsObj(v8::Local pObject, - CJS_Runtime* pRuntime) - : CJS_Object(pObject, pRuntime) {} - -CJS_PrintParamsObj::~CJS_PrintParamsObj() = default; diff --git a/fxjs/cjs_printparamsobj.h b/fxjs/cjs_printparamsobj.h deleted file mode 100644 index f8b055729c..0000000000 --- a/fxjs/cjs_printparamsobj.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2017 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_PRINTPARAMSOBJ_H_ -#define FXJS_CJS_PRINTPARAMSOBJ_H_ - -#include "fxjs/cjs_object.h" - -class CJS_PrintParamsObj final : public CJS_Object { - public: - static int GetObjDefnID(); - static void DefineJSObjects(CFXJS_Engine* pEngine); - - CJS_PrintParamsObj(v8::Local pObject, CJS_Runtime* pRuntime); - ~CJS_PrintParamsObj() override; - - bool GetUI() const { return bUI; } - int GetStart() const { return nStart; } - int GetEnd() const { return nEnd; } - bool GetSilent() const { return bSilent; } - bool GetShrinkToFit() const { return bShrinkToFit; } - bool GetPrintAsImage() const { return bPrintAsImage; } - bool GetReverse() const { return bReverse; } - bool GetAnnotations() const { return bAnnotations; } - - private: - static int ObjDefnID; - - bool bUI = true; - int nStart = 0; - int nEnd = 0; - bool bSilent = false; - bool bShrinkToFit = false; - bool bPrintAsImage = false; - bool bReverse = false; - bool bAnnotations = true; -}; - -#endif // FXJS_CJS_PRINTPARAMSOBJ_H_ diff --git a/fxjs/cjs_runtime.cpp b/fxjs/cjs_runtime.cpp index 3bc8448435..3914b36715 100644 --- a/fxjs/cjs_runtime.cpp +++ b/fxjs/cjs_runtime.cpp @@ -29,7 +29,6 @@ #include "fxjs/cjs_icon.h" #include "fxjs/cjs_object.h" #include "fxjs/cjs_position.h" -#include "fxjs/cjs_printparamsobj.h" #include "fxjs/cjs_publicmethods.h" #include "fxjs/cjs_report.h" #include "fxjs/cjs_scalehow.h" @@ -124,9 +123,8 @@ void CJS_Runtime::DefineJSObjects() { CJS_GlobalConsts::DefineJSObjects(this); CJS_GlobalArrays::DefineJSObjects(this); - // ObjDefIDs 21 - 23. + // ObjDefIDs 21 - 22. CJS_TimerObj::DefineJSObjects(this); - CJS_PrintParamsObj::DefineJSObjects(this); CJS_Annot::DefineJSObjects(this); } diff --git a/fxjs/js_define.cpp b/fxjs/js_define.cpp index 0a18b6d15b..54bd8e1c3a 100644 --- a/fxjs/js_define.cpp +++ b/fxjs/js_define.cpp @@ -313,3 +313,10 @@ std::vector> ExpandKeywordParams( return result; } + +bool IsExpandedParamKnown(v8::Local value) { + return !value.IsEmpty() && + (value->IsString() || value->IsNumber() || value->IsBoolean() || + value->IsDate() || value->IsObject() || value->IsNull() || + value->IsUndefined()); +} diff --git a/fxjs/js_define.h b/fxjs/js_define.h index bf7aa35504..0705dfea6b 100644 --- a/fxjs/js_define.h +++ b/fxjs/js_define.h @@ -35,14 +35,16 @@ double JS_MakeDate(double day, double time); // with a single argument which is an object containing the actual arguments // as its properties. The varying arguments to this method are the property // names as wchar_t string literals corresponding to each positional argument. -// The result will always contain |nKeywords| value, with unspecified ones -// being set to type VT_unknown. +// The result will always contain |nKeywords| value, check for the unspecified +// ones in the result using IsExpandedParamKnown() below. std::vector> ExpandKeywordParams( CJS_Runtime* pRuntime, const std::vector>& originals, size_t nKeywords, ...); +bool IsExpandedParamKnown(v8::Local value); + // All JS classes have a name, an object defintion ID, and the ability to // register themselves with FXJS_V8. We never make a BASE class on its own // because it can't really do anything. diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc index e64382c911..c5c298d23e 100644 --- a/samples/pdfium_test.cc +++ b/samples/pdfium_test.cc @@ -219,6 +219,19 @@ void ExampleDocMail(IPDF_JSPLATFORM*, GetPlatformWString(BCC).c_str(), GetPlatformWString(Subject).c_str(), GetPlatformWString(Msg).c_str()); } + +void ExampleDocPrint(IPDF_JSPLATFORM*, + FPDF_BOOL bUI, + int nStart, + int nEnd, + FPDF_BOOL bSilent, + FPDF_BOOL bShrinkToFit, + FPDF_BOOL bPrintAsImage, + FPDF_BOOL bReverse, + FPDF_BOOL bAnnotations) { + printf("Doc Print: %d, %d, %d, %d, %d, %d, %d, %d\n", bUI, nStart, nEnd, + bSilent, bShrinkToFit, bPrintAsImage, bReverse, bAnnotations); +} #endif // PDF_ENABLE_V8 void ExampleUnsupportedHandler(UNSUPPORT_INFO*, int type) { @@ -724,6 +737,7 @@ void RenderPdf(const std::string& name, platform_callbacks.app_beep = ExampleAppBeep; platform_callbacks.Doc_gotoPage = ExampleDocGotoPage; platform_callbacks.Doc_mail = ExampleDocMail; + platform_callbacks.Doc_print = ExampleDocPrint; #endif // PDF_ENABLE_V8 FPDF_FORMFILLINFO_PDFiumTest form_callbacks = {}; diff --git a/testing/resources/javascript/document_methods.in b/testing/resources/javascript/document_methods.in index 0188d7c237..bb7af748d8 100644 --- a/testing/resources/javascript/document_methods.in +++ b/testing/resources/javascript/document_methods.in @@ -284,6 +284,12 @@ function testPrint() { expect('typeof this.print', 'function'); // TODO(tsepez): test success cases. + expect('this.print()', undefined); + expect('this.print(false, 1, 10, true, true, true, true, true)', undefined); + expect('this.print({})', undefined); + expect('this.print({"bUi": false, "nStart": 42, "nEnd": 17, ' + + '"bSilent": true, "bShrinkToFit": true, "bPrintAsImage": true, ' + + '"bReverse": true, "bAnnotations": true, "bogus": "yes"})', undefined); } function testRemoveField() { diff --git a/testing/resources/javascript/document_methods_expected.txt b/testing/resources/javascript/document_methods_expected.txt index 01bf0ed0bd..e39690ba45 100644 --- a/testing/resources/javascript/document_methods_expected.txt +++ b/testing/resources/javascript/document_methods_expected.txt @@ -118,6 +118,14 @@ Alert: PASS: this.mailForm(true) = undefined Mail Msg: 0, to=user@example.com, cc=cc@example.com, bcc=bcc@example.com, subject=Lottery Winner, body=You won the lottery! Alert: PASS: this.mailForm(false, "user@example.com", "cc@example.com", "bcc@example.com", "Lottery Winner", "You won the lottery!") = undefined Alert: PASS: typeof this.print = function +Doc Print: 1, 0, 0, 0, 0, 0, 0, 0 +Alert: PASS: this.print() = undefined +Doc Print: 0, 1, 10, 1, 1, 1, 1, 1 +Alert: PASS: this.print(false, 1, 10, true, true, true, true, true) = undefined +Doc Print: 1, 0, 0, 0, 0, 0, 0, 0 +Alert: PASS: this.print({}) = undefined +Doc Print: 1, 42, 17, 1, 1, 1, 1, 1 +Alert: PASS: this.print({"bUi": false, "nStart": 42, "nEnd": 17, "bSilent": true, "bShrinkToFit": true, "bPrintAsImage": true, "bReverse": true, "bAnnotations": true, "bogus": "yes"}) = undefined Alert: PASS: typeof this.removeField = function Alert: PASS: this.removeField() threw error Document.removeField: Incorrect number of parameters passed to function. Alert: PASS: typeof this.resetForm = function -- cgit v1.2.3