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