foliojs / png.js

A (animated) PNG decoder in JavaScript for the HTML5 canvas element and Node.js
http://devongovett.github.com/png.js
MIT License
491 stars 92 forks source link

Can't capture exceptions when adding "invalid" PNG to the document #53

Closed ddcovery closed 4 years ago

ddcovery commented 4 years ago

Trying to add a "problematic" PNG into a pdf causes an unmanaged exception in our application because pdfKit doesn't give us any way to capture the exception.

The problem is in the asynchronous API internally used to decode PNGs. Look this code into png-node.js file:

decodePixels(fn) {
    return zlib.inflate(this.imgData, (err, data) => {
       ...
      switch (data[pos++]) {
          ....
          default:
            throw new Error(`Invalid filter algorithm: ${data[pos - 1]}`);
     }
     ...
     return fn(pixels);
   }
} 

An internal throw new Error("invalid filter..:") is raised into the zlib.inflate callback causing NODE to capture it as an unmanaged exception.

Wrapping call into a try { } catch { } structure, doesn't help (because Inflate is called asynchronously )

try {
  pdf.image(imageFile, ...)
} catch(e){
  console.log("This message is not shown when an internal decode exception is raised");
}

In summary, calling image.decodePixels(function(data){...}) with problematic images can produce errors that are not "capturable" by the caller .

Only a comment: png-node.js API is asynchronows but without "error" management... that's really a bad library for a server side NODE application

you can find pieces of code like this:

PNG.decode = function(path, fn) {
  return fs.readFile(path, function(err, file) {
    var png;
    png = new PNG(file);
    return png.decode(function(pixels) {
      return fn(pixels);
   });
 });
};

As you can see, the "err" parameter in the callback is not treated properly and, in fact, the "fn" parameter doesn't expect to be informed about possible errors.

ddcovery commented 4 years ago

Sorry... this post was for the pdfkit project... :(