blob: 49ef2578654d4a14505c3c8894a9c383b158d62c [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
Lei Zhangb6992dd2019-02-05 23:30:20 +00007#include "public/fpdfview.h"
8#include "testing/utils/file_util.h"
Lei Zhang72e8b692019-02-05 19:16:52 +00009#include "testing/utils/path_service.h"
10#include "v8/include/libplatform/libplatform.h"
11#include "v8/include/v8.h"
12
13namespace {
14
15#ifdef V8_USE_EXTERNAL_STARTUP_DATA
16// Returns the full path for an external V8 data file based on either
17// the currect exectuable path or an explicit override.
18std::string GetFullPathForSnapshotFile(const std::string& exe_path,
19 const std::string& bin_dir,
20 const std::string& filename) {
21 std::string result;
22 if (!bin_dir.empty()) {
23 result = bin_dir;
24 if (*bin_dir.rbegin() != PATH_SEPARATOR) {
25 result += PATH_SEPARATOR;
26 }
27 } else if (!exe_path.empty()) {
28 size_t last_separator = exe_path.rfind(PATH_SEPARATOR);
29 if (last_separator != std::string::npos) {
30 result = exe_path.substr(0, last_separator + 1);
31 }
32 }
33 result += filename;
34 return result;
35}
36
37bool GetExternalData(const std::string& exe_path,
38 const std::string& bin_dir,
39 const std::string& filename,
40 v8::StartupData* result_data) {
41 std::string full_path =
42 GetFullPathForSnapshotFile(exe_path, bin_dir, filename);
43 size_t data_length = 0;
44 std::unique_ptr<char, pdfium::FreeDeleter> data_buffer =
45 GetFileContents(full_path.c_str(), &data_length);
46 if (!data_buffer)
47 return false;
48
49 result_data->data = data_buffer.release();
50 result_data->raw_size = data_length;
51 return true;
52}
53#endif // V8_USE_EXTERNAL_STARTUP_DATA
54
55std::unique_ptr<v8::Platform> InitializeV8Common(const std::string& exe_path) {
56 v8::V8::InitializeICUDefaultLocation(exe_path.c_str());
57
58 std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
59 v8::V8::InitializePlatform(platform.get());
60
61 const char* recommended_v8_flags = FPDF_GetRecommendedV8Flags();
62 v8::V8::SetFlagsFromString(recommended_v8_flags,
63 static_cast<int>(strlen(recommended_v8_flags)));
64
65 // By enabling predictable mode, V8 won't post any background tasks.
66 // By enabling GC, it makes it easier to chase use-after-free.
67 static const char kAdditionalV8Flags[] = "--predictable --expose-gc";
68 v8::V8::SetFlagsFromString(kAdditionalV8Flags,
69 static_cast<int>(strlen(kAdditionalV8Flags)));
70
71 v8::V8::Initialize();
72 return platform;
73}
74
75} // namespace
76
77#ifdef V8_USE_EXTERNAL_STARTUP_DATA
78std::unique_ptr<v8::Platform> InitializeV8ForPDFiumWithStartupData(
79 const std::string& exe_path,
80 const std::string& bin_dir,
81 v8::StartupData* natives_blob,
82 v8::StartupData* snapshot_blob) {
83 std::unique_ptr<v8::Platform> platform = InitializeV8Common(exe_path);
84 if (natives_blob && snapshot_blob) {
85 if (!GetExternalData(exe_path, bin_dir, "natives_blob.bin", natives_blob))
86 return nullptr;
87 if (!GetExternalData(exe_path, bin_dir, "snapshot_blob.bin", snapshot_blob))
88 return nullptr;
89 v8::V8::SetNativesDataBlob(natives_blob);
90 v8::V8::SetSnapshotDataBlob(snapshot_blob);
91 }
92 return platform;
93}
94#else // V8_USE_EXTERNAL_STARTUP_DATA
95std::unique_ptr<v8::Platform> InitializeV8ForPDFium(
96 const std::string& exe_path) {
97 return InitializeV8Common(exe_path);
98}
99#endif // V8_USE_EXTERNAL_STARTUP_DATA