Sharp: Possible image data leak when resizing a transparent GIF

Created on 13 Aug 2018  路  7Comments  路  Source: lovell/sharp

Hi there,
I'm seeing leaked image data when resizing a transparent GIF image.

I'm unsure if this is a issue with sharp/vips or the loader that handles GIF images.
It looks like the content of resizes leak into the resize of transparent GIF images.

Here's the output of resizing one png and a gif multiple times:

(with flatten):
20180813-130825

(without flatten):
20180813-130801

After transforming the png, each transformation of the transparent gif leaks leaks some information. In this minimal case, it's pretty uncommon but we've seen worse in production.

Is this a known issue that once can possibly fix by using a different configuration?
Trying to reproduce it with a transparent png, it doesn't happen :thinking:

Here's the minimal setup for the above output (note it will result in slightly different images depending on your system).

const sharp = require("sharp");
const fs = require("fs");

const fA = "top-secret.png";
const fB = "transparent.gif";

let counter = 0;

function transform(fileName) {
  return new Promise(resolve => {
    const resizer = sharp()
      .flatten(true)
      .rotate()
      .toFormat("png")
      .resize(300, 400)
      .min()
      .crop(sharp.gravity.center);

    const writeStream = fs.createWriteStream(
      `./outputs/${fileName}.${counter}.png`
    );

    writeStream.on("close", () => {
      counter++;
      resolve();
    });

    fs.createReadStream(`./inputs/${fileName}`)
      .pipe(resizer)
      .pipe(writeStream);
  });
}

async function main() {
  await transform(fA);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
  await transform(fB);
}

main().catch(e => console.error(e));

Here are the given inputs:
transparent
top-secret

Do you have any ideas or suggestions on how to proceed with this?

Thanks

bug ready-to-ship

Most helpful comment

I added something to 0 pages before load, does that fix it?

All 7 comments

@jcupitt Should the logic for DISPOSE_DO_NOT in gifload set pixel values to zero when rendering the first frame, rather than the current approach of doing nothing?

I added something to 0 pages before load, does that fix it?

@jcupitt Thanks for the fast response John, your change looks good to me.

Thanks for the quick fix.

@jcupitt do you know if this fix will land in libvips 8.7.0 or is it outside the current release window?

It's just snuck under the wire, so yes, in 8.7.0. Assuming it works!

sharp v0.21.0 is now available with a prebuilt libvips v8.7.0 that contains the upstream fix.

Thanks,

I can confirm that it works with latest sharp + libvips.

Great job :+1:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kachurovskiy picture kachurovskiy  路  3Comments

henbenla picture henbenla  路  3Comments

knoxcard picture knoxcard  路  3Comments

paulieo10 picture paulieo10  路  3Comments

OleVik picture OleVik  路  3Comments