summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJane Liu <janeliulwq@google.com>2017-07-19 10:19:42 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-07-19 14:35:29 +0000
commit4442d453f570fda76ec4852e2bb03e7ec8bfb825 (patch)
treed0de96e6725c03af321cc3735b9aed46285da5f0
parentc5ea630cb5eecb7d4f7f20938b8e4b52a982c0a6 (diff)
downloadpdfium-4442d453f570fda76ec4852e2bb03e7ec8bfb825.tar.xz
Added testing flag --save-attachments that saves embedded attachments
1. Added --save-attachments flag in pdfium_test to save embedded attachments using fpdf_attachment APIs. Bug=pdfium:174 Change-Id: I62f09aeb0ab1431f6e127da389518878a7214423 Reviewed-on: https://pdfium-review.googlesource.com/7990 Commit-Queue: Jane Liu <janeliulwq@google.com> Reviewed-by: dsinclair <dsinclair@chromium.org>
-rw-r--r--samples/pdfium_test.cc77
-rw-r--r--testing/test_support.cpp8
-rw-r--r--testing/test_support.h4
3 files changed, 80 insertions, 9 deletions
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index 719ac509aa..83f18ed79f 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -21,6 +21,7 @@
#include "public/cpp/fpdf_deleters.h"
#include "public/fpdf_annot.h"
+#include "public/fpdf_attachment.h"
#include "public/fpdf_dataavail.h"
#include "public/fpdf_edit.h"
#include "public/fpdf_ext.h"
@@ -83,6 +84,7 @@ struct Options {
show_metadata(false),
send_events(false),
render_oneshot(false),
+ save_attachments(false),
#ifdef ENABLE_CALLGRIND
callgrind_delimiters(false),
#endif // ENABLE_CALLGRIND
@@ -95,6 +97,7 @@ struct Options {
bool show_metadata;
bool send_events;
bool render_oneshot;
+ bool save_attachments;
#ifdef ENABLE_CALLGRIND
bool callgrind_delimiters;
#endif // ENABLE_CALLGRIND
@@ -701,6 +704,8 @@ bool ParseCommandLine(const std::vector<std::string>& args,
options->send_events = true;
} else if (cur_arg == "--render-oneshot") {
options->render_oneshot = true;
+ } else if (cur_arg == "--save-attachments") {
+ options->save_attachments = true;
#ifdef ENABLE_CALLGRIND
} else if (cur_arg == "--callgrind-delim") {
options->callgrind_delimiters = true;
@@ -1225,6 +1230,58 @@ void RenderPdf(const std::string& name,
}
}
+ if (options.save_attachments) {
+ for (int i = 0; i < FPDFDoc_GetAttachmentCount(doc.get()); ++i) {
+ FPDF_ATTACHMENT attachment = FPDFDoc_GetAttachment(doc.get(), i);
+
+ // Retrieve the attachment file name.
+ unsigned long len = FPDFAttachment_GetName(attachment, nullptr, 0);
+ if (!len) {
+ fprintf(stderr, "Warning: Attachment #%d has an empty file name.\n",
+ i + 1);
+ }
+ std::vector<char> buf(len);
+ FPDFAttachment_GetName(attachment, buf.data(), len);
+ std::string attachment_name =
+ GetPlatformString(reinterpret_cast<unsigned short*>(buf.data()));
+
+ // Open the attachment file for writing.
+ char save_name[256];
+ int chars_formatted =
+ snprintf(save_name, sizeof(save_name), "%s.attachment.%s",
+ name.c_str(), attachment_name.c_str());
+ if (chars_formatted < 0 ||
+ static_cast<size_t>(chars_formatted) >= sizeof(save_name)) {
+ fprintf(stderr, "Filename %s is too long\n", save_name);
+ continue;
+ }
+ FILE* fp = fopen(save_name, "wb");
+ if (!fp) {
+ fprintf(stderr, "Failed to open %s for saving attachment.\n",
+ save_name);
+ continue;
+ }
+
+ // Write the attachment file.
+ len = FPDFAttachment_GetFile(attachment, nullptr, 0);
+ if (!len) {
+ fprintf(stderr, "Warning: Attachment \"%s\" is empty.\n",
+ attachment_name.c_str());
+ }
+ buf.clear();
+ buf.resize(len);
+ FPDFAttachment_GetFile(attachment, buf.data(), len);
+ size_t written_len = fwrite(buf.data(), sizeof(char), len, fp);
+ if (written_len != len) {
+ fprintf(stderr, "Warning: Unsuccessful write to file \"%s\".\n",
+ save_name);
+ }
+ fclose(fp);
+
+ fprintf(stderr, "Saved attachment \"%s\".\n", attachment_name.c_str());
+ }
+ }
+
std::unique_ptr<void, FPDFFormHandleDeleter> form(
FPDFDOC_InitFormFillEnvironment(doc.get(), &form_callbacks));
form_callbacks.form_handle = form.get();
@@ -1307,17 +1364,19 @@ static void ShowConfig() {
static const char kUsageString[] =
"Usage: pdfium_test [OPTION] [FILE]...\n"
- " --show-config - print build options and exit\n"
- " --show-metadata - print the file metadata\n"
- " --show-structure - print the structure elements from the document\n"
- " --send-events - send input described by .evt file\n"
- " --render-oneshot - render image without using progressive renderer\n"
+ " --show-config - print build options and exit\n"
+ " --show-metadata - print the file metadata\n"
+ " --show-structure - print the structure elements from the document\n"
+ " --send-events - send input described by .evt file\n"
+ " --render-oneshot - render image without using progressive renderer\n"
+ " --save-attachments - write embedded attachments "
+ "<pdf-name>.attachment.<attachment-name>\n"
#ifdef ENABLE_CALLGRIND
- " --callgrind-delim - delimit interesting section when using callgrind\n"
+ " --callgrind-delim - delimit interesting section when using callgrind\n"
#endif // ENABLE_CALLGRIND
- " --bin-dir=<path> - override path to v8 external data\n"
- " --font-dir=<path> - override path to external fonts\n"
- " --scale=<number> - scale output size by number (e.g. 0.5)\n"
+ " --bin-dir=<path> - override path to v8 external data\n"
+ " --font-dir=<path> - override path to external fonts\n"
+ " --scale=<number> - scale output size by number (e.g. 0.5)\n"
" --pages=<number>(-<number>) - only render the given 0-based page(s)\n"
#ifdef _WIN32
" --bmp - write page images <pdf-name>.<page-number>.bmp\n"
diff --git a/testing/test_support.cpp b/testing/test_support.cpp
index 1ad8543bae..e5c3ab45a0 100644
--- a/testing/test_support.cpp
+++ b/testing/test_support.cpp
@@ -9,6 +9,7 @@
#include "core/fdrm/crypto/fx_crypt.h"
#include "core/fxcrt/fx_memory.h"
+#include "core/fxcrt/fx_string.h"
#include "testing/utils/path_service.h"
#ifdef PDF_ENABLE_V8
@@ -103,6 +104,13 @@ std::unique_ptr<char, pdfium::FreeDeleter> GetFileContents(const char* filename,
return buffer;
}
+std::string GetPlatformString(FPDF_WIDESTRING wstr) {
+ return std::string(
+ CFX_WideString::FromUTF16LE(wstr, CFX_WideString::WStringLength(wstr))
+ .UTF8Encode()
+ .c_str());
+}
+
std::wstring GetPlatformWString(FPDF_WIDESTRING wstr) {
if (!wstr)
return nullptr;
diff --git a/testing/test_support.h b/testing/test_support.h
index 7676e5783b..feec4bbe0b 100644
--- a/testing/test_support.h
+++ b/testing/test_support.h
@@ -62,6 +62,10 @@ std::unique_ptr<char, pdfium::FreeDeleter> GetFileContents(const char* filename,
std::vector<std::string> StringSplit(const std::string& str, char delimiter);
+// Converts a FPDF_WIDESTRING to a std::string.
+// Deals with differences between UTF16LE and UTF8.
+std::string GetPlatformString(FPDF_WIDESTRING wstr);
+
// Converts a FPDF_WIDESTRING to a std::wstring.
// Deals with differences between UTF16LE and wchar_t.
std::wstring GetPlatformWString(FPDF_WIDESTRING wstr);