1

Dear StackOverflow Community,

I am facing an issue with zlib while attempting to rewrite a PDF file. Specifically, I am trying to convert FlateDecoded data back to normal data, but I keep encountering the "incorrect header check" error when using the zlib.inflate function.

My ultimate goal is to decrypt the data stream that is FlateDecoded. I have tried multiple approaches, including using

  • {deflate, inflate} from 'react-native-gzip',
  • pako library,
  • zlib from 'react-zlib-js', but the problem persists.

I have attempted different strategies such as converting the data into UInt8Array and inflating it with zlib, as well as converting it to hex and then attempting to inflate it. Unfortunately, none of these attempts have resolved the issue, and I still receive the same error. Also I tried to do it in Swift, but got the same output and same errors.

Here is a snippet of my current code:

import RNFS from 'react-native-fs';
import RNFetchBlob from 'rn-fetch-blob';
import { PDFDocument, } from 'pdf-lib'; 
import base64 from 'react-native-base64'; 
var Buffer = require('buffer').Buffer; 
import zlib from 'react-zlib-js'; 
var textEncoding = require('text-encoding'); 


export function rewritePDF(path) {
  return new Promise((resolve, reject) => {
    RNFS.readFile(path.replace('%20', ' '), 'base64').then(data => {
      const myNewPDFData = base64.decode(data);
      console.log(data);
      console.log(myNewPDFData);
      const pdfObjects = myNewPDFData.split(/(?<=\bobj\b)|(?=\bendobj\b)/g);
      console.log(pdfObjects);
      const flateDecodedData = pdfObjects[21];
      console.log(flateDecodedData);

      const pureStream = flateDecodedData.split(
        /(?<=\bstream\b)|(?=\bendstream\b)/g,
      )[1];
      let input = new Buffer(pureStream);
      console.log(input);
      console.log(pureStream);

      // zlib.inflate(pureStream, function (r, e) {
      //   if (e) {
      //     console.log(e);
      //     return;
      //   }
      //   console.log(r);
      // });

      // const hexPureStream = Buffer.from(pureStream, 'utf8').toString('hex');
      // console.log(hexPureStream.slice(2, hexPureStream.length - 2));

      // zlib.inflate(
      //   hexPureStream.slice(2, hexPureStream.length - 2),
      //   function (r, e) {
      //     if (e) {
      //       console.log(e);
      //       return;
      //     }
      //     console.log(r);
      //   },
      // ),
      //   zlib.deflate('test', function (e, r) {
      //     if (e) {
      //       console.log(e);
      //       return;
      //     }
      //     console.log(new TextDecoder().decode(r));

      //     zlib.inflate(r, function (err, res) {
      //       if (err) {
      //         console.log(e);
      //         return;
      //       }
      //       console.log(res);
      //       console.log(new TextDecoder().decode(res));
      //     });
      //   });

      let newData = base64.encode(myNewPDFData);
      PDFDocument.load(newData).then(async pdfDoc => {
        const pdfBytes = await pdfDoc.saveAsBase64();
        RNFetchBlob.fs
          .writeFile(
            path.replace('file://', '').replace('%20', ' '),
            pdfBytes,
            'base64',
          )
          .then(() => resolve(path))
          .catch(error => {
            console.log(error);
          });
      });
    });
  });
}

The 'data' from RNFS.readFile looks like this

The 'myNewPDFData' or decoded data looks like this

This is some of pdfObjects

This is one of FlatDecoded data

And this is pureStream

Also I checked

What does a zlib header look like?

zlib decompression failing

And some links on topic "How to decode FlateDecoded data".

I would greatly appreciate any guidance, insights, or alternative approaches to successfully decrypting my case.

react-native pdf zlib decoding

  • 1
    Not a JavaScript expert, but are you somehow putting the whole file through some sort of conversion to/from UTF8 or similar? That would account for the binary parts of the PDF being corrupted whilst the rest looks ok. Have you checked that the data matches the /Length, for example? If not, that's an indication something has gone wrong. – johnwhitington Aug 01 '23 at 18:45

0 Answers0