blob: 29d6e556c56c13dd795f386e894a066314d5bf76 [file] [log] [blame]
Lei Zhang72e8b692019-02-05 19:16:52 +00001// Copyright 2019 PDFium Authors. All rights reserved.
2// 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"
12#include "v8/include/libplatform/libplatform.h"
13#include "v8/include/v8.h"
14
15namespace {
16
17#ifdef V8_USE_EXTERNAL_STARTUP_DATA
18// Returns the full path for an external V8 data file based on either
19// the currect exectuable path or an explicit override.
20std::string GetFullPathForSnapshotFile(const std::string& exe_path,
21 const std::string& bin_dir,
22 const std::string& filename) {
23 std::string result;
24 if (!bin_dir.empty()) {
25 result = bin_dir;
26 if (*bin_dir.rbegin() != PATH_SEPARATOR) {
27 result += PATH_SEPARATOR;
28 }
29 } else if (!exe_path.empty()) {
30 size_t last_separator = exe_path.rfind(PATH_SEPARATOR);
31 if (last_separator != std::string::npos) {
32 result = exe_path.substr(0, last_separator + 1);
33 }
34 }
35 result += filename;
36 return result;
37}
38
39bool GetExternalData(const std::string& exe_path,
40 const std::string& bin_dir,
41 const std::string& filename,
42 v8::StartupData* result_data) {
43 std::string full_path =
44 GetFullPathForSnapshotFile(exe_path, bin_dir, filename);
45 size_t data_length = 0;
46 std::unique_ptr<char, pdfium::FreeDeleter> data_buffer =
47 GetFileContents(full_path.c_str(), &data_length);
48 if (!data_buffer)
49 return false;
50
51 result_data->data = data_buffer.release();
52 result_data->raw_size = data_length;
53 return true;
54}
55#endif // V8_USE_EXTERNAL_STARTUP_DATA
56
Tom Sepeze0d3c502020-08-11 23:51:10 +000057std::unique_ptr<v8::Platform> InitializeV8Common(const std::string& exe_path,
58 const std::string& js_flags) {
Lei Zhang72e8b692019-02-05 19:16:52 +000059 v8::V8::InitializeICUDefaultLocation(exe_path.c_str());
60
61 std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
62 v8::V8::InitializePlatform(platform.get());
63
64 const char* recommended_v8_flags = FPDF_GetRecommendedV8Flags();
Lei Zhang06d1acb2019-05-04 07:40:40 +000065 v8::V8::SetFlagsFromString(recommended_v8_flags);
Lei Zhang72e8b692019-02-05 19:16:52 +000066
Tom Sepeze0d3c502020-08-11 23:51:10 +000067 if (!js_flags.empty())
68 v8::V8::SetFlagsFromString(js_flags.c_str());
69
Lei Zhang72e8b692019-02-05 19:16:52 +000070 // By enabling predictable mode, V8 won't post any background tasks.
71 // By enabling GC, it makes it easier to chase use-after-free.
72 static const char kAdditionalV8Flags[] = "--predictable --expose-gc";
Lei Zhang06d1acb2019-05-04 07:40:40 +000073 v8::V8::SetFlagsFromString(kAdditionalV8Flags);
Lei Zhang72e8b692019-02-05 19:16:52 +000074
75 v8::V8::Initialize();
76 return platform;
77}
78
79} // namespace
80
81#ifdef V8_USE_EXTERNAL_STARTUP_DATA
82std::unique_ptr<v8::Platform> InitializeV8ForPDFiumWithStartupData(
83 const std::string& exe_path,
Tom Sepeze0d3c502020-08-11 23:51:10 +000084 const std::string& js_flags,
Lei Zhang72e8b692019-02-05 19:16:52 +000085 const std::string& bin_dir,
Lei Zhang72e8b692019-02-05 19:16:52 +000086 v8::StartupData* snapshot_blob) {
Tom Sepeze0d3c502020-08-11 23:51:10 +000087 std::unique_ptr<v8::Platform> platform =
88 InitializeV8Common(exe_path, js_flags);
Lei Zhanga8e8baf2019-10-08 17:53:04 +000089 if (snapshot_blob) {
Lei Zhang72e8b692019-02-05 19:16:52 +000090 if (!GetExternalData(exe_path, bin_dir, "snapshot_blob.bin", snapshot_blob))
91 return nullptr;
Lei Zhang72e8b692019-02-05 19:16:52 +000092 v8::V8::SetSnapshotDataBlob(snapshot_blob);
93 }
94 return platform;
95}
96#else // V8_USE_EXTERNAL_STARTUP_DATA
97std::unique_ptr<v8::Platform> InitializeV8ForPDFium(
Tom Sepeze0d3c502020-08-11 23:51:10 +000098 const std::string& exe_path,
99 const std::string& js_flags) {
100 return InitializeV8Common(exe_path, js_flags);
Lei Zhang72e8b692019-02-05 19:16:52 +0000101}
102#endif // V8_USE_EXTERNAL_STARTUP_DATA