Skip to content

Commit

Permalink
Add support of user and owner passwords for pdf files
Browse files Browse the repository at this point in the history
  • Loading branch information
blackbeam committed Dec 16, 2018
1 parent 744ffbe commit e92437c
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 14 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"scripts": {
"install": "(node-gyp rebuild) || (exit 1)",
"preinstall": "((npm install nan) && (node-gyp configure)) || (exit 0)",
"preinstall": "((npm install nan@2.11.1) && (node-gyp configure)) || (exit 0)",
"test": "./node_modules/mocha/bin/mocha -gc --slow 250",
"clean": "((node-gyp clean) && (rm -rf node_modules)) || (exit 0)",
"build-debug": "(node-gyp configure --debug && node-gyp rebuild --debug) || (exit 0)"
Expand Down
58 changes: 47 additions & 11 deletions src/NodePopplerDocument.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@
#include "NodePopplerDocument.h"
#include "NodePopplerPage.h"

PDFDoc *createMemPDFDoc(char *buffer, size_t length)
PDFDoc *createMemPDFDoc(
char *buffer,
size_t length,
GooString* ownerPassword = nullptr,
GooString* userPassword = nullptr)
{
Object obj;

#if ((POPPLER_VERSION_MAJOR == 0) && (POPPLER_VERSION_MINOR <= 57))
obj.initNull();
return new PDFDoc(new MemStream(buffer, 0, length, &obj), NULL, NULL);
return new PDFDoc(new MemStream(buffer, 0, length, &obj), ownerPassword, userPassword);
#else
return new PDFDoc(new MemStream(buffer, 0, length, std::move(obj)), NULL, NULL);
return new PDFDoc(new MemStream(buffer, 0, length, std::move(obj)), ownerPassword, userPassword);
#endif
}

Expand Down Expand Up @@ -54,22 +59,32 @@ void NodePopplerDocument::evPageClosed(const NodePopplerPage *p)
}
}

NodePopplerDocument::NodePopplerDocument(const char *cFileName)
NodePopplerDocument::NodePopplerDocument(
const char *cFileName,
GooString* ownerPassword,
GooString* userPassword)
{
doc = NULL;
buffer = NULL;

GooString *fileNameA = new GooString(cFileName);
doc = PDFDocFactory().createPDFDoc(*fileNameA, NULL, NULL);

doc = PDFDocFactory().createPDFDoc(*fileNameA, ownerPassword, userPassword);

pages = new GooList();
}

NodePopplerDocument::NodePopplerDocument(char *buffer, size_t length)
NodePopplerDocument::NodePopplerDocument(
char *buffer,
size_t length,
GooString* ownerPassword,
GooString* userPassword)
{
doc = NULL;
this->buffer = NULL;
this->buffer = new char[length];
std::memcpy(this->buffer, buffer, length);
doc = createMemPDFDoc(this->buffer, length);
doc = createMemPDFDoc(this->buffer, length, ownerPassword, userPassword);
pages = new GooList();
}

Expand Down Expand Up @@ -184,21 +199,42 @@ NAN_METHOD(NodePopplerDocument::New)
{
Nan::HandleScope scope;

if (info.Length() != 1)
if (
!(0 < info.Length() && info.Length() <= 3)
|| !(info[0]->IsString() || Buffer::HasInstance(info[0]))
|| !(info[1]->IsUndefined() || info[1]->IsNull() || info[1]->IsString())
|| !(info[2]->IsUndefined() || info[2]->IsNull() || info[2]->IsString()))
{
return Nan::ThrowError("One argument required: (filename: String).");
return Nan::ThrowError("Supported arguments: (fileName: string | Buffer, userPassword?: string, ownerPassword?: string).");
}

NodePopplerDocument *doc;

GooString* userPassword = nullptr;
GooString* ownerPassword = nullptr;

if (info[1]->IsString()) {
Nan::Utf8String jsUserPassword(To<String>(info[1]).ToLocalChecked());
userPassword = new GooString(*jsUserPassword);
}

if (info[2]->IsString()) {
Nan::Utf8String jsOwnerPassword(To<String>(info[2]).ToLocalChecked());
ownerPassword = new GooString(*jsOwnerPassword);
}

if (info[0]->IsString())
{
Nan::Utf8String str(To<String>(info[0]).ToLocalChecked());
doc = new NodePopplerDocument(*str);
doc = new NodePopplerDocument(*str, ownerPassword, userPassword);
}
else if (Buffer::HasInstance(info[0]))
{
doc = new NodePopplerDocument(Buffer::Data(info[0]), Buffer::Length(info[0]));
doc = new NodePopplerDocument(
Buffer::Data(info[0]),
Buffer::Length(info[0]),
userPassword,
ownerPassword);
}
else
{
Expand Down
11 changes: 9 additions & 2 deletions src/NodePopplerDocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,15 @@ namespace node {
class NodePopplerPage;
class NodePopplerDocument : public Nan::ObjectWrap {
public:
NodePopplerDocument(const char* cFileName);
NodePopplerDocument(char* buffer, size_t length);
NodePopplerDocument(
const char* cFileName,
GooString* ownerPassword = nullptr,
GooString* userPassword = nullptr);
NodePopplerDocument(
char* buffer,
size_t length,
GooString* ownerPassword = nullptr,
GooString* userPassword = nullptr);
~NodePopplerDocument();

inline bool isOk() {
Expand Down
Binary file added test/fixtures/password_protected.pdf
Binary file not shown.
9 changes: 9 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,15 @@ describe('PopplerDocument', function () {
a.equal(d.PDFMajorVersion, 1);
a.equal(d.PDFMinorVersion, 5);
a.equal(d.fileName, fileName);
var fileName = __dirname + '/fixtures/password_protected.pdf';
var d = new poppler.PopplerDocument(fileName, '1234');
a.equal(d.isEncrypted, true);
a.equal(d.isLinearized, false);
a.equal(d.pdfVersion, 'PDF-1.6');
a.equal(d.pageCount, 1);
a.equal(d.PDFMajorVersion, 1);
a.equal(d.PDFMinorVersion, 6);
a.equal(d.fileName, fileName);
});
it('should throw on non existing page', function () {
this.timeout(0);
Expand Down

0 comments on commit e92437c

Please sign in to comment.