Allow print() only in response to a user gesture This prevents the print dialog opening automatically when a PDF is embedded in a web-page. As part of this change, move the existing tests from document_methods.in to mouse_events.in, and extend the mouse_events.in tests to check that print can only be called in response to a user gesture. BUG=chromium:968914 Change-Id: Ib55808cf500288460f79c940af0c4d2738bb93e5 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56790 Commit-Queue: Tom Sepez <tsepez@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp index 4fc8803..cd9beeb 100644 --- a/fxjs/cjs_document.cpp +++ b/fxjs/cjs_document.cpp
@@ -508,6 +508,11 @@ if (!m_pFormFillEnv) return CJS_Result::Failure(JSMessage::kBadObjectError); + CJS_EventRecorder* pHandler = + pRuntime->GetCurrentEventContext()->GetEventRecorder(); + if (!pHandler->IsUserGesture()) + return CJS_Result::Failure(JSMessage::kUserGestureRequiredError); + m_pFormFillEnv->JS_docprint(bUI, nStart, nEnd, bSilent, bShrinkToFit, bPrintAsImage, bReverse, bAnnotations); return CJS_Result::Success();
diff --git a/testing/resources/javascript/document_methods.in b/testing/resources/javascript/document_methods.in index 1f2dd29..9571e55 100644 --- a/testing/resources/javascript/document_methods.in +++ b/testing/resources/javascript/document_methods.in
@@ -274,16 +274,11 @@ } function testPrint() { - // Method is present. - expect('typeof this.print', 'function'); + // Method is present. + 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); + // Successful only when invoked by a user gesture. + expectError('this.print()', undefined); } function testRemoveField() {
diff --git a/testing/resources/javascript/document_methods_expected.txt b/testing/resources/javascript/document_methods_expected.txt index 495c2fb..ec42224 100644 --- a/testing/resources/javascript/document_methods_expected.txt +++ b/testing/resources/javascript/document_methods_expected.txt
@@ -131,14 +131,7 @@ Mail Msg: 0, to=user@example.com, cc=cc@example.com, bcc=bcc@example.com, subject=LotteryWinner, body=You won the lottery! Alert: PASS: this.mailForm({"bUI": false, "cTo": "user@example.com", "cCc": "cc@example.com", "cBcc": "bcc@example.com", "cSubject": "LotteryWinner", "cMsg": "You won the lottery!", "bogus": "yes"}) = 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: this.print() threw Document.print: User gesture required. Alert: PASS: typeof this.removeField = function Alert: PASS: this.removeField() threw Document.removeField: Incorrect number of parameters passed to function. Alert: PASS: typeof this.resetForm = function
diff --git a/testing/resources/javascript/mouse_events.in b/testing/resources/javascript/mouse_events.in index 353961c..9480e94 100644 --- a/testing/resources/javascript/mouse_events.in +++ b/testing/resources/javascript/mouse_events.in
@@ -61,6 +61,13 @@ } catch \(e\) { app.alert\("PASS: this.submitForm blocked with " + e\); } + + try { + this.print\(\); + app.alert\("ERROR: this.print\(\) must not be allowed to execute"\); + } catch \(e\) { + app.alert\("PASS: this.print blocked with " + e\); + } ) >> endobj @@ -75,6 +82,13 @@ } catch \(e\) { app.alert\("PASS: this.submitForm blocked with " + e\); } + + try { + this.print\(\); + app.alert\("ERROR: this.print\(\) must not be allowed to execute"\); + } catch \(e\) { + app.alert\("PASS: this.print blocked with " + e\); + } ) >> endobj @@ -88,6 +102,17 @@ } catch \(e\) { app.alert\("ERROR: " + e\); } + + try { + this.print\(\); + this.print\(false, 1, 10, true, true, true, true, true\); + this.print\({}\); + this.print\({"bUi": false, "nStart": 42, "nEnd": 17, + "bSilent": true, "bShrinkToFit": true, "bPrintAsImage": true, + "bReverse": true, "bAnnotations": true, "bogus": "yes"}\); + } catch \(e\) { + app.alert\("ERROR: " + e\); + } ) >> endobj @@ -101,6 +126,12 @@ } catch \(e\) { app.alert\("ERROR: " + e\); } + + try { + this.print\(\); + } catch \(e\) { + app.alert\("ERROR: " + e\); + } ) >> endobj @@ -115,6 +146,13 @@ } catch \(e\) { app.alert\("PASS: this.submitForm blocked with " + e\); } + + try { + this.print\(\); + app.alert\("ERROR: this.print\(\) must not be allowed to execute"\); + } catch \(e\) { + app.alert\("PASS: this.print blocked with " + e\); + } ) >> endobj @@ -129,6 +167,13 @@ } catch \(e\) { app.alert\("PASS: this.submitForm blocked with " + e\); } + + try { + this.print\(\); + app.alert\("ERROR: this.print\(\) must not be allowed to execute"\); + } catch \(e\) { + app.alert\("PASS: this.print blocked with " + e\); + } ) >> endobj
diff --git a/testing/resources/javascript/mouse_events_expected.txt b/testing/resources/javascript/mouse_events_expected.txt index da031bf..8e87e1a 100644 --- a/testing/resources/javascript/mouse_events_expected.txt +++ b/testing/resources/javascript/mouse_events_expected.txt
@@ -1,20 +1,33 @@ Alert: enter Alert: PASS: this.submitForm blocked with Document.submitForm: User gesture required. +Alert: PASS: this.print blocked with Document.print: User gesture required. Alert: exit Alert: PASS: this.submitForm blocked with Document.submitForm: User gesture required. +Alert: PASS: this.print blocked with Document.print: User gesture required. Alert: enter Alert: PASS: this.submitForm blocked with Document.submitForm: User gesture required. +Alert: PASS: this.print blocked with Document.print: User gesture required. Alert: down Doc Submit Form: url=myform +Doc Print: 1, 0, 0, 0, 0, 0, 0, 0 +Doc Print: 0, 1, 10, 1, 1, 1, 1, 1 +Doc Print: 1, 0, 0, 0, 0, 0, 0, 0 +Doc Print: 1, 42, 17, 1, 1, 1, 1, 1 Alert: focus Alert: PASS: this.submitForm blocked with Document.submitForm: User gesture required. +Alert: PASS: this.print blocked with Document.print: User gesture required. Alert: up Doc Submit Form: url=myform +Doc Print: 1, 0, 0, 0, 0, 0, 0, 0 Alert: exit Alert: PASS: this.submitForm blocked with Document.submitForm: User gesture required. +Alert: PASS: this.print blocked with Document.print: User gesture required. Alert: enter Alert: PASS: this.submitForm blocked with Document.submitForm: User gesture required. +Alert: PASS: this.print blocked with Document.print: User gesture required. Alert: focus Alert: PASS: this.submitForm blocked with Document.submitForm: User gesture required. +Alert: PASS: this.print blocked with Document.print: User gesture required. Alert: exit Alert: PASS: this.submitForm blocked with Document.submitForm: User gesture required. +Alert: PASS: this.print blocked with Document.print: User gesture required.