Skip to content

Commit

Permalink
Merge branch 'release/1.3.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
vbuch committed Jun 4, 2021
2 parents 45211a3 + 105bfcc commit 5f784b9
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 53 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,11 @@
# CHANGELOG

## [1.3.3]

* plainAddPlaceholder: Fixed loss of PDF metadata when adding placeholder;
* Export helpers from root;
* Bumped dependencies;

## [1.3.2]

* Fixed detection of ByteRange (including when it is a placeholder);
Expand Down
2 changes: 1 addition & 1 deletion dist/helpers/plainAddPlaceholder/createBufferTrailer.js
Expand Up @@ -14,7 +14,7 @@ const createBufferTrailer = (pdf, info, addedReferences) => {
rows[index + 1] = `${index} 1\n${paddedOffset} 00000 n `;
});
rows = rows.filter(row => row !== undefined);
return Buffer.concat([Buffer.from('xref\n'), Buffer.from(`${info.xref.startingIndex} 1\n`), Buffer.from(rows.join('\n')), Buffer.from('\ntrailer\n'), Buffer.from('<<\n'), Buffer.from(`/Size ${info.xref.maxIndex + 1}\n`), Buffer.from(`/Prev ${info.xRefPosition}\n`), Buffer.from(`/Root ${info.rootRef}\n`), Buffer.from('/Info 15 0 R\n'), Buffer.from('>>\n'), Buffer.from('startxref\n'), Buffer.from(`${pdf.length}\n`), Buffer.from('%%EOF')]);
return Buffer.concat([Buffer.from('xref\n'), Buffer.from(`${info.xref.startingIndex} 1\n`), Buffer.from(rows.join('\n')), Buffer.from('\ntrailer\n'), Buffer.from('<<\n'), Buffer.from(`/Size ${info.xref.maxIndex + 1}\n`), Buffer.from(`/Root ${info.rootRef}\n`), Buffer.from(info.infoRef ? `/Info ${info.infoRef}\n` : ''), Buffer.from(`/Prev ${info.xRefPosition}\n`), Buffer.from('>>\n'), Buffer.from('startxref\n'), Buffer.from(`${pdf.length}\n`), Buffer.from('%%EOF')]);
};

