Add context to file load failures in pdfium_test.
[pdfium.git] / testing / test_support.cpp
1 // Copyright 2015 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 "test_support.h"
6
7 #include <stdio.h>
8 #include <string.h>
9
10 #ifdef _WIN32
11 #define PATH_SEPARATOR '\\'
12 #else
13 #define PATH_SEPARATOR '/'
14 #endif
15
16 namespace {
17
18 #ifdef PDF_ENABLE_V8
19 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
20 // Returns the full path for an external V8 data file based on either
21 // the currect exectuable path or an explicit override.
22 std::string GetFullPathForSnapshotFile(const std::string& exe_path,
23                                        const std::string& bin_dir,
24                                        const std::string& filename) {
25   std::string result;
26   if (!bin_dir.empty()) {
27     result = bin_dir;
28     if (*bin_dir.rbegin() != PATH_SEPARATOR) {
29       result += PATH_SEPARATOR;
30     }
31   } else if (!exe_path.empty()) {
32     size_t last_separator = exe_path.rfind(PATH_SEPARATOR);
33     if (last_separator != std::string::npos) {
34       result = exe_path.substr(0, last_separator + 1);
35     }
36   }
37   result += filename;
38   return result;
39 }
40
41 bool GetExternalData(const std::string& exe_path,
42                      const std::string& bin_dir,
43                      const std::string& filename,
44                      v8::StartupData* result_data) {
45   std::string full_path =
46       GetFullPathForSnapshotFile(exe_path, bin_dir, filename);
47   size_t data_length = 0;
48   char* data_buffer = GetFileContents(full_path.c_str(), &data_length);
49   if (!data_buffer) {
50     return false;
51   }
52   result_data->data = const_cast<const char*>(data_buffer);
53   result_data->raw_size = data_length;
54   return true;
55 }
56 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
57
58 void InitializeV8Common(v8::Platform** platform) {
59   v8::V8::InitializeICU();
60
61   *platform = v8::platform::CreateDefaultPlatform();
62   v8::V8::InitializePlatform(*platform);
63   v8::V8::Initialize();
64
65   // By enabling predictable mode, V8 won't post any background tasks.
66   const char predictable_flag[] = "--predictable";
67   v8::V8::SetFlagsFromString(predictable_flag,
68                              static_cast<int>(strlen(predictable_flag)));
69 }
70 #endif  // PDF_ENABLE_V8
71
72 }  // namespace
73
74 char* GetFileContents(const char* filename, size_t* retlen) {
75   FILE* file = fopen(filename, "rb");
76   if (!file) {
77     fprintf(stderr, "Failed to open: %s\n", filename);
78     return nullptr;
79   }
80   (void)fseek(file, 0, SEEK_END);
81   size_t file_length = ftell(file);
82   if (!file_length) {
83     return nullptr;
84   }
85   (void)fseek(file, 0, SEEK_SET);
86   char* buffer = (char*)malloc(file_length);
87   if (!buffer) {
88     return nullptr;
89   }
90   size_t bytes_read = fread(buffer, 1, file_length, file);
91   (void)fclose(file);
92   if (bytes_read != file_length) {
93     fprintf(stderr, "Failed to read: %s\n", filename);
94     free(buffer);
95     return nullptr;
96   }
97   *retlen = bytes_read;
98   return buffer;
99 }
100
101 #ifdef PDF_ENABLE_V8
102 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
103 bool InitializeV8ForPDFium(const std::string& exe_path,
104                            const std::string& bin_dir,
105                            v8::StartupData* natives_blob,
106                            v8::StartupData* snapshot_blob,
107                            v8::Platform** platform) {
108   InitializeV8Common(platform);
109   if (!GetExternalData(exe_path, bin_dir, "natives_blob.bin", natives_blob))
110     return false;
111   if (!GetExternalData(exe_path, bin_dir, "snapshot_blob.bin", snapshot_blob))
112     return false;
113   v8::V8::SetNativesDataBlob(natives_blob);
114   v8::V8::SetSnapshotDataBlob(snapshot_blob);
115   return true;
116 }
117 #else   // V8_USE_EXTERNAL_STARTUP_DATA
118 bool InitializeV8ForPDFium(v8::Platform** platform) {
119   InitializeV8Common(platform);
120   return true;
121 }
122 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
123 #endif  // PDF_ENABLE_V8
124
125 TestLoader::TestLoader(const char* pBuf, size_t len)
126     : m_pBuf(pBuf), m_Len(len) {
127 }
128
129 // static
130 int TestLoader::GetBlock(void* param,
131                          unsigned long pos,
132                          unsigned char* pBuf,
133                          unsigned long size) {
134   TestLoader* pLoader = static_cast<TestLoader*>(param);
135   if (pos + size < pos || pos + size > pLoader->m_Len)
136     return 0;
137
138   memcpy(pBuf, pLoader->m_pBuf + pos, size);
139   return 1;
140 }