Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not search for a "trailer" word in placeholder-plain once the xref position is known #229

Merged
merged 5 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## [next]

* [placeholder-plain] Fix ability to add a placeholder to a file that contains the "trailer" keyword in plain text.

## [3.2.1]

* [signer-p12] Fixed JSDoc on the sign() method.
Expand Down
91 changes: 91 additions & 0 deletions packages/examples/src/multiple-signatures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
var fs = require('fs');
var path = require('path');
var plainAddPlaceholder = require('@signpdf/placeholder-plain').plainAddPlaceholder;
var signpdf = require('@signpdf/signpdf').default;
var P12Signer = require('@signpdf/signer-p12').P12Signer;

function buyerSign(pdfBuffer, targetPath) {
// Add a placeholder for John Doe - the customer
var pdfWithPlaceholder = plainAddPlaceholder({
pdfBuffer: pdfBuffer,
reason: 'Agrees to buy the truck trailer.',
contactInfo: '[email protected]',
name: 'John Doe',
location: 'Free Text Str., Free World',
});

// John signs the PDF
// certificate.p12 is the certificate that is going to be used to sign
var certificateBuffer = fs.readFileSync(path.join(__dirname, '/../../../resources/certificate.p12'));
var signer = new P12Signer(certificateBuffer);
return signpdf
.sign(pdfWithPlaceholder, signer)
.then(function (signedPdf) {
// signedPdf is a Buffer of an electronically signed PDF. Store it.
fs.writeFileSync(targetPath, signedPdf);

return signedPdf;
})
}

function sellerSign(pdfBuffer, targetPath) {
// Add a placeholder for John Doe - the customer
var pdfWithPlaceholder = plainAddPlaceholder({
pdfBuffer: pdfBuffer,
reason: 'Agrees to sell a truck trailer to John Doe.',
contactInfo: '[email protected]',
name: 'Thug Dealer',
location: 'Automotive Str., Free World',
});

// The seller signs the PDF
// bundle.p12 is the certificate bundle that is going to be used to sign
var certificateBuffer = fs.readFileSync(path.join(__dirname, '/../../../resources/bundle.p12'));
var signer = new P12Signer(certificateBuffer);
return signpdf
.sign(pdfWithPlaceholder, signer)
.then(function (signedPdf) {
// signedPdf is a Buffer of an electronically signed PDF. Store it.
fs.writeFileSync(targetPath, signedPdf);

return signedPdf;
})
}

/**
* John Doe is buying a truck trailer from Thug Dealer.
* The PDF is signed by both parties in two copies.
* The first copy is signed by John Doe and then by Thug Dealer.
* The second copy is signed by Thug Dealer and then by John Doe.
* 4 PDFs are created in the output folder.
*/
function work() {
// contributing.pdf is the "contract" they are going to sign.
var pdfBuffer = fs.readFileSync(path.join(__dirname, '/../../../resources/contributing.pdf'));

// A copy of the PDF is signed by the buyer and then by the seller.
buyerSign(
pdfBuffer,
path.join(__dirname, '/../output/multiple-signatures-buyer-seller-1.pdf'
))
.then(function (signedByCustomer) {
return sellerSign(
signedByCustomer,
path.join(__dirname, '/../output/multiple-signatures-buyer-seller-2.pdf')
);
});

// A copy of the PDF is signed by the seller and then by the buyer.
sellerSign(
pdfBuffer,
path.join(__dirname, '/../output/multiple-signatures-seller-buyer-1.pdf'
))
.then(function (signedBySeller) {
return buyerSign(
signedBySeller,
path.join(__dirname, '/../output/multiple-signatures-seller-buyer-2.pdf')
);
});
}

work();
10 changes: 5 additions & 5 deletions packages/placeholder-plain/dist/readRefTable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ export function getLastTrailerPosition(pdf: any): number;
export function getXref(pdf: any, position: any): {
size: any;
prev: string;
xRefContent: Map<any, any>;
xRefContent: Map<number, number>;
};
export function getFullXrefTable(pdf: Buffer): GetFullXrefTableReturnType;
export function getFullXrefTable(pdf: Buffer): FullXrefTable;
export default readRefTable;
export type GetFullXrefTableReturnType = Map<any, any>;
export type FullXrefTable = Map<number, number>;
export type ReadRefTableReturnType = {
startingIndex: number;
maxIndex: number;
offsets: GetFullXrefTableReturnType;
offsets: FullXrefTable;
};
/**
* @typedef {object} ReadRefTableReturnType
* @prop {number} startingIndex
* @prop {number} maxIndex
* @prop {GetFullXrefTableReturnType} offsets
* @prop {FullXrefTable} offsets
*/
/**
* @param {Buffer} pdfBuffer
Expand Down
2 changes: 1 addition & 1 deletion packages/placeholder-plain/dist/readRefTable.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 16 additions & 8 deletions packages/placeholder-plain/dist/readRefTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,31 +62,39 @@ const getXref = (pdf, position) => {
};

/**
* @typedef {Map<*, *>} GetFullXrefTableReturnType
* @typedef {Map<number, number>} FullXrefTable
*/