var _default = createBufferTrailer;
Expand Down
31 changes: 21 additions & 10 deletions dist/helpers/plainAddPlaceholder/readPdf.js
Expand Up @@ -11,6 +11,22 @@ var _findObject = _interopRequireDefault(require("./findObject"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const getValue = (trailer, key) => {
let index = trailer.indexOf(key);

if (index === -1) {
return undefined;
}

const slice = trailer.slice(index);
index = slice.indexOf('/', 1);

if (index === -1) {
index = slice.indexOf('>', 1);
}

return slice.slice(key.length + 1, index).toString().trim(); // key + at least one space
};
/**
* Simplified parsing of a PDF Buffer.
* Extracts reference table, root info and trailer start.
Expand All @@ -19,6 +35,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
*
* @param {Buffer} pdfBuffer
*/


const readPdf = pdfBuffer => {
// Extract the trailer dictionary.
const trailerStart = pdfBuffer.lastIndexOf('trailer'); // The trailer is followed by xref. Then an EOF. EOF's length is 6 characters.
Expand All @@ -27,21 +45,14 @@ const readPdf = pdfBuffer => {
let xRefPosition = trailer.slice(trailer.lastIndexOf('startxref') + 10).toString();
xRefPosition = parseInt(xRefPosition);
const refTable = (0, _readRefTable.default)(pdfBuffer);
let rootSlice = trailer.slice(trailer.indexOf('/Root'));
let rootIndex = rootSlice.indexOf('/', 1);

if (rootIndex === -1) {
rootIndex = rootSlice.indexOf('>', 1);
}

rootSlice = rootSlice.slice(0, rootIndex);
const rootRef = rootSlice.slice(6).toString().trim(); // /Root + at least one space

const rootRef = getValue(trailer, '/Root');
const root = (0, _findObject.default)(pdfBuffer, refTable, rootRef).toString();
const infoRef = getValue(trailer, '/Info');
return {
xref: refTable,
rootRef,
root,
infoRef,
trailerStart,
previousXrefs: [],
xRefPosition
Expand Down
16 changes: 16 additions & 0 deletions dist/signpdf.js
Expand Up @@ -3,6 +3,11 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
var _exportNames = {
DEFAULT_BYTE_RANGE_PLACEHOLDER: true,
SignPdf: true,
SignPdfError: true
};
Object.defineProperty(exports, "SignPdfError", {
enumerable: true,
get: function () {
Expand All @@ -17,6 +22,17 @@ var _SignPdfError = _interopRequireDefault(require("./SignPdfError"));

var _helpers = require("./helpers");

Object.keys(_helpers).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _helpers[key];
}
});
});

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const DEFAULT_BYTE_RANGE_PLACEHOLDER = '**********';
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "node-signpdf",
"version": "1.3.2",
"version": "1.3.3",
"description": "Simple signing of PDFs in node.",
"repository": {
"type": "git",
Expand Down
Binary file added resources/no-metadata.pdf
Binary file not shown.
4 changes: 2 additions & 2 deletions src/helpers/plainAddPlaceholder/createBufferTrailer.js
Expand Up @@ -15,9 +15,9 @@ const createBufferTrailer = (pdf, info, addedReferences) => {
Buffer.from('\ntrailer\n'),
Buffer.from('<<\n'),
Buffer.from(`/Size ${info.xref.maxIndex + 1}\n`),
Buffer.from(`/Prev ${info.xRefPosition}\n`),
Buffer.from(`/Root ${info.rootRef}\n`),
Buffer.from('/Info 15 0 R\n'),
Buffer.from(info.infoRef ? `/Info ${info.infoRef}\n` : ''),
Buffer.from(`/Prev ${info.xRefPosition}\n`),
Buffer.from('>>\n'),
Buffer.from('startxref\n'),
Buffer.from(`${pdf.length}\n`),
Expand Down
26 changes: 19 additions & 7 deletions src/helpers/plainAddPlaceholder/readPdf.js
@@ -1,6 +1,21 @@
import readRefTable from './readRefTable';
import findObject from './findObject';

const getValue = (trailer, key) => {
let index = trailer.indexOf(key);

if (index === -1) {
return undefined;
}

const slice = trailer.slice(index);
index = slice.indexOf('/', 1);
if (index === -1) {
index = slice.indexOf('>', 1);
}
return slice.slice(key.length + 1, index).toString().trim(); // key + at least one space
};

/**
* Simplified parsing of a PDF Buffer.
* Extracts reference table, root info and trailer start.
Expand All @@ -20,19 +35,16 @@ const readPdf = (pdfBuffer) => {
xRefPosition = parseInt(xRefPosition);
const refTable = readRefTable(pdfBuffer);

let rootSlice = trailer.slice(trailer.indexOf('/Root'));
let rootIndex = rootSlice.indexOf('/', 1);
if (rootIndex === -1) {
rootIndex = rootSlice.indexOf('>', 1);
}
rootSlice = rootSlice.slice(0, rootIndex);
const rootRef = rootSlice.slice(6).toString().trim(); // /Root + at least one space
const rootRef = getValue(trailer, '/Root');
const root = findObject(pdfBuffer, refTable, rootRef).toString();

const infoRef = getValue(trailer, '/Info');

return {
xref: refTable,
rootRef,
root,
infoRef,
trailerStart,
previousXrefs: [],
xRefPosition,
Expand Down
1 change: 1 addition & 0 deletions src/signpdf.js
Expand Up @@ -3,6 +3,7 @@ import SignPdfError from './SignPdfError';
import {removeTrailingNewLine, findByteRange} from './helpers';

export {default as SignPdfError} from './SignPdfError';
export * from './helpers';

export const DEFAULT_BYTE_RANGE_PLACEHOLDER = '**********';

Expand Down
15 changes: 15 additions & 0 deletions src/signpdf.test.js
Expand Up @@ -172,6 +172,21 @@ describe('Test signing', () => {
expect(typeof signature === 'string').toBe(true);
expect(signedData instanceof Buffer).toBe(true);
});
it('signs a ready pdf that does not have metadata', async () => {
const p12Buffer = fs.readFileSync(`${__dirname}/../resources/certificate.p12`);
let pdfBuffer = fs.readFileSync(`${__dirname}/../resources/no-metadata.pdf`);

pdfBuffer = plainAddPlaceholder({
pdfBuffer,
reason: 'I have reviewed it.',
signatureLength: 1612,
});
pdfBuffer = signer.sign(pdfBuffer, p12Buffer);

const {signature, signedData} = extractSignature(pdfBuffer);
expect(typeof signature === 'string').toBe(true);
expect(signedData instanceof Buffer).toBe(true);
});
it('signs a ready pdf two times', async () => {
const secondP12Buffer = fs.readFileSync(`${__dirname}/../resources/withpass.p12`);
let signedPdfBuffer = fs.readFileSync(`${__dirname}/../resources/signed-once.pdf`);
Expand Down
70 changes: 38 additions & 32 deletions yarn.lock
Expand Up @@ -1542,14 +1542,15 @@ browserify-optional@^1.0.0, browserify-optional@^1.0.1:
browser-resolve "^1.8.1"

browserslist@^4.12.0, browserslist@^4.8.5:
version "4.14.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.0.tgz#2908951abfe4ec98737b72f34c3bcedc8d43b000"
integrity sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==
version "4.16.6"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==
dependencies:
caniuse-lite "^1.0.30001111"
electron-to-chromium "^1.3.523"
escalade "^3.0.2"
node-releases "^1.1.60"
caniuse-lite "^1.0.30001219"
colorette "^1.2.2"
electron-to-chromium "^1.3.723"
escalade "^3.1.1"
node-releases "^1.1.71"

bser@2.1.1:
version "2.1.1"
Expand Down Expand Up @@ -1593,10 +1594,10 @@ camelcase@^5.0.0, camelcase@^5.3.1:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==

caniuse-lite@^1.0.30001111:
version "1.0.30001113"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001113.tgz#22016ab55b5a8b04fa00ca342d9ee1b98df48065"
integrity sha512-qMvjHiKH21zzM/VDZr6oosO6Ri3U0V2tC015jRXjOecwQCJtsU5zklTNTk31jQbIOP8gha0h1ccM/g0ECP+4BA==
caniuse-lite@^1.0.30001219:
version "1.0.30001228"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa"
integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==

capture-exit@^2.0.0:
version "2.0.0"
Expand Down Expand Up @@ -1709,6 +1710,11 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=

colorette@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==

combined-stream@^1.0.6, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
Expand Down Expand Up @@ -1986,10 +1992,10 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0"
safer-buffer "^2.1.0"

electron-to-chromium@^1.3.523:
version "1.3.528"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.528.tgz#9d815a1ab50d2e90755116fd6e02c3c5bdddf7db"
integrity sha512-PEwLXeD679xF6+hYL32QBMzpyEr/H2v/K2v8N0ANkVvSrw2kblSgM7xmLYvzQTUy9d6V5SeV89lbwFqpatNqmw==
electron-to-chromium@^1.3.723:
version "1.3.738"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.738.tgz#aec24b091c82acbfabbdcce08076a703941d17ca"
integrity sha512-vCMf4gDOpEylPSLPLSwAEsz+R3ShP02Y3cAKMZvTqule3XcPp7tgc/0ESI7IS6ZeyBlGClE50N53fIOkcIVnpw==

emoji-regex@^7.0.1:
version "7.0.3"
Expand Down Expand Up @@ -2093,10 +2099,10 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.1, es6-symbol@~3.1.3:
d "^1.0.1"
ext "^1.1.2"

escalade@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4"
integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==

escape-string-regexp@^1.0.5:
version "1.0.5"
Expand Down Expand Up @@ -2763,9 +2769,9 @@ homedir-polyfill@^1.0.1:
parse-passwd "^1.0.0"

hosted-git-info@^2.1.4:
version "2.8.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==

html-encoding-sniffer@^1.0.2:
version "1.0.2"
Expand Down Expand Up @@ -3699,9 +3705,9 @@ lodash.unescape@4.0.1:
integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=

lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.19:
version "4.17.19"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==

log-driver@^1.2.7:
version "1.2.7"
Expand Down Expand Up @@ -3917,10 +3923,10 @@ node-notifier@^5.4.2:
shellwords "^0.1.1"
which "^1.3.0"

node-releases@^1.1.60:
version "1.1.60"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084"
integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==
node-releases@^1.1.71:
version "1.1.72"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe"
integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==

normalize-package-data@^2.3.2:
version "2.5.0"
Expand Down Expand Up @@ -5483,9 +5489,9 @@ xtend@^4.0.2, xtend@~4.0.1:
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==

y18n@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
version "4.0.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==

yargs-parser@^13.1.2:
version "13.1.2"
Expand Down

0 comments on commit 5f784b9

Please sign in to comment.