Tolerate empty local in JS_DateParse().

Return early, and let the error that triggered the empty local
propogate to whatever may catch it.

- Rewrite to use early returns
- Prefer As<>() when previously tested with Is*()

Bug: chromium:1142688
Change-Id: Iffe11bb0d75f61a6bf42f39beb37c9cb2de157a0
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/75790
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/js_define.cpp b/fxjs/js_define.cpp
index 352370f..2bc1284 100644
--- a/fxjs/js_define.cpp
+++ b/fxjs/js_define.cpp
@@ -29,30 +29,29 @@
   v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
 
   // Use the built-in object method.
-  v8::Local<v8::Value> v =
-      context->Global()
-          ->Get(context, fxv8::NewStringHelper(pIsolate, "Date"))
-          .ToLocalChecked();
-  if (v->IsObject()) {
-    v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
-    v = o->Get(context, fxv8::NewStringHelper(pIsolate, "parse"))
-            .ToLocalChecked();
-    if (v->IsFunction()) {
-      v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
-      const int argc = 1;
-      v8::Local<v8::String> timeStr =
-          fxv8::NewStringHelper(pIsolate, str.AsStringView());
-      v8::Local<v8::Value> argv[argc] = {timeStr};
-      v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
-      if (v->IsNumber()) {
-        double date = v->ToNumber(context).ToLocalChecked()->Value();
-        if (!std::isfinite(date))
-          return date;
-        return FX_LocalTime(date);
-      }
-    }
-  }
-  return 0;
+  v8::MaybeLocal<v8::Value> maybe_value =
+      context->Global()->Get(context, fxv8::NewStringHelper(pIsolate, "Date"));
+
+  v8::Local<v8::Value> value;
+  if (!maybe_value.ToLocal(&value) || !value->IsObject())
+    return 0;
+
+  v8::Local<v8::Object> obj = value.As<v8::Object>();
+  maybe_value = obj->Get(context, fxv8::NewStringHelper(pIsolate, "parse"));
+  if (!maybe_value.ToLocal(&value) || !value->IsFunction())
+    return 0;
+
+  v8::Local<v8::Function> func = value.As<v8::Function>();
+  static constexpr int argc = 1;
+  v8::Local<v8::Value> argv[argc] = {
+      fxv8::NewStringHelper(pIsolate, str.AsStringView()),
+  };
+  maybe_value = func->Call(context, context->Global(), argc, argv);
+  if (!maybe_value.ToLocal(&value) || !value->IsNumber())
+    return 0;
+
+  double date = value.As<v8::Number>()->Value();
+  return std::isfinite(date) ? FX_LocalTime(date) : date;
 }
 
 std::vector<v8::Local<v8::Value>> ExpandKeywordParams(
diff --git a/testing/resources/javascript/bug_1142688.in b/testing/resources/javascript/bug_1142688.in
new file mode 100644
index 0000000..6d3825d
--- /dev/null
+++ b/testing/resources/javascript/bug_1142688.in
@@ -0,0 +1,78 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 5 0 R
+  /AcroForm <<
+    /Fields [
+      3 0 R
+      2 0 R
+    ]
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /T (tf1)
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /T (tf0)
+  /AA <<
+    /F 10 0 R
+  >>
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Pages
+  /Count 2
+  /Kids [
+    8 0 R
+    9 0 R
+  ]
+>>
+endobj
+{{object 8 0}} <<
+  /Type /Page
+  /Parent 5 0 R
+  /Annots [3 0 R]
+>>
+endobj
+{{object 9 0}} <<
+  /Type /Page
+  /Parent 5 0 R
+  /Annots [2 0 R]
+>>
+endobj
+{{object 10 0}} <<
+  /Type /Action
+  /S /JavaScript
+  /JS 13 0 R
+>>
+{{object 13 0}} <<
+  {{streamlen}}
+>>
+stream
+function f3() {
+  // Setup dubious values in event recorder.
+  try { AFSpecial_Format(2); } catch(e) {}
+  try { AFNumber_Format(-302907477,0,1,-6,"",true); } catch(e) {}
+
+  // Exhaust call stack, then do work upon exiting each frame. The
+  // objective is to get any call() made under the covers to throw
+  // with a stack size exception.
+  try { f3(); } catch(e) {}
+  try { AFDate_Keystroke("yymm-dd"); } catch(e) {}
+}
+f3();
+app.alert('Done.');
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/bug_1142688_expected.txt b/testing/resources/javascript/bug_1142688_expected.txt
new file mode 100644
index 0000000..7cb32ca
--- /dev/null
+++ b/testing/resources/javascript/bug_1142688_expected.txt
@@ -0,0 +1 @@
+Alert: Done.