views:

183

answers:

6

Imagine I have some file data in a variable $data. I need to determine whether it is an image or not. No need for details such as corrupt images etc.

Firs thought would be getting the file mime type by looking at the magic number and then see whether "image" is in the mime type.

No such luck, even if I have a "file extension to mime type" script, I don't have a reliable way to get mime from magic number.

My next option was to have a reasonable list of image file magic numbers and consult them. However, it relatively difficult to find such magic numbers (gif for instance has different magic numbers, some of which could pretty rare - if memory serves me right).

A better idea would be some linux program which can do this kind of thing.

Any ideas? I'm running RHEL and PHP 5.3. I've got root access - ie able to install stuff if needed.

- Chris.

+3  A: 

The standard file utility might be what you're looking for. It uses a table of magic numbers to identify the file format:

$ file test.jpg 
test.jpg: JPEG image data, JFIF standard 1.01

If you don't wish to create a temporary file, you can use file - and pipe the data into its stdin. Make sure you watch for the termination of the child process, because file will write its output and stop as soon as it has read enough of your stream to be certain of the format.

Greg Hewgill
I think this is the best answer in my case. The - tip is especially useful. I've done this kind of thing in the past, and have the right code to get this working.Thanks.
Christian Sciberras
PHP implements its own wrapper around the libmagic database - see the FileInfo functions.
symcbean
+1  A: 

I think standard getimagesize() is enough.
Of course it require a file, bit it isn't a big deal.

Col. Shrapnel
If it didn't require a file I'd definitely use it.Of course there's imagecreatefromstring; I'll give it a try first.
Christian Sciberras
+2  A: 

There also was finfo: http://php.net/manual/en/function.finfo-open.php Lots of working code on this php.net manual page.

Additionally you can check first 3-bytes of your data stream, there should be image file header data which identifies image file format.

Andy
Identifying the header data (first part known as magic number) was my problem.
Christian Sciberras
Let's say that you looking for jpeg, gif and png images only. I just opened png in hex editor and found that first 4 bytes of PNG is: 0x89 P N G, for GIF the first 3 bytes is exactly GIF, jpeg is more complex but if you will compare a few jpeg's you will find that 7-10 bytes are always JFIF. I think file utility works same way.
Andy
+3  A: 

The best answer (which I've determined from Col. Shrapnel) would be the use of:

$handle=imagecreatefromstring($data);

Quoting the PHP manual:

An image resource will be returned on success. FALSE is returned if the image type is unsupported, the data is not in a recognised format, or the image is corrupt and cannot be loaded.

Christian Sciberras
Seems to be a good plain PHP solution!
powtac
+1  A: 

If I were you I'd avoid using the imagecreatefromstring solution if you only need to determine if it is an image because this would use additional memory when creating the image resource. Also it would only support JPEG, PNG, GIF, WBMP, and GD2. while other equally valid image formats would not be valid, eg. ICO.

I would use finfo as suggested or if you don't have the PECL extensions, I'd recommend file -bi image.... As it would return the content-type, eg. image/png. You can just check if it starts with image/*. This way your script would accept any image format.

mqchen
Since I'll be editing these images later and need GD support, that function makes more sense since I know for sure the image will be supported.If I needed to support more realistic types, such as ico or svg etc, I'll definitely use "file -bi" as you said.Thanks for the tip.
Christian Sciberras
A: 

You can read this article in order to get some additional ideas.
Good luck

Bakhtiyor
Even though the article is useful, it is not the case. First of, it is completely unrelated.My issue isn't about security, but rather about correctly determining whether a file data is valid or not.One of the good things about my implementation is that the user/attacker can't execute the PHP since the data is in a string (and unlike generic webservers, I'm not dumb enough to execute any string I come in contact with ;) ).
Christian Sciberras
I see, so have a luck on solving ur problem.
Bakhtiyor