Merge to M84: Make PDFium JS host object have immutable prototypes

It is doubtful that any legitimate PDF would ever change __proto__
on these objects, and those that do are just trying to muck with us.

TBR: thestig@chromium.org
Bug: chromium:1091404
Change-Id: I99367281e796b91c1858fead3eb18a3a655291f1
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/70430
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
(cherry picked from commit 9b9ba210f32c2a33cff3502a75eb84c39ad5576a)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/70471
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/cfxjs_engine.cpp b/fxjs/cfxjs_engine.cpp
index 9624feb..4a15ebe 100644
--- a/fxjs/cfxjs_engine.cpp
+++ b/fxjs/cfxjs_engine.cpp
@@ -145,6 +145,7 @@
     v8::HandleScope handle_scope(isolate);
     v8::Local<v8::FunctionTemplate> fn = v8::FunctionTemplate::New(isolate);
     fn->InstanceTemplate()->SetInternalFieldCount(2);
+    fn->InstanceTemplate()->SetImmutableProto();
     fn->SetCallHandler(CallHandler, v8::Number::New(isolate, eObjType));
     if (eObjType == FXJSOBJTYPE_GLOBAL) {
       fn->InstanceTemplate()->Set(v8::Symbol::GetToStringTag(isolate),
diff --git a/testing/resources/javascript/immutable_proto.in b/testing/resources/javascript/immutable_proto.in
new file mode 100644
index 0000000..61885c5
--- /dev/null
+++ b/testing/resources/javascript/immutable_proto.in
@@ -0,0 +1,43 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 10 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [
+    3 0 R
+  ]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+>>
+endobj
+% OpenAction action
+{{object 10 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 11 0 R
+>>
+endobj
+{{object 11 0}} <<
+  {{streamlen}}
+>>
+stream
+{{include expect.js}}
+expect("this.__proto__", "[object Object]");
+expect("app.__proto__", "[object Object]");
+expectError("this.__proto__ = {}");
+expectError("app.__proto__ = this");
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/immutable_proto_expected.txt b/testing/resources/javascript/immutable_proto_expected.txt
new file mode 100644
index 0000000..7e7c670
--- /dev/null
+++ b/testing/resources/javascript/immutable_proto_expected.txt
@@ -0,0 +1,4 @@
+Alert: PASS: this.__proto__ = [object Object]
+Alert: PASS: app.__proto__ = [object Object]
+Alert: PASS: this.__proto__ = {} threw TypeError: Immutable prototype object '[object global]' cannot have their prototype set
+Alert: PASS: app.__proto__ = this threw TypeError: Immutable prototype object '[object Object]' cannot have their prototype set