blob: 613226fa4f9396b2e454b6df6e4a2a79ef74dc60 [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
Lei Zhang4da226a2023-11-10 20:15:43 +00007#include <stdlib.h>
8
Felix Kauselmann5fe85692019-02-11 20:55:52 +00009#include <cstring>
Lei Zhang4da226a2023-11-10 20:15:43 +000010#include <vector>
Felix Kauselmann5fe85692019-02-11 20:55:52 +000011
Tom Sepezfb6e3552024-05-07 18:15:23 +000012#include "core/fxcrt/fx_memcpy_wrappers.h"
Lei Zhangf36006c2024-02-17 00:56:24 +000013#include "core/fxcrt/numerics/safe_conversions.h"
Lei Zhangb6992dd2019-02-05 23:30:20 +000014#include "public/fpdfview.h"
15#include "testing/utils/file_util.h"
Lei Zhang72e8b692019-02-05 19:16:52 +000016#include "testing/utils/path_service.h"
17#include "v8/include/libplatform/libplatform.h"
Lei Zhangbfcf1562022-07-07 01:49:26 +000018#include "v8/include/v8-initialization.h"
19#include "v8/include/v8-snapshot.h"
Lei Zhang72e8b692019-02-05 19:16:52 +000020
Tom Sepez30eddfa2021-02-16 19:24:00 +000021#ifdef PDF_ENABLE_XFA
22#include "v8/include/cppgc/platform.h"
23#endif
24
Lei Zhang72e8b692019-02-05 19:16:52 +000025namespace {
26
27#ifdef V8_USE_EXTERNAL_STARTUP_DATA
28// Returns the full path for an external V8 data file based on either
29// the currect exectuable path or an explicit override.
30std::string GetFullPathForSnapshotFile(const std::string& exe_path,
31 const std::string& bin_dir,
32 const std::string& filename) {
33 std::string result;
34 if (!bin_dir.empty()) {
35 result = bin_dir;
36 if (*bin_dir.rbegin() != PATH_SEPARATOR) {
37 result += PATH_SEPARATOR;
38 }
39 } else if (!exe_path.empty()) {
40 size_t last_separator = exe_path.rfind(PATH_SEPARATOR);
41 if (last_separator != std::string::npos) {
42 result = exe_path.substr(0, last_separator + 1);
43 }
44 }
45 result += filename;
46 return result;
47}
48
49bool GetExternalData(const std::string& exe_path,
50 const std::string& bin_dir,
51 const std::string& filename,
52 v8::StartupData* result_data) {
53 std::string full_path =
54 GetFullPathForSnapshotFile(exe_path, bin_dir, filename);
Lei Zhang4da226a2023-11-10 20:15:43 +000055 std::vector<uint8_t> data_buffer = GetFileContents(full_path.c_str());
56 if (data_buffer.empty()) {
Lei Zhang72e8b692019-02-05 19:16:52 +000057 return false;
Lei Zhang4da226a2023-11-10 20:15:43 +000058 }
Lei Zhang72e8b692019-02-05 19:16:52 +000059
Lei Zhang4da226a2023-11-10 20:15:43 +000060 // `result_data` takes ownership.
61 void* copy = malloc(data_buffer.size());
Tom Sepezfb6e3552024-05-07 18:15:23 +000062 FXSYS_memcpy(copy, data_buffer.data(), data_buffer.size());
Lei Zhang4da226a2023-11-10 20:15:43 +000063 result_data->data = static_cast<char*>(copy);
Lei Zhangf36006c2024-02-17 00:56:24 +000064 result_data->raw_size = pdfium::checked_cast<int>(data_buffer.size());
Lei Zhang72e8b692019-02-05 19:16:52 +000065 return true;
66}
67#endif // V8_USE_EXTERNAL_STARTUP_DATA
68
Tom Sepeze0d3c502020-08-11 23:51:10 +000069std::unique_ptr<v8::Platform> InitializeV8Common(const std::string& exe_path,
70 const std::string& js_flags) {
Lei Zhang72e8b692019-02-05 19:16:52 +000071 v8::V8::InitializeICUDefaultLocation(exe_path.c_str());
72
73 std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
74 v8::V8::InitializePlatform(platform.get());
Tom Sepez30eddfa2021-02-16 19:24:00 +000075#ifdef PDF_ENABLE_XFA
76 cppgc::InitializeProcess(platform->GetPageAllocator());
77#endif
Lei Zhang72e8b692019-02-05 19:16:52 +000078
79 const char* recommended_v8_flags = FPDF_GetRecommendedV8Flags();
Lei Zhang06d1acb2019-05-04 07:40:40 +000080 v8::V8::SetFlagsFromString(recommended_v8_flags);
Lei Zhang72e8b692019-02-05 19:16:52 +000081
Tom Sepeze0d3c502020-08-11 23:51:10 +000082 if (!js_flags.empty())
83 v8::V8::SetFlagsFromString(js_flags.c_str());
84
Lei Zhang72e8b692019-02-05 19:16:52 +000085 // By enabling predictable mode, V8 won't post any background tasks.
86 // By enabling GC, it makes it easier to chase use-after-free.
87 static const char kAdditionalV8Flags[] = "--predictable --expose-gc";
Lei Zhang06d1acb2019-05-04 07:40:40 +000088 v8::V8::SetFlagsFromString(kAdditionalV8Flags);
Lei Zhang72e8b692019-02-05 19:16:52 +000089
90 v8::V8::Initialize();
91 return platform;
92}
93
94} // namespace
95
96#ifdef V8_USE_EXTERNAL_STARTUP_DATA
97std::unique_ptr<v8::Platform> InitializeV8ForPDFiumWithStartupData(
98 const std::string& exe_path,
Tom Sepeze0d3c502020-08-11 23:51:10 +000099 const std::string& js_flags,
Lei Zhang72e8b692019-02-05 19:16:52 +0000100 const std::string& bin_dir,
Lei Zhang72e8b692019-02-05 19:16:52 +0000101 v8::StartupData* snapshot_blob) {
Tom Sepeze0d3c502020-08-11 23:51:10 +0000102 std::unique_ptr<v8::Platform> platform =
103 InitializeV8Common(exe_path, js_flags);
Lei Zhanga8e8baf2019-10-08 17:53:04 +0000104 if (snapshot_blob) {
Lei Zhang72e8b692019-02-05 19:16:52 +0000105 if (!GetExternalData(exe_path, bin_dir, "snapshot_blob.bin", snapshot_blob))
106 return nullptr;
Lei Zhang72e8b692019-02-05 19:16:52 +0000107 v8::V8::SetSnapshotDataBlob(snapshot_blob);
108 }
109 return platform;
110}
111#else // V8_USE_EXTERNAL_STARTUP_DATA
112std::unique_ptr<v8::Platform> InitializeV8ForPDFium(
Tom Sepeze0d3c502020-08-11 23:51:10 +0000113 const std::string& exe_path,
114 const std::string& js_flags) {
115 return InitializeV8Common(exe_path, js_flags);
Lei Zhang72e8b692019-02-05 19:16:52 +0000116}
117#endif // V8_USE_EXTERNAL_STARTUP_DATA
Tom Sepez30eddfa2021-02-16 19:24:00 +0000118
119void ShutdownV8ForPDFium() {
120#ifdef PDF_ENABLE_XFA
121 cppgc::ShutdownProcess();
122#endif
Tom Sepeze506d562022-01-24 20:52:53 +0000123 v8::V8::Dispose();
Alan Screen5e30ae82021-12-01 23:08:27 +0000124 v8::V8::DisposePlatform();
Tom Sepez30eddfa2021-02-16 19:24:00 +0000125}