Skip to content

Commit

Permalink
Let libvips check whether we received a valid image or not
Browse files Browse the repository at this point in the history
This removes the custom image fingerprinting code and uses the libvips
is_a_buffer() infrastructure instead.
  • Loading branch information
mcuelenaere committed Mar 1, 2015
1 parent 1f7e80e commit 2da4d7c
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 51 deletions.
17 changes: 1 addition & 16 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,22 +73,7 @@ var Sharp = function(input) {
this.options.fileIn = input;
} else if (typeof input === 'object' && input instanceof Buffer) {
// input=buffer
if (
(input.length > 3) &&
// JPEG
(input[0] === 0xFF && input[1] === 0xD8) ||
// PNG
(input[0] === 0x89 && input[1] === 0x50) ||
// WebP
(input[0] === 0x52 && input[1] === 0x49) ||
// TIFF
(input[0] === 0x4D && input[1] === 0x4D && input[2] === 0x00 && (input[3] === 0x2A || input[3] === 0x2B)) ||
(input[0] === 0x49 && input[1] === 0x49 && (input[2] === 0x2A || input[2] === 0x2B) && input[3] === 0x00)
) {
this.options.bufferIn = input;
} else {
throw new Error('Buffer contains an unsupported image format. JPEG, PNG, WebP and TIFF are currently supported.');
}
this.options.bufferIn = input;
} else {
// input=stream
this.options.streamIn = true;
Expand Down
42 changes: 23 additions & 19 deletions src/common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,40 @@ namespace sharp {
return EndsWith(str, ".tif") || EndsWith(str, ".tiff") || EndsWith(str, ".TIF") || EndsWith(str, ".TIFF");
}

// Buffer content checkers
unsigned char const MARKER_JPEG[] = {0xff, 0xd8};
unsigned char const MARKER_PNG[] = {0x89, 0x50};
unsigned char const MARKER_WEBP[] = {0x52, 0x49};

static bool buffer_is_tiff(char *buffer, size_t len) {
return (
len >= 4 && (
(buffer[0] == 'M' && buffer[1] == 'M' && buffer[2] == '\0' && (buffer[3] == '*' || buffer[3] == '+')) ||
(buffer[0] == 'I' && buffer[1] == 'I' && (buffer[2] == '*' || buffer[2] == '+') && buffer[3] == '\0')
)
);
}

/*
Determine image format of a buffer.
*/
ImageType DetermineImageType(void *buffer, size_t const length) {
ImageType imageType = ImageType::UNKNOWN;
if (length >= 4) {
if (memcmp(MARKER_JPEG, buffer, 2) == 0) {
#if (VIPS_MAJOR_VERSION >= 8)
if (vips_foreign_is_a_buffer("jpegload_buffer", buffer, length)) {
imageType = ImageType::JPEG;
} else if (vips_foreign_is_a_buffer("pngload_buffer", buffer, length)) {
imageType = ImageType::PNG;
} else if (vips_foreign_is_a_buffer("webpload_buffer", buffer, length)) {
imageType = ImageType::WEBP;
} else if (vips_foreign_is_a_buffer("tiffload_buffer", buffer, length)) {
imageType = ImageType::TIFF;
} else if(vips_foreign_is_a_buffer("magickload_buffer", buffer, length)) {
imageType = ImageType::MAGICK;
}
#else
const char* loader = vips_foreign_find_load_buffer(buffer, length);

if (loader != NULL) {
if (!strcmp(loader, "VipsForeignLoadJpegBuffer")) {
imageType = ImageType::JPEG;
} else if (memcmp(MARKER_PNG, buffer, 2) == 0) {
} else if (!strcmp(loader, "VipsForeignLoadPngBuffer")) {
imageType = ImageType::PNG;
} else if (memcmp(MARKER_WEBP, buffer, 2) == 0) {
} else if (!strcmp(loader, "VipsForeignLoadWebpBuffer")) {
imageType = ImageType::WEBP;
} else if (buffer_is_tiff(static_cast<char*>(buffer), length)) {
} else if (!strcmp(loader, "VipsForeignLoadTiffBuffer")) {
imageType = ImageType::TIFF;
} else if (!strcmp(loader, "VipsForeignLoadMagickBuffer")) {
imageType = ImageType::MAGICK;
}
}
#endif
return imageType;
}

Expand Down
28 changes: 12 additions & 16 deletions test/unit/io.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,27 +202,23 @@ describe('Input/output', function() {
});

it('Fail when input is empty Buffer', function(done) {
var failed = true;
try {
sharp(new Buffer(0));
failed = false;
} catch (err) {
sharp(new Buffer(0)).toBuffer().then(function () {
assert(false);
done();
}).catch(function (err) {
assert(err instanceof Error);
}
assert(failed);
done();
done();
});
});

it('Fail when input is invalid Buffer', function(done) {
var failed = true;
try {
sharp(new Buffer([0x1, 0x2, 0x3, 0x4]));
failed = false;
} catch (err) {
sharp(new Buffer([0x1, 0x2, 0x3, 0x4])).toBuffer().then(function () {
assert(false);
done();
}).catch(function (err) {
assert(err instanceof Error);
}
assert(failed);
done();
done();
});
});

it('Promises/A+', function(done) {
Expand Down

0 comments on commit 2da4d7c

Please sign in to comment.