pdfmake icon indicating copy to clipboard operation
pdfmake copied to clipboard

Pdf files look identical, but base64 representation differs on node 16 and node 20

Open artemka-debug opened this issue 2 years ago • 1 comments

HI!

First of all, thank you for this library.

What is the problem?

Pdf files that were generated using node 16 and node 20 are not equal.

Prerequisites:

  1. pdfmake: ^0.2.7
  2. Use type: "module" in package.json
  3. nvm: 0.39.7
  4. Download this font - https://fonts.google.com/specimen/Roboto
  5. Create folder with index.js file and installed Roboto font folder in the root, so you have following structure:
  • folder
    • index.js
    • package.json
    • Roboto
      • Roboto-Bold.ttf

Steps to reproduce

  1. Paste following code in index.mjs file
import { writeFile } from 'fs/promises';
import PdfPrinter from 'pdfmake';

const pdfPrinter = new PdfPrinter({
  Roboto: {
    bold: 'Roboto/Roboto-Bold.ttf',
    bolditalics: 'Roboto/Roboto-BoldItalic.ttf',
    normal: 'Roboto/Roboto-Light.ttf',
    italics: 'Roboto/Roboto-Light.ttf',
  },
});

const doc = pdfPrinter.createPdfKitDocument({
  content: 'Hello world!',
  info: {
    creationDate: new Date('2024-01-24'),
  },
});

const pdf = await pdfStreamToBuffer(doc);
const base64Pdf = pdf.toString('base64');
await writeFile(process.argv[2], Buffer.from(base64Pdf, 'base64'));

async function pdfStreamToBuffer(stream) {
  return new Promise((resolve, reject) => {
    const buffer = [];

    stream.on('data', (chunk) => buffer.push(chunk));
    stream.on('end', () => resolve(Buffer.concat(buffer)));
    /* istanbul ignore next */
    stream.on('error', (err) => reject(`error converting stream - ${err}`));
    stream.end();
  });
}
  1. Install & use node 16
$ nvm install 16
$ nvm use 16
  1. Generate pdf file use node 16 and index.mjs script:
node index.mjs example-node-16.pdf
  1. Install & use node 20
$ nvm install 20
$ nvm use 20
  1. Generate pdf file use node 20 and index.mjs script:
node index.mjs example-node-20.pdf
  1. Create compare.mjs file:
import { readFile } from 'fs/promises';

const node16Pdf = await readFile(`./${process.argv[2]}`, 'base64');
const node20Pdf = await readFile(`./${process.argv[3]}`, 'base64');

console.log(node16Pdf === node20Pdf);
  1. Compare both files as base64 strings:
$ node index.mjs example-node-16.pdf example-node-20.pdf

This should output true to the console, but for some reason it outputs false.

Thanks for the help!

artemka-debug avatar Jan 24 '24 10:01 artemka-debug

+1, seeing something similar in my application

mdovhopo avatar Jan 25 '24 20:01 mdovhopo

Tested with versions 20.9.0 and 16.20.2. And both files are identical.

liborm85 avatar Jun 16 '24 12:06 liborm85