Skip to content

Commit

Permalink
Fetch the cross-reference stream object
Browse files Browse the repository at this point in the history
  • Loading branch information
vbuch committed Nov 29, 2023
1 parent 1c9e4c3 commit 0f1bf61
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
37 changes: 26 additions & 11 deletions packages/placeholder-plain/src/readRefTable.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import {SignPdfError} from '@signpdf/utils';
import xrefToRefMap from './xrefToRefMap';
import {findObjectAt} from './findObject';

export const getLastTrailerPosition = (pdf) => {
const trailerStart = pdf.lastIndexOf(Buffer.from('trailer', 'utf8'));
const trailer = pdf.slice(trailerStart, pdf.length - 6);

const xRefPosition = trailer
.slice(trailer.lastIndexOf(Buffer.from('startxref', 'utf8')) + 10)
.toString();

return parseInt(xRefPosition);
/**
* @param {Buffer} pdf
* @returns {number}
*/
export const getLastXrefPosition = (pdf) => {
const xRefPosition = pdf
.subarray(
pdf.lastIndexOf(Buffer.from('startxref', 'utf8')) + 10,
pdf.lastIndexOf(Buffer.from('%%EOF', 'utf8')),
)
.toString()
.trim();

const lastXrefPosition = parseInt(xRefPosition);
if (`${lastXrefPosition}` !== xRefPosition) {
throw new SignPdfError(
`Expected an integer startxref position but got ${xRefPosition} instead.`,
SignPdfError.TYPE_PARSE,
);
}
return lastXrefPosition;
};

/**
Expand Down Expand Up @@ -77,7 +90,9 @@ const readXrefTableAt = (pdfSlice, position) => {
* @param {number} _position
* @returns {GetXRefReturnType | null}
*/
const readXrefStreamAt = (_pdfSlice, _position) => {
const readXrefStreamAt = (pdfSlice, position) => {
const {dictionary: _d, stream: _s} = findObjectAt(pdfSlice, position);

throw new SignPdfError(
'Cross-Reference Streams not yet implemented.',
SignPdfError.TYPE_PARSE,
Expand Down Expand Up @@ -116,7 +131,7 @@ export const getXref = (pdf, position) => {
* @returns {GetFullXrefTableReturnType}
*/
export const getFullXrefTable = (pdf) => {
const lastTrailerPosition = getLastTrailerPosition(pdf);
const lastTrailerPosition = getLastXrefPosition(pdf);
const lastXrefTable = getXref(pdf, lastTrailerPosition);

if (lastXrefTable.prev === undefined) {
Expand Down
9 changes: 6 additions & 3 deletions packages/placeholder-plain/src/readRefTable.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import {readTestResource} from '@signpdf/internal-utils';
import {SignPdfError} from '@signpdf/utils';
import readRefTable, {getXref} from './readRefTable';
import readRefTable, {getFullXrefTable, getXref} from './readRefTable';

describe(getXref, () => {
describe(getFullXrefTable, () => {
it('works for #79', () => {
expect(getXref(readTestResource('issue-79-test.pdf'))).toBeTruthy();
expect(getFullXrefTable(readTestResource('issue-79-test.pdf'))).toBeTruthy();
});
});

describe(getXref, () => {
it('Throws an error when xref is not found at position', () => {
const pdf = Buffer.from('Not containing an X R E F.');
const position = 0;
Expand Down

0 comments on commit 0f1bf61

Please sign in to comment.