Allow setting v8 flags from pdfium_test command line.

This feature might have been useful in debugging a recent V8
debug CHECK(). Uses the same flag name as chrome does for this
option.

Change-Id: I262bcb091dd1c72e052f6750a24055adc0893cf3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/72672
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index 2011f8a..67f16fd 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -125,6 +125,7 @@
   bool save_thumbnails_raw = false;
 #ifdef PDF_ENABLE_V8
   bool disable_javascript = false;
+  std::string js_flags;  // Extra flags to pass to v8 init.
 #ifdef PDF_ENABLE_XFA
   bool disable_xfa = false;
 #endif  // PDF_ENABLE_XFA
@@ -475,6 +476,12 @@
 #ifdef PDF_ENABLE_V8
     } else if (cur_arg == "--disable-javascript") {
       options->disable_javascript = true;
+    } else if (ParseSwitchKeyValue(cur_arg, "--js-flags=", &value)) {
+      if (!options->js_flags.empty()) {
+        fprintf(stderr, "Duplicate --js-flags argument\n");
+        return false;
+      }
+      options->js_flags = value;
 #ifdef PDF_ENABLE_XFA
     } else if (cur_arg == "--disable-xfa") {
       options->disable_xfa = true;
@@ -1094,6 +1101,7 @@
     "<pdf-name>.thumbnail.raw.<page-number>.png\n"
 #ifdef PDF_ENABLE_V8
     "  --disable-javascript   - do not execute JS in PDF files\n"
+    "  --js-flags=<flags>     - additional flags to pas to V8"
 #ifdef PDF_ENABLE_XFA
     "  --disable-xfa          - do not process XFA forms\n"
 #endif  // PDF_ENABLE_XFA
@@ -1166,9 +1174,9 @@
   if (!options.disable_javascript) {
 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
     platform = InitializeV8ForPDFiumWithStartupData(
-        options.exe_path, options.bin_directory, &snapshot);
+        options.exe_path, options.js_flags, options.bin_directory, &snapshot);
 #else   // V8_USE_EXTERNAL_STARTUP_DATA
-    platform = InitializeV8ForPDFium(options.exe_path);
+    platform = InitializeV8ForPDFium(options.exe_path, options.js_flags);
 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
     config.m_pPlatform = platform.get();
 
diff --git a/testing/fuzzers/pdf_fuzzer_init_public.cc b/testing/fuzzers/pdf_fuzzer_init_public.cc
index 5ece0bc..0ced636 100644
--- a/testing/fuzzers/pdf_fuzzer_init_public.cc
+++ b/testing/fuzzers/pdf_fuzzer_init_public.cc
@@ -62,9 +62,9 @@
 #ifdef PDF_ENABLE_V8
 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
     platform = InitializeV8ForPDFiumWithStartupData(
-        ProgramPath(), std::string(), &snapshot_blob);
+        ProgramPath(), std::string(), std::string(), &snapshot_blob);
 #else
-    platform = InitializeV8ForPDFium(ProgramPath());
+    platform = InitializeV8ForPDFium(ProgramPath(), std::string());
 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
 #endif  // PDF_ENABLE_V8
 
diff --git a/testing/v8_initializer.cpp b/testing/v8_initializer.cpp
index 8564b2e..29d6e55 100644
--- a/testing/v8_initializer.cpp
+++ b/testing/v8_initializer.cpp
@@ -54,7 +54,8 @@
 }
 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
 
-std::unique_ptr<v8::Platform> InitializeV8Common(const std::string& exe_path) {
+std::unique_ptr<v8::Platform> InitializeV8Common(const std::string& exe_path,
+                                                 const std::string& js_flags) {
   v8::V8::InitializeICUDefaultLocation(exe_path.c_str());
 
   std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
@@ -63,6 +64,9 @@
   const char* recommended_v8_flags = FPDF_GetRecommendedV8Flags();
   v8::V8::SetFlagsFromString(recommended_v8_flags);
 
+  if (!js_flags.empty())
+    v8::V8::SetFlagsFromString(js_flags.c_str());
+
   // By enabling predictable mode, V8 won't post any background tasks.
   // By enabling GC, it makes it easier to chase use-after-free.
   static const char kAdditionalV8Flags[] = "--predictable --expose-gc";
@@ -77,9 +81,11 @@
 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
 std::unique_ptr<v8::Platform> InitializeV8ForPDFiumWithStartupData(
     const std::string& exe_path,
+    const std::string& js_flags,
     const std::string& bin_dir,
     v8::StartupData* snapshot_blob) {
-  std::unique_ptr<v8::Platform> platform = InitializeV8Common(exe_path);
+  std::unique_ptr<v8::Platform> platform =
+      InitializeV8Common(exe_path, js_flags);
   if (snapshot_blob) {
     if (!GetExternalData(exe_path, bin_dir, "snapshot_blob.bin", snapshot_blob))
       return nullptr;
@@ -89,7 +95,8 @@
 }
 #else   // V8_USE_EXTERNAL_STARTUP_DATA
 std::unique_ptr<v8::Platform> InitializeV8ForPDFium(
-    const std::string& exe_path) {
-  return InitializeV8Common(exe_path);
+    const std::string& exe_path,
+    const std::string& js_flags) {
+  return InitializeV8Common(exe_path, js_flags);
 }
 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
diff --git a/testing/v8_initializer.h b/testing/v8_initializer.h
index bd2301c..2f4c3c5 100644
--- a/testing/v8_initializer.h
+++ b/testing/v8_initializer.h
@@ -23,10 +23,12 @@
 // |snapshot_blob| is an optional out parameter.
 std::unique_ptr<v8::Platform> InitializeV8ForPDFiumWithStartupData(
     const std::string& exe_path,
+    const std::string& js_flags,
     const std::string& bin_dir,
     v8::StartupData* snapshot_blob);
 #else
 std::unique_ptr<v8::Platform> InitializeV8ForPDFium(
+    const std::string& js_flags,
     const std::string& exe_path);
 #endif
 
diff --git a/testing/v8_test_environment.cpp b/testing/v8_test_environment.cpp
index 08a8840..78cc453 100644
--- a/testing/v8_test_environment.cpp
+++ b/testing/v8_test_environment.cpp
@@ -49,12 +49,12 @@
 void V8TestEnvironment::SetUp() {
 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
   if (v8_snapshot_) {
-    platform_ =
-        InitializeV8ForPDFiumWithStartupData(exe_path_, std::string(), nullptr);
+    platform_ = InitializeV8ForPDFiumWithStartupData(exe_path_, std::string(),
+                                                     std::string(), nullptr);
   } else {
     v8_snapshot_ = std::make_unique<v8::StartupData>();
-    platform_ = InitializeV8ForPDFiumWithStartupData(exe_path_, std::string(),
-                                                     v8_snapshot_.get());
+    platform_ = InitializeV8ForPDFiumWithStartupData(
+        exe_path_, std::string(), std::string(), v8_snapshot_.get());
   }
 #else
   platform_ = InitializeV8ForPDFium(exe_path_);