/**
* @param {Buffer} pdf
* @returns {GetFullXrefTableReturnType}
* @param {number} xRefPosition
* @returns {FullXrefTable}
*/
exports.getXref = getXref;
const getFullXrefTable = pdf => {
const lastTrailerPosition = getLastTrailerPosition(pdf);
const lastXrefTable = getXref(pdf, lastTrailerPosition);
const getFullXref = (pdf, xRefPosition) => {
const lastXrefTable = getXref(pdf, xRefPosition);
if (lastXrefTable.prev === undefined) {
return lastXrefTable.xRefContent;
}
const pdfWithoutLastTrailer = pdf.slice(0, lastTrailerPosition);
const partOfXrefTable = getFullXrefTable(pdfWithoutLastTrailer);
const partOfXrefTable = getFullXref(pdf, lastXrefTable.prev);
const mergedXrefTable = new Map([...partOfXrefTable, ...lastXrefTable.xRefContent]);
return mergedXrefTable;
};

/**
* @param {Buffer} pdf
* @returns {FullXrefTable}
*/
const getFullXrefTable = pdf => {
const lastTrailerPosition = getLastTrailerPosition(pdf);
return getFullXref(pdf, lastTrailerPosition);
};

/**
* @typedef {object} ReadRefTableReturnType
* @prop {number} startingIndex
* @prop {number} maxIndex
* @prop {GetFullXrefTableReturnType} offsets
* @prop {FullXrefTable} offsets
*/

/**
Expand Down
6 changes: 5 additions & 1 deletion packages/placeholder-plain/dist/xrefToRefMap.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export default xrefToRefMap;
declare function xrefToRefMap(xrefString: any): Map<any, any>;
/**
* @param {string} xrefString
* @returns {Map<number, number>}
*/
declare function xrefToRefMap(xrefString: string): Map<number, number>;
//# sourceMappingURL=xrefToRefMap.d.ts.map
2 changes: 1 addition & 1 deletion packages/placeholder-plain/dist/xrefToRefMap.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/placeholder-plain/dist/xrefToRefMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Object.defineProperty(exports, "__esModule", {
});
exports.default = void 0;
var _utils = require("@signpdf/utils");
/**
* @param {string} xrefString
* @returns {Map<number, number>}
*/
const xrefToRefMap = xrefString => {
const lines = xrefString.split('\n').filter(l => l !== '');
let index = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,39 @@ Object {
"startingIndex": 0,
}
`;

exports[`readRefTable Expects to merge correctly the refTable of resources 8`] = `
Object {
"maxIndex": 27,
"offsets": Map {
1 => 15,
2 => 89780,
3 => 265,
4 => 302,
5 => 27161,
6 => 55428,
7 => 72070,
8 => 378,
9 => 592,
10 => 764,
11 => 4338,
12 => 89711,
13 => 4443,
14 => 26241,
15 => 26484,
16 => 26817,
17 => 27302,
18 => 54210,
19 => 54444,
20 => 55060,
21 => 55560,
22 => 71288,
23 => 71522,
24 => 71742,
25 => 72781,
26 => 89525,
27 => 89643,
},
"startingIndex": 0,
}
`;
25 changes: 17 additions & 8 deletions packages/placeholder-plain/src/readRefTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,22 +82,22 @@ export const getXref = (pdf, position) => {
};

/**
* @typedef {Map<*, *>} GetFullXrefTableReturnType
* @typedef {Map<number, number>} FullXrefTable
*/

/**
* @param {Buffer} pdf
* @returns {GetFullXrefTableReturnType}
* @param {number} xRefPosition
* @returns {FullXrefTable}
*/
export const getFullXrefTable = (pdf) => {
const lastTrailerPosition = getLastTrailerPosition(pdf);
const lastXrefTable = getXref(pdf, lastTrailerPosition);
const getFullXref = (pdf, xRefPosition) => {
const lastXrefTable = getXref(pdf, xRefPosition);

if (lastXrefTable.prev === undefined) {
return lastXrefTable.xRefContent;
}
const pdfWithoutLastTrailer = pdf.slice(0, lastTrailerPosition);
const partOfXrefTable = getFullXrefTable(pdfWithoutLastTrailer);

const partOfXrefTable = getFullXref(pdf, lastXrefTable.prev);

const mergedXrefTable = new Map([
...partOfXrefTable,
Expand All @@ -107,11 +107,20 @@ export const getFullXrefTable = (pdf) => {
return mergedXrefTable;
};

/**
* @param {Buffer} pdf
* @returns {FullXrefTable}
*/
export const getFullXrefTable = (pdf) => {
const lastTrailerPosition = getLastTrailerPosition(pdf);
return getFullXref(pdf, lastTrailerPosition);
};

/**
* @typedef {object} ReadRefTableReturnType
* @prop {number} startingIndex
* @prop {number} maxIndex
* @prop {GetFullXrefTableReturnType} offsets
* @prop {FullXrefTable} offsets
*/

/**
Expand Down
1 change: 1 addition & 0 deletions packages/placeholder-plain/src/readRefTable.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ describe(readRefTable, () => {
'incrementally_signed.pdf',
'signed.pdf',
'w3dummy.pdf',
'issue-209-reason-includes-trailer-word.pdf',
].forEach((fileName) => {
const pdf = readTestResource(fileName);
const r = readRefTable(pdf);
Expand Down
4 changes: 4 additions & 0 deletions packages/placeholder-plain/src/xrefToRefMap.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import {SignPdfError} from '@signpdf/utils';

/**
* @param {string} xrefString
* @returns {Map<number, number>}
*/
const xrefToRefMap = (xrefString) => {
const lines = xrefString.split('\n').filter((l) => l !== '');

Expand Down
Binary file not shown.
Loading