xref: /aosp_15_r20/external/pdfium/testing/v8_initializer.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2019 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker #include "testing/v8_initializer.h"
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #include <cstring>
8*3ac0a46fSAndroid Build Coastguard Worker 
9*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdfview.h"
10*3ac0a46fSAndroid Build Coastguard Worker #include "testing/utils/file_util.h"
11*3ac0a46fSAndroid Build Coastguard Worker #include "testing/utils/path_service.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/numerics/safe_conversions.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/libplatform/libplatform.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-initialization.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-snapshot.h"
16*3ac0a46fSAndroid Build Coastguard Worker 
17*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
18*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/cppgc/platform.h"
19*3ac0a46fSAndroid Build Coastguard Worker #endif
20*3ac0a46fSAndroid Build Coastguard Worker 
21*3ac0a46fSAndroid Build Coastguard Worker namespace {
22*3ac0a46fSAndroid Build Coastguard Worker 
23*3ac0a46fSAndroid Build Coastguard Worker #ifdef V8_USE_EXTERNAL_STARTUP_DATA
24*3ac0a46fSAndroid Build Coastguard Worker // Returns the full path for an external V8 data file based on either
25*3ac0a46fSAndroid Build Coastguard Worker // the currect exectuable path or an explicit override.
GetFullPathForSnapshotFile(const std::string & exe_path,const std::string & bin_dir,const std::string & filename)26*3ac0a46fSAndroid Build Coastguard Worker std::string GetFullPathForSnapshotFile(const std::string& exe_path,
27*3ac0a46fSAndroid Build Coastguard Worker                                        const std::string& bin_dir,
28*3ac0a46fSAndroid Build Coastguard Worker                                        const std::string& filename) {
29*3ac0a46fSAndroid Build Coastguard Worker   std::string result;
30*3ac0a46fSAndroid Build Coastguard Worker   if (!bin_dir.empty()) {
31*3ac0a46fSAndroid Build Coastguard Worker     result = bin_dir;
32*3ac0a46fSAndroid Build Coastguard Worker     if (*bin_dir.rbegin() != PATH_SEPARATOR) {
33*3ac0a46fSAndroid Build Coastguard Worker       result += PATH_SEPARATOR;
34*3ac0a46fSAndroid Build Coastguard Worker     }
35*3ac0a46fSAndroid Build Coastguard Worker   } else if (!exe_path.empty()) {
36*3ac0a46fSAndroid Build Coastguard Worker     size_t last_separator = exe_path.rfind(PATH_SEPARATOR);
37*3ac0a46fSAndroid Build Coastguard Worker     if (last_separator != std::string::npos) {
38*3ac0a46fSAndroid Build Coastguard Worker       result = exe_path.substr(0, last_separator + 1);
39*3ac0a46fSAndroid Build Coastguard Worker     }
40*3ac0a46fSAndroid Build Coastguard Worker   }
41*3ac0a46fSAndroid Build Coastguard Worker   result += filename;
42*3ac0a46fSAndroid Build Coastguard Worker   return result;
43*3ac0a46fSAndroid Build Coastguard Worker }
44*3ac0a46fSAndroid Build Coastguard Worker 
GetExternalData(const std::string & exe_path,const std::string & bin_dir,const std::string & filename,v8::StartupData * result_data)45*3ac0a46fSAndroid Build Coastguard Worker bool GetExternalData(const std::string& exe_path,
46*3ac0a46fSAndroid Build Coastguard Worker                      const std::string& bin_dir,
47*3ac0a46fSAndroid Build Coastguard Worker                      const std::string& filename,
48*3ac0a46fSAndroid Build Coastguard Worker                      v8::StartupData* result_data) {
49*3ac0a46fSAndroid Build Coastguard Worker   std::string full_path =
50*3ac0a46fSAndroid Build Coastguard Worker       GetFullPathForSnapshotFile(exe_path, bin_dir, filename);
51*3ac0a46fSAndroid Build Coastguard Worker   size_t data_length = 0;
52*3ac0a46fSAndroid Build Coastguard Worker   std::unique_ptr<char, pdfium::FreeDeleter> data_buffer =
53*3ac0a46fSAndroid Build Coastguard Worker       GetFileContents(full_path.c_str(), &data_length);
54*3ac0a46fSAndroid Build Coastguard Worker   if (!data_buffer)
55*3ac0a46fSAndroid Build Coastguard Worker     return false;
56*3ac0a46fSAndroid Build Coastguard Worker 
57*3ac0a46fSAndroid Build Coastguard Worker   result_data->data = data_buffer.release();
58*3ac0a46fSAndroid Build Coastguard Worker   result_data->raw_size = pdfium::base::checked_cast<int>(data_length);
59*3ac0a46fSAndroid Build Coastguard Worker   return true;
60*3ac0a46fSAndroid Build Coastguard Worker }
61*3ac0a46fSAndroid Build Coastguard Worker #endif  // V8_USE_EXTERNAL_STARTUP_DATA
62*3ac0a46fSAndroid Build Coastguard Worker 
InitializeV8Common(const std::string & exe_path,const std::string & js_flags)63*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<v8::Platform> InitializeV8Common(const std::string& exe_path,
64*3ac0a46fSAndroid Build Coastguard Worker                                                  const std::string& js_flags) {
65*3ac0a46fSAndroid Build Coastguard Worker   v8::V8::InitializeICUDefaultLocation(exe_path.c_str());
66*3ac0a46fSAndroid Build Coastguard Worker 
67*3ac0a46fSAndroid Build Coastguard Worker   std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
68*3ac0a46fSAndroid Build Coastguard Worker   v8::V8::InitializePlatform(platform.get());
69*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
70*3ac0a46fSAndroid Build Coastguard Worker   cppgc::InitializeProcess(platform->GetPageAllocator());
71*3ac0a46fSAndroid Build Coastguard Worker #endif
72*3ac0a46fSAndroid Build Coastguard Worker 
73*3ac0a46fSAndroid Build Coastguard Worker   const char* recommended_v8_flags = FPDF_GetRecommendedV8Flags();
74*3ac0a46fSAndroid Build Coastguard Worker   v8::V8::SetFlagsFromString(recommended_v8_flags);
75*3ac0a46fSAndroid Build Coastguard Worker 
76*3ac0a46fSAndroid Build Coastguard Worker   if (!js_flags.empty())
77*3ac0a46fSAndroid Build Coastguard Worker     v8::V8::SetFlagsFromString(js_flags.c_str());
78*3ac0a46fSAndroid Build Coastguard Worker 
79*3ac0a46fSAndroid Build Coastguard Worker   // By enabling predictable mode, V8 won't post any background tasks.
80*3ac0a46fSAndroid Build Coastguard Worker   // By enabling GC, it makes it easier to chase use-after-free.
81*3ac0a46fSAndroid Build Coastguard Worker   static const char kAdditionalV8Flags[] = "--predictable --expose-gc";
82*3ac0a46fSAndroid Build Coastguard Worker   v8::V8::SetFlagsFromString(kAdditionalV8Flags);
83*3ac0a46fSAndroid Build Coastguard Worker 
84*3ac0a46fSAndroid Build Coastguard Worker   v8::V8::Initialize();
85*3ac0a46fSAndroid Build Coastguard Worker   return platform;
86*3ac0a46fSAndroid Build Coastguard Worker }
87*3ac0a46fSAndroid Build Coastguard Worker 
88*3ac0a46fSAndroid Build Coastguard Worker }  // namespace
89*3ac0a46fSAndroid Build Coastguard Worker 
90*3ac0a46fSAndroid Build Coastguard Worker #ifdef V8_USE_EXTERNAL_STARTUP_DATA
InitializeV8ForPDFiumWithStartupData(const std::string & exe_path,const std::string & js_flags,const std::string & bin_dir,v8::StartupData * snapshot_blob)91*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<v8::Platform> InitializeV8ForPDFiumWithStartupData(
92*3ac0a46fSAndroid Build Coastguard Worker     const std::string& exe_path,
93*3ac0a46fSAndroid Build Coastguard Worker     const std::string& js_flags,
94*3ac0a46fSAndroid Build Coastguard Worker     const std::string& bin_dir,
95*3ac0a46fSAndroid Build Coastguard Worker     v8::StartupData* snapshot_blob) {
96*3ac0a46fSAndroid Build Coastguard Worker   std::unique_ptr<v8::Platform> platform =
97*3ac0a46fSAndroid Build Coastguard Worker       InitializeV8Common(exe_path, js_flags);
98*3ac0a46fSAndroid Build Coastguard Worker   if (snapshot_blob) {
99*3ac0a46fSAndroid Build Coastguard Worker     if (!GetExternalData(exe_path, bin_dir, "snapshot_blob.bin", snapshot_blob))
100*3ac0a46fSAndroid Build Coastguard Worker       return nullptr;
101*3ac0a46fSAndroid Build Coastguard Worker     v8::V8::SetSnapshotDataBlob(snapshot_blob);
102*3ac0a46fSAndroid Build Coastguard Worker   }
103*3ac0a46fSAndroid Build Coastguard Worker   return platform;
104*3ac0a46fSAndroid Build Coastguard Worker }
105*3ac0a46fSAndroid Build Coastguard Worker #else   // V8_USE_EXTERNAL_STARTUP_DATA
InitializeV8ForPDFium(const std::string & exe_path,const std::string & js_flags)106*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<v8::Platform> InitializeV8ForPDFium(
107*3ac0a46fSAndroid Build Coastguard Worker     const std::string& exe_path,
108*3ac0a46fSAndroid Build Coastguard Worker     const std::string& js_flags) {
109*3ac0a46fSAndroid Build Coastguard Worker   return InitializeV8Common(exe_path, js_flags);
110*3ac0a46fSAndroid Build Coastguard Worker }
111*3ac0a46fSAndroid Build Coastguard Worker #endif  // V8_USE_EXTERNAL_STARTUP_DATA
112*3ac0a46fSAndroid Build Coastguard Worker 
ShutdownV8ForPDFium()113*3ac0a46fSAndroid Build Coastguard Worker void ShutdownV8ForPDFium() {
114*3ac0a46fSAndroid Build Coastguard Worker #ifdef PDF_ENABLE_XFA
115*3ac0a46fSAndroid Build Coastguard Worker   cppgc::ShutdownProcess();
116*3ac0a46fSAndroid Build Coastguard Worker #endif
117*3ac0a46fSAndroid Build Coastguard Worker   v8::V8::Dispose();
118*3ac0a46fSAndroid Build Coastguard Worker   v8::V8::DisposePlatform();
119*3ac0a46fSAndroid Build Coastguard Worker }
120