blob: 108398480f7c7745fdb6a1a56a3d782e28c4cd58 [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
57std::unique_ptr<v8::Platform> InitializeV8Common(const std::string& exe_path) {
58 v8::V8::InitializeICUDefaultLocation(exe_path.c_str());
59
60 std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
61 v8::V8::InitializePlatform(platform.get());
62
63 const char* recommended_v8_flags = FPDF_GetRecommendedV8Flags();
64 v8::V8::SetFlagsFromString(recommended_v8_flags,
65 static_cast<int>(strlen(recommended_v8_flags)));
66
67 // By enabling predictable mode, V8 won't post any background tasks.
68 // By enabling GC, it makes it easier to chase use-after-free.
69 static const char kAdditionalV8Flags[] = "--predictable --expose-gc";
70 v8::V8::SetFlagsFromString(kAdditionalV8Flags,
71 static_cast<int>(strlen(kAdditionalV8Flags)));
72
73 v8::V8::Initialize();
74 return platform;
75}
76
77} // namespace
78
79#ifdef V8_USE_EXTERNAL_STARTUP_DATA
80std::unique_ptr<v8::Platform> InitializeV8ForPDFiumWithStartupData(
81 const std::string& exe_path,
82 const std::string& bin_dir,
83 v8::StartupData* natives_blob,
84 v8::StartupData* snapshot_blob) {
85 std::unique_ptr<v8::Platform> platform = InitializeV8Common(exe_path);
86 if (natives_blob && snapshot_blob) {
87 if (!GetExternalData(exe_path, bin_dir, "natives_blob.bin", natives_blob))
88 return nullptr;
89 if (!GetExternalData(exe_path, bin_dir, "snapshot_blob.bin", snapshot_blob))
90 return nullptr;
91 v8::V8::SetNativesDataBlob(natives_blob);
92 v8::V8::SetSnapshotDataBlob(snapshot_blob);
93 }
94 return platform;
95}
96#else // V8_USE_EXTERNAL_STARTUP_DATA
97std::unique_ptr<v8::Platform> InitializeV8ForPDFium(
98 const std::string& exe_path) {
99 return InitializeV8Common(exe_path);
100}
101#endif // V8_USE_EXTERNAL_STARTUP_DATA