blob: f4ed6112b011f26066c3780839c56f89e7c282fa [file] [log] [blame]
K. Moon832a6942022-10-31 20:11:31 +00001// Copyright 2019 The PDFium Authors
Lei Zhang72e8b692019-02-05 19:16:52 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "testing/v8_initializer.h"
6
Felix Kauselmann5fe85692019-02-11 20:55:52 +00007#include <cstring>
8
Lei Zhangb6992dd2019-02-05 23:30:20 +00009#include "public/fpdfview.h"
10#include "testing/utils/file_util.h"
Lei Zhang72e8b692019-02-05 19:16:52 +000011#include "testing/utils/path_service.h"
Tom Sepezea03a7b2022-02-24 00:30:14 +000012#include "third_party/base/numerics/safe_conversions.h"
Lei Zhang72e8b692019-02-05 19:16:52 +000013#include "v8/include/libplatform/libplatform.h"
Lei Zhangbfcf1562022-07-07 01:49:26 +000014#include "v8/include/v8-initialization.h"
15#include "v8/include/v8-snapshot.h"
Lei Zhang72e8b692019-02-05 19:16:52 +000016
Tom Sepez30eddfa2021-02-16 19:24:00 +000017#ifdef PDF_ENABLE_XFA
18#include "v8/include/cppgc/platform.h"
19#endif
20
Lei Zhang72e8b692019-02-05 19:16:52 +000021namespace {
22
23#ifdef V8_USE_EXTERNAL_STARTUP_DATA
24// Returns the full path for an external V8 data file based on either
25// the currect exectuable path or an explicit override.
26std::string GetFullPathForSnapshotFile(const std::string& exe_path,
27 const std::string& bin_dir,
28 const std::string& filename) {
29 std::string result;
30 if (!bin_dir.empty()) {
31 result = bin_dir;
32 if (*bin_dir.rbegin() != PATH_SEPARATOR) {
33 result += PATH_SEPARATOR;
34 }
35 } else if (!exe_path.empty()) {
36 size_t last_separator = exe_path.rfind(PATH_SEPARATOR);
37 if (last_separator != std::string::npos) {
38 result = exe_path.substr(0, last_separator + 1);
39 }
40 }
41 result += filename;
42 return result;
43}
44
45bool GetExternalData(const std::string& exe_path,
46 const std::string& bin_dir,
47 const std::string& filename,
48 v8::StartupData* result_data) {
49 std::string full_path =
50 GetFullPathForSnapshotFile(exe_path, bin_dir, filename);
51 size_t data_length = 0;
52 std::unique_ptr<char, pdfium::FreeDeleter> data_buffer =
53 GetFileContents(full_path.c_str(), &data_length);
54 if (!data_buffer)
55 return false;
56
57 result_data->data = data_buffer.release();
Tom Sepezea03a7b2022-02-24 00:30:14 +000058 result_data->raw_size = pdfium::base::checked_cast<int>(data_length);
Lei Zhang72e8b692019-02-05 19:16:52 +000059 return true;
60}
61#endif // V8_USE_EXTERNAL_STARTUP_DATA
62
Tom Sepeze0d3c502020-08-11 23:51:10 +000063std::unique_ptr<v8::Platform> InitializeV8Common(const std::string& exe_path,
64 const std::string& js_flags) {
Lei Zhang72e8b692019-02-05 19:16:52 +000065 v8::V8::InitializeICUDefaultLocation(exe_path.c_str());
66
67 std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
68 v8::V8::InitializePlatform(platform.get());
Tom Sepez30eddfa2021-02-16 19:24:00 +000069#ifdef PDF_ENABLE_XFA
70 cppgc::InitializeProcess(platform->GetPageAllocator());
71#endif
Lei Zhang72e8b692019-02-05 19:16:52 +000072
73 const char* recommended_v8_flags = FPDF_GetRecommendedV8Flags();
Lei Zhang06d1acb2019-05-04 07:40:40 +000074 v8::V8::SetFlagsFromString(recommended_v8_flags);
Lei Zhang72e8b692019-02-05 19:16:52 +000075
Tom Sepeze0d3c502020-08-11 23:51:10 +000076 if (!js_flags.empty())
77 v8::V8::SetFlagsFromString(js_flags.c_str());
78
Lei Zhang72e8b692019-02-05 19:16:52 +000079 // By enabling predictable mode, V8 won't post any background tasks.
80 // By enabling GC, it makes it easier to chase use-after-free.
81 static const char kAdditionalV8Flags[] = "--predictable --expose-gc";
Lei Zhang06d1acb2019-05-04 07:40:40 +000082 v8::V8::SetFlagsFromString(kAdditionalV8Flags);
Lei Zhang72e8b692019-02-05 19:16:52 +000083
84 v8::V8::Initialize();
85 return platform;
86}
87
88} // namespace
89
90#ifdef V8_USE_EXTERNAL_STARTUP_DATA
91std::unique_ptr<v8::Platform> InitializeV8ForPDFiumWithStartupData(
92 const std::string& exe_path,
Tom Sepeze0d3c502020-08-11 23:51:10 +000093 const std::string& js_flags,
Lei Zhang72e8b692019-02-05 19:16:52 +000094 const std::string& bin_dir,
Lei Zhang72e8b692019-02-05 19:16:52 +000095 v8::StartupData* snapshot_blob) {
Tom Sepeze0d3c502020-08-11 23:51:10 +000096 std::unique_ptr<v8::Platform> platform =
97 InitializeV8Common(exe_path, js_flags);
Lei Zhanga8e8baf2019-10-08 17:53:04 +000098 if (snapshot_blob) {
Lei Zhang72e8b692019-02-05 19:16:52 +000099 if (!GetExternalData(exe_path, bin_dir, "snapshot_blob.bin", snapshot_blob))
100 return nullptr;
Lei Zhang72e8b692019-02-05 19:16:52 +0000101 v8::V8::SetSnapshotDataBlob(snapshot_blob);
102 }
103 return platform;
104}
105#else // V8_USE_EXTERNAL_STARTUP_DATA
106std::unique_ptr<v8::Platform> InitializeV8ForPDFium(
Tom Sepeze0d3c502020-08-11 23:51:10 +0000107 const std::string& exe_path,
108 const std::string& js_flags) {
109 return InitializeV8Common(exe_path, js_flags);
Lei Zhang72e8b692019-02-05 19:16:52 +0000110}
111#endif // V8_USE_EXTERNAL_STARTUP_DATA
Tom Sepez30eddfa2021-02-16 19:24:00 +0000112
113void ShutdownV8ForPDFium() {
114#ifdef PDF_ENABLE_XFA
115 cppgc::ShutdownProcess();
116#endif
Tom Sepeze506d562022-01-24 20:52:53 +0000117 v8::V8::Dispose();
Alan Screen5e30ae82021-12-01 23:08:27 +0000118 v8::V8::DisposePlatform();
Tom Sepez30eddfa2021-02-16 19:24:00 +0000119}