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.