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

Error when using node JS pdf-lib: Expected xref at NaN but found other content #249

Open
CristiCh opened this issue Apr 10, 2024 · 5 comments

Comments

@CristiCh
Copy link

CristiCh commented Apr 10, 2024

I am using pdf-lib in a node JS project and I get the same error when trying to modify the pdf. Does anyone know why this is happening? Thanks!

exports.transformPdf = onObjectFinalized({}, async (event) => {
    const bucket = admin.storage().bucket()
    const fileBucket = event.data.bucket; // Storage bucket containing the file.
    const filePath = event.data.name; // File path in the bucket.
    const contentType = event.data.contentType; // File content type.
    console.log(filePath);
    const file = await bucket.file(filePath);
    const fileDir = path.dirname(filePath);
    const fileBasename = path.basename(filePath);
    console.log(fileDir);
    if (fileDir != 'uploads') { return; }

    getRawBody(file.createReadStream())
    .then(async (pdfBuffer) => {
        console.log(pdfBuffer.length + ' bytes submitted');
        const pdfDoc = await PDFDocument.load(pdfBuffer, { capNumbers: true });
        console.log(pdfDoc);

        const timesRomanFont = await pdfDoc.embedFont(StandardFonts.TimesRoman);
        // const page = pdfDoc.addPage();
        const pagesCount = pdfDoc.getPageCount();
        const page = pdfDoc.getPage(pagesCount-1);
        const { width, height } = page.getSize();
        const fontSize = 20;
        page.drawText('Signed By Cristi C.', {
            x: width - 10 * fontSize,
            y: height - 40 * fontSize,
            size: fontSize,
            font: timesRomanFont,
            color: rgb(0, 0.53, 0.71),
        });
        const pdfBytes = await pdfDoc.save();
        bucket.file('transformed/'+fileBasename).save(pdfBytes).then(function (res) {}); //Save file in folder signed with the original name
        console.log('Document transformed');
    });

The error is: Expected xref at NaN but found other content

Thanks!

@Vanderson159
Copy link

I also came across this problem, did you find any solution?

@exilonX
Copy link

exilonX commented Nov 6, 2024

I'm having the same issue with PDF version 1.7 exported from sql reporting services.

Seems that the issue comes from how the trailer information is interpreted

1.4 from the contributing.pdf example :

trailer
<</Size 25
/Root 12 0 R
/Info 1 0 R>>
startxref
72203
%%EOF

1.7 example from my pdf

<< /Type /XRef 
/Index [0 50]
/W [1 4 3]
/Filter /FlateDecode /Size 50 /Length 195 /Root 47 0 R /Info 48 0 R >>
stream
X	c`
endstream
endobj
startxref
444002
%%EOF

SignPdfError: Expected xref at NaN but found other content.
at getXref (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:26:13)
at getFullXref (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:75:25)
at getFullXrefTable (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:90:10)
at readRefTable (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:106:25)
at readPdf (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readPdf.js:56:46)
at plainAddPlaceholder (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\plainAddPlaceholder.js:70:37)
at work (C:\Users\ionel\Desktop\code\reges\reges-process\scripts\test.js:32:28) {

My typescript code:

async signPdf(pdfBuffer: Buffer, pdfId: string): Promise<Buffer> {
  // Step 3: Add a signature placeholder using pdfkitAddPlaceholder
  try {
    const normalized = await this.addXrefTable(pdfBuffer);
    console.log(normalized.lastIndexOf('startxref'));
    const pdfWithPlaceholder = plainAddPlaceholder({
      pdfBuffer: normalized,
      reason: 'Document digitally signed',
      location: 'Location',
      contactInfo: '[email protected]',
      name: 'Signature',
      widgetRect: [100, 100, 300, 200], // Adjust coordinates as needed
      // signatureLength: 8192,
    });

    // Step 4: Generate signature hash from the external signing service
    const signatureHash = await this.generateSignature(pdfBuffer, pdfId);

    const signPdf = new SignPdf();
    const signedPdf = signPdf.sign(pdfWithPlaceholder, signatureHash);

    return signedPdf;
  } catch (error) {
    console.error('Error adding signature placeholder:', error);
    console.error(error);
  }
}

@rania-kouadri-aichouch
Copy link

I'm having the same issue with PDF version 1.7 exported from sql reporting services.

Seems that the issue comes from how the trailer information is interpreted

1.4 from the contributing.pdf example :

trailer
<</Size 25
/Root 12 0 R
/Info 1 0 R>>
startxref
72203
%%EOF

1.7 example from my pdf

<< /Type /XRef 
/Index [0 50]
/W [1 4 3]
/Filter /FlateDecode /Size 50 /Length 195 /Root 47 0 R /Info 48 0 R >>
stream
X	c`
endstream
endobj
startxref
444002
%%EOF

SignPdfError: Expected xref at NaN but found other content. at getXref (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:26:13) at getFullXref (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:75:25) at getFullXrefTable (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:90:10) at readRefTable (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:106:25) at readPdf (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readPdf.js:56:46) at plainAddPlaceholder (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\plainAddPlaceholder.js:70:37) at work (C:\Users\ionel\Desktop\code\reges\reges-process\scripts\test.js:32:28) {

My typescript code:

async signPdf(pdfBuffer: Buffer, pdfId: string): Promise<Buffer> {
  // Step 3: Add a signature placeholder using pdfkitAddPlaceholder
  try {
    const normalized = await this.addXrefTable(pdfBuffer);
    console.log(normalized.lastIndexOf('startxref'));
    const pdfWithPlaceholder = plainAddPlaceholder({
      pdfBuffer: normalized,
      reason: 'Document digitally signed',
      location: 'Location',
      contactInfo: '[email protected]',
      name: 'Signature',
      widgetRect: [100, 100, 300, 200], // Adjust coordinates as needed
      // signatureLength: 8192,
    });

    // Step 4: Generate signature hash from the external signing service
    const signatureHash = await this.generateSignature(pdfBuffer, pdfId);

    const signPdf = new SignPdf();
    const signedPdf = signPdf.sign(pdfWithPlaceholder, signatureHash);

    return signedPdf;
  } catch (error) {
    console.error('Error adding signature placeholder:', error);
    console.error(error);
  }
}

Hello did you find a solution for this , im working on the same thing -- signing

@Milad305
Copy link

I'm having the same issue with PDF version 1.7 exported from sql reporting services.

Seems that the issue comes from how the trailer information is interpreted

1.4 from the contributing.pdf example :

trailer
<</Size 25
/Root 12 0 R
/Info 1 0 R>>
startxref
72203
%%EOF

1.7 example from my pdf

<< /Type /XRef 
/Index [0 50]
/W [1 4 3]
/Filter /FlateDecode /Size 50 /Length 195 /Root 47 0 R /Info 48 0 R >>
stream
X	c`
endstream
endobj
startxref
444002
%%EOF

SignPdfError: Expected xref at NaN but found other content. at getXref (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:26:13) at getFullXref (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:75:25) at getFullXrefTable (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:90:10) at readRefTable (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readRefTable.js:106:25) at readPdf (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\readPdf.js:56:46) at plainAddPlaceholder (C:\Users\ionel\Desktop\code\reges\reges-process\node_modules@signpdf\placeholder-plain\dist\plainAddPlaceholder.js:70:37) at work (C:\Users\ionel\Desktop\code\reges\reges-process\scripts\test.js:32:28) {

My typescript code:

async signPdf(pdfBuffer: Buffer, pdfId: string): Promise<Buffer> {
  // Step 3: Add a signature placeholder using pdfkitAddPlaceholder
  try {
    const normalized = await this.addXrefTable(pdfBuffer);
    console.log(normalized.lastIndexOf('startxref'));
    const pdfWithPlaceholder = plainAddPlaceholder({
      pdfBuffer: normalized,
      reason: 'Document digitally signed',
      location: 'Location',
      contactInfo: '[email protected]',
      name: 'Signature',
      widgetRect: [100, 100, 300, 200], // Adjust coordinates as needed
      // signatureLength: 8192,
    });

    // Step 4: Generate signature hash from the external signing service
    const signatureHash = await this.generateSignature(pdfBuffer, pdfId);

    const signPdf = new SignPdf();
    const signedPdf = signPdf.sign(pdfWithPlaceholder, signatureHash);

    return signedPdf;
  } catch (error) {
    console.error('Error adding signature placeholder:', error);
    console.error(error);
  }
}

when a pdf is compressed this happens
some widgets and the xref table in compressed pdf are stream i,ve tried to decompress pdf with pako package but still its not working if any one has any solution ill be grateful to share it

@Milad305
Copy link

i found a way to bypass this problem
after reading pdf with
const pdf = PDFDocument.load(pdfContent);
const myPdf = await pdf.save({useObjectStreams:false});

useObjectStreams:false changes xref table stream to a regular xref table then you can use myPdf for sign without problem .
but still this is not a solution its better to stream support be added to package

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants