Make CFXJSE-created contexts refer to their CFXJS counteparts.

Bug: 773229
Change-Id: Ic3774c7f6abe3a195bbe09b91d91c549d4d7ac46
Reviewed-on: https://pdfium-review.googlesource.com/25110
Reviewed-by: dsinclair <dsinclair@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/fpdfview_embeddertest.cpp b/fpdfsdk/fpdfview_embeddertest.cpp
index cca77c9..47d0223 100644
--- a/fpdfsdk/fpdfview_embeddertest.cpp
+++ b/fpdfsdk/fpdfview_embeddertest.cpp
@@ -347,6 +347,10 @@
   EXPECT_FALSE(OpenDocument("bug_298.pdf"));
 }
 
+TEST_F(FPDFViewEmbeddertest, Crasher_773229) {
+  EXPECT_TRUE(OpenDocument("bug_773229.pdf"));
+}
+
 // Test if the document opens without infinite looping.
 // Previously this test will hang in a loop inside LoadAllCrossRefV4. After
 // the fix, LoadAllCrossRefV4 will return false after detecting a cross
diff --git a/fxjs/cfxjse_context.cpp b/fxjs/cfxjse_context.cpp
index 3ec3b47..e2a0540 100644
--- a/fxjs/cfxjse_context.cpp
+++ b/fxjs/cfxjse_context.cpp
@@ -10,6 +10,7 @@
 
 #include "fxjs/cfxjse_class.h"
 #include "fxjs/cfxjse_value.h"
+#include "fxjs/fxjs_v8.h"
 #include "third_party/base/ptr_util.h"
 
 namespace {
@@ -159,10 +160,12 @@
 // static
 std::unique_ptr<CFXJSE_Context> CFXJSE_Context::Create(
     v8::Isolate* pIsolate,
+    CFXJS_Engine* pOptionalEngineToSet,
     const FXJSE_CLASS_DESCRIPTOR* pGlobalClass,
     CFXJSE_HostObject* pGlobalObject) {
   CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
   auto pContext = pdfium::MakeUnique<CFXJSE_Context>(pIsolate);
+
   v8::Local<v8::ObjectTemplate> hObjectTemplate;
   if (pGlobalClass) {
     CFXJSE_Class* pGlobalClassObj =
@@ -176,18 +179,23 @@
     hObjectTemplate = v8::ObjectTemplate::New(pIsolate);
     hObjectTemplate->SetInternalFieldCount(2);
   }
-
   hObjectTemplate->Set(
       v8::Symbol::GetToStringTag(pIsolate),
       v8::String::NewFromUtf8(pIsolate, "global", v8::NewStringType::kNormal)
           .ToLocalChecked());
+
   v8::Local<v8::Context> hNewContext =
       v8::Context::New(pIsolate, nullptr, hObjectTemplate);
+
   v8::Local<v8::Context> hRootContext = v8::Local<v8::Context>::New(
       pIsolate, CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext);
   hNewContext->SetSecurityToken(hRootContext->GetSecurityToken());
+
   v8::Local<v8::Object> hGlobalObject = GetGlobalObjectFromContext(hNewContext);
   FXJSE_UpdateObjectBinding(hGlobalObject, pGlobalObject);
+  if (pOptionalEngineToSet)
+    CFXJS_Engine::SetEngineInContext(pOptionalEngineToSet, hNewContext);
+
   pContext->m_hContext.Reset(pIsolate, hNewContext);
   return pContext;
 }
diff --git a/fxjs/cfxjse_context.h b/fxjs/cfxjse_context.h
index c6949fc..0f4c97a 100644
--- a/fxjs/cfxjse_context.h
+++ b/fxjs/cfxjse_context.h
@@ -13,6 +13,7 @@
 #include "fxjs/fxjse.h"
 #include "v8/include/v8.h"
 
+class CFXJS_Engine;
 class CFXJSE_Class;
 class CFXJSE_Value;
 struct FXJSE_CLASS_DESCRIPTOR;
@@ -21,6 +22,7 @@
  public:
   static std::unique_ptr<CFXJSE_Context> Create(
       v8::Isolate* pIsolate,
+      CFXJS_Engine* pOptionalEngineToSet,
       const FXJSE_CLASS_DESCRIPTOR* pGlobalClass,
       CFXJSE_HostObject* pGlobalObject);
 
diff --git a/fxjs/cfxjse_engine.cpp b/fxjs/cfxjse_engine.cpp
index 6b3ea10..198e1d5 100644
--- a/fxjs/cfxjse_engine.cpp
+++ b/fxjs/cfxjse_engine.cpp
@@ -97,6 +97,7 @@
     : CJS_V8(fxjs_engine->GetIsolate()),
       m_pDocument(pDocument),
       m_JsContext(CFXJSE_Context::Create(fxjs_engine->GetIsolate(),
+                                         fxjs_engine,
                                          &GlobalClassDescriptor,
                                          pDocument->GetRoot())),
       m_pJsClass(nullptr),
@@ -431,7 +432,7 @@
     return nullptr;
 
   auto pNewContext =
-      CFXJSE_Context::Create(GetIsolate(), &VariablesClassDescriptor,
+      CFXJSE_Context::Create(GetIsolate(), nullptr, &VariablesClassDescriptor,
                              new CXFA_ThisProxy(pSubform, pScriptNode));
   RemoveBuiltInObjs(pNewContext.get());
   pNewContext->EnableCompatibleMode();
diff --git a/fxjs/cfxjse_formcalc_context.cpp b/fxjs/cfxjse_formcalc_context.cpp
index c46b9a6..3306cd9 100644
--- a/fxjs/cfxjse_formcalc_context.cpp
+++ b/fxjs/cfxjse_formcalc_context.cpp
@@ -2834,7 +2834,7 @@
   }
 
   std::unique_ptr<CFXJSE_Context> pNewContext(
-      CFXJSE_Context::Create(pIsolate, nullptr, nullptr));
+      CFXJSE_Context::Create(pIsolate, nullptr, nullptr, nullptr));
 
   auto returnValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate);
   pNewContext->ExecuteScript(
diff --git a/testing/resources/bug_773229.pdf b/testing/resources/bug_773229.pdf
new file mode 100644
index 0000000..5f34a1a
--- /dev/null
+++ b/testing/resources/bug_773229.pdf
@@ -0,0 +1,78 @@
+%PDF-1.7

+1 0 obj

+<<

+    /Type /Catalog

+    /Pages 2 0 R

+    /AcroForm 4 0 R

+>>

+endobj

+2 0 obj

+<<

+    /Type /Pages

+    /Count 1

+    /Kids [3 0 R]

+>>

+endobj

+3 0 obj

+<<

+    /Type /Page

+    /Parent 2 0 R

+>>

+endobj

+4 0 obj

+<<

+    /XFA [

+        (xdp:xdp) 5 0 R

+        (form) 6 0 R

+        (</xdp:xdp>) 7 0 R

+    ]

+>>

+endobj

+5 0 obj

+<< >>

+stream

+<?xml version="1.0" encoding="UTF-8"?>

+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">

+endstream

+endobj

+6 0 obj

+<< >>

+stream

+<config></config>

+<?xml version="1.0"?>

+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">

+    <subform>

+        <field name="field1">

+            <event activity="docReady">

+                <script contentType="application/x-javascript">

+                    app.alert(app.runtimeHighlight);

+                </script>

+            </event>

+        </field>

+    </subform>

+</template>

+endstream

+endobj

+7 0 obj

+<< >>

+stream

+</xdp:xdp>

+endstream

+endobj

+xref

+0 8

+0000000000 65535 f

+0000000010 00000 n

+0000000094 00000 n

+0000000170 00000 n

+0000000231 00000 n

+0000000350 00000 n

+0000000481 00000 n

+0000002637 00000 n

+trailer

+<<

+    /Root 1 0 R

+>>

+startxref

+2692

+%%EOF
\ No newline at end of file