summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2014-12-17 16:24:01 -0800
committerTom Sepez <tsepez@chromium.org>2014-12-17 16:24:01 -0800
commit5ee12d778eb90ad865085680d49cd9f0391f3edd (patch)
tree000d3c154cfdf74f54d425ad7a37bf8315881a99
parent1a6785b2dd574e61ee3d666fb7fff3f09599776d (diff)
downloadpdfium-5ee12d778eb90ad865085680d49cd9f0391f3edd.tar.xz
Initialize V8 external data (XFA version).
This is a quick patch to fix the segv which occurs in pdfium_test when the v8 external data is not provided. Fixing the full-up initialization is left as a follow-on exercise. Path manipulations remain a nuisance since we don't want to depend on a particular /base library. BUG=439793 R=thestig@chromium.org Review URL: https://codereview.chromium.org/810793004
-rw-r--r--samples/pdfium_test.cc210
1 files changed, 157 insertions, 53 deletions
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index 19e8b7ee57..61732d52b2 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -11,6 +11,7 @@
#include <list>
#include <string>
#include <utility>
+#include <vector>
#include "../fpdfsdk/include/fpdf_dataavail.h"
#include "../fpdfsdk/include/fpdf_ext.h"
@@ -21,7 +22,10 @@
#include "v8/include/v8.h"
#ifdef _WIN32
- #define snprintf _snprintf
+#define snprintf _snprintf
+#define PATH_SEPARATOR '\\'
+#else
+#define PATH_SEPARATOR '/'
#endif
enum OutputFormat {
@@ -33,6 +37,80 @@ enum OutputFormat {
#endif
};
+struct Options {
+ Options() : output_format(OUTPUT_NONE) { }
+
+ OutputFormat output_format;
+ std::string exe_path;
+ std::string bin_directory;
+};
+
+// Reads the entire contents of a file into a newly malloc'd buffer.
+static char* GetFileContents(const char* filename, size_t* retlen) {
+ FILE* file = fopen(filename, "rb");
+ if (!file) {
+ fprintf(stderr, "Failed to open: %s\n", filename);
+ return NULL;
+ }
+ (void) fseek(file, 0, SEEK_END);
+ size_t file_length = ftell(file);
+ if (!file_length) {
+ return NULL;
+ }
+ (void) fseek(file, 0, SEEK_SET);
+ char* buffer = (char*) malloc(file_length);
+ if (!buffer) {
+ return NULL;
+ }
+ size_t bytes_read = fread(buffer, 1, file_length, file);
+ (void) fclose(file);
+ if (bytes_read != file_length) {
+ fprintf(stderr, "Failed to read: %s\n", filename);
+ free(buffer);
+ return NULL;
+ }
+ *retlen = bytes_read;
+ return buffer;
+}
+
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+// Returns the full path for an external V8 data file based on either
+// the currect exectuable path or an explicit override.
+static std::string GetFullPathForSnapshotFile(const Options& options,
+ const std::string& filename) {
+ std::string result;
+ if (!options.bin_directory.empty()) {
+ result = options.bin_directory;
+ if (*options.bin_directory.rbegin() != PATH_SEPARATOR) {
+ result += PATH_SEPARATOR;
+ }
+ } else if (!options.exe_path.empty()) {
+ size_t last_separator = options.exe_path.rfind(PATH_SEPARATOR);
+ if (last_separator != std::string::npos) {
+ result = options.exe_path.substr(0, last_separator + 1);
+ }
+ }
+ result += filename;
+ return result;
+}
+
+// Reads an extenal V8 data file from the |options|-indicated location,
+// returing true on success and false on error.
+static bool GetExternalData(const Options& options,
+ const std::string& bin_filename,
+ v8::StartupData* result_data) {
+ std::string full_path = GetFullPathForSnapshotFile(options, bin_filename);
+ size_t data_length = 0;
+ char* data_buffer = GetFileContents(full_path.c_str(), &data_length);
+ if (!data_buffer) {
+ return false;
+ }
+ result_data->data = const_cast<const char*>(data_buffer);
+ result_data->raw_size = data_length;
+ return true;
+}
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+
static void WritePpm(const char* pdf_name, int num, const void* buffer_void,
int stride, int width, int height) {
const char* buffer = reinterpret_cast<const char*>(buffer_void);
@@ -198,34 +276,57 @@ void Unsupported_Handler(UNSUPPORT_INFO*, int type) {
printf("Unsupported feature: %s.\n", feature.c_str());
}
-bool ParseCommandLine(int argc, const char* argv[], OutputFormat* output_format,
- std::list<const char*>* files) {
- *output_format = OUTPUT_NONE;
- files->clear();
-
- int cur_arg = 1;
- for (; cur_arg < argc; ++cur_arg) {
- if (strcmp(argv[cur_arg], "--ppm") == 0)
- *output_format = OUTPUT_PPM;
+bool ParseCommandLine(const std::vector<std::string>& args,
+ Options* options, std::list<std::string>* files) {
+ if (args.empty()) {
+ return false;
+ }
+ options->exe_path = args[0];
+ int cur_idx = 1;
+ for (; cur_idx < args.size(); ++cur_idx) {
+ const std::string& cur_arg = args[cur_idx];
+ if (cur_arg == "--ppm") {
+ if (options->output_format != OUTPUT_NONE) {
+ fprintf(stderr, "Duplicate or conflicting --ppm argument\n");
+ return false;
+ }
+ options->output_format = OUTPUT_PPM;
+ }
#ifdef _WIN32
- else if (strcmp(argv[cur_arg], "--emf") == 0)
- *output_format = OUTPUT_EMF;
- else if (strcmp(argv[cur_arg], "--bmp") == 0)
- *output_format = OUTPUT_BMP;
-#endif
+ else if (cur_arg == "--emf") {
+ if (options->output_format != OUTPUT_NONE) {
+ fprintf(stderr, "Duplicate or conflicting --emf argument\n");
+ return false;
+ }
+ options->output_format = OUTPUT_EMF;
+ }
+ else if (cur_arg == "--bmp") {
+ if (options->output_format != OUTPUT_NONE) {
+ fprintf(stderr, "Duplicate or conflicting --bmp argument\n");
+ return false;
+ }
+ options->output_format = OUTPUT_BMP;
+ }
+#endif // _WIN32
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ else if (cur_arg.size() > 10 && cur_arg.compare(0, 10, "--bin-dir=") == 0) {
+ if (!options->bin_directory.empty()) {
+ fprintf(stderr, "Duplicate --bin-dir argument\n");
+ return false;
+ }
+ options->bin_directory = cur_arg.substr(10);
+ }
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
else
break;
}
-
- if (cur_arg > 2) // Multiple options.
+ if (cur_idx >= args.size()) {
+ fprintf(stderr, "No input files.\n");
return false;
-
- if (cur_arg >= argc) // No input files.
- return false;
-
- for (int i = cur_arg; i < argc; i++)
- files->push_back(argv[i]);
-
+ }
+ for (int i = cur_idx; i < args.size(); i++) {
+ files->push_back(args[i]);
+ }
return true;
}
@@ -256,9 +357,9 @@ bool Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) {
void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {
}
-void RenderPdf(const char* name, const char* pBuf, size_t len,
+void RenderPdf(const std::string& name, const char* pBuf, size_t len,
OutputFormat format) {
- printf("Rendering PDF file %s.\n", name);
+ printf("Rendering PDF file %s.\n", name.c_str());
IPDF_JSPLATFORM platform_callbacks;
memset(&platform_callbacks, '\0', sizeof(platform_callbacks));
@@ -350,15 +451,15 @@ void RenderPdf(const char* name, const char* pBuf, size_t len,
switch (format) {
#ifdef _WIN32
case OUTPUT_BMP:
- WriteBmp(name, i, buffer, stride, width, height);
+ WriteBmp(name.c_str(), i, buffer, stride, width, height);
break;
case OUTPUT_EMF:
- WriteEmf(page, name, i);
+ WriteEmf(page.c_str(), name, i);
break;
#endif
case OUTPUT_PPM:
- WritePpm(name, i, buffer, stride, width, height);
+ WritePpm(name.c_str(), i, buffer, stride, width, height);
break;
default:
break;
@@ -382,19 +483,33 @@ void RenderPdf(const char* name, const char* pBuf, size_t len,
}
int main(int argc, const char* argv[]) {
- v8::V8::InitializeICU();
- OutputFormat format = OUTPUT_NONE;
- std::list<const char*> files;
- if (!ParseCommandLine(argc, argv, &format, &files)) {
+ std::vector<std::string> args(argv, argv + argc);
+ Options options;
+ std::list<std::string> files;
+ if (!ParseCommandLine(args, &options, &files)) {
printf("Usage: pdfium_test [OPTION] [FILE]...\n");
- printf("--ppm write page images <pdf-name>.<page-number>.ppm\n");
+ printf("--bin-dir=<path> - override path to v8 external data\n");
+ printf("--ppm - write page images <pdf-name>.<page-number>.ppm\n");
#ifdef _WIN32
- printf("--bmp write page images <pdf-name>.<page-number>.bmp\n");
- printf("--emf write page meta files <pdf-name>.<page-number>.emf\n");
+ printf("--bmp - write page images <pdf-name>.<page-number>.bmp\n");
+ printf("--emf - write page meta files <pdf-name>.<page-number>.emf\n");
#endif
return 1;
}
+ v8::V8::InitializeICU();
+
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ v8::StartupData natives;
+ v8::StartupData snapshot;
+ if (!GetExternalData(options, "natives_blob.bin", &natives) ||
+ !GetExternalData(options, "snapshot_blob.bin", &snapshot)) {
+ return 1;
+ }
+ v8::V8::SetNativesDataBlob(&natives);
+ v8::V8::SetSnapshotDataBlob(&snapshot);
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+
FPDF_InitLibrary();
UNSUPPORT_INFO unsuppored_info;
@@ -405,25 +520,14 @@ int main(int argc, const char* argv[]) {
FSDK_SetUnSpObjProcessHandler(&unsuppored_info);
while (!files.empty()) {
- const char* filename = files.front();
+ std::string filename = files.front();
files.pop_front();
- FILE* file = fopen(filename, "rb");
- if (!file) {
- fprintf(stderr, "Failed to open: %s\n", filename);
+ size_t file_length = 0;
+ char* file_contents = GetFileContents(filename.c_str(), &file_length);
+ if (!file_contents)
continue;
- }
- (void) fseek(file, 0, SEEK_END);
- size_t len = ftell(file);
- (void) fseek(file, 0, SEEK_SET);
- char* pBuf = (char*) malloc(len);
- size_t ret = fread(pBuf, 1, len, file);
- (void) fclose(file);
- if (ret != len) {
- fprintf(stderr, "Failed to read: %s\n", filename);
- } else {
- RenderPdf(filename, pBuf, len, format);
- }
- free(pBuf);
+ RenderPdf(filename, file_contents, file_length, options.output_format);
+ free(file_contents);
}
FPDF_DestroyLibrary();