View Full Version : When exactly does getimagesize return false?
Jesdisciple
02-15-2011, 08:23 PM
I have getimagesize returning false after an upload. I used set_error_handler('errors', -1) to ensure no error is being thrown to help me know the problem. As far as I can ascertain, the PHP manual doesn't specify situations where false is returned but no errors are thrown. Can anyone shed some light for me?
More generally, is getimagesize even a good function for checking the success of an image upload? I have a bug I'm trying to fix in code written by someone else, involving this function.
Thanks for any advice.
bluewalrus
02-15-2011, 08:26 PM
Just put the move file function in a conditional or post your code and we can provide examples.
Jesdisciple
02-15-2011, 08:45 PM
The algorithm is based on this (http://castlesblog.com/2010/july/13/html5-drag-drop-upload), but the code I'm asking about was added to that:
if(getimagesize($_FILES['upload']['tmp_name']) == FALSE){
if(isset($_GET['base64'])){ /* The former developer suspected Firefox of inappropriately sending the images as base64 thereby triggering the outer conditional. */
echo "TESTING";
}else{
$firephp->log(file_exists($_FILES['upload']['tmp_name'])); // 1
echo "error"; // JavaScript interprets this as a failed upload.
die();
}
}
I hope that's enough information, as a minimal test case would be difficult to make.
getimagesize() is overkill if all you're trying to do is confirm an upload. If you also need to make sure the image is a particular format, dimension, etc. etc., then it's perfect.
Either way, I would confirm that the file was uploaded before using getimagesize(). That way, you can avoid the processing overhead if there's no file.
To answer you original question, getimagesize() returns false "on failure." that could mean that the file didn't exist, was unreadable (e.g., insufficient permissions), was not a supported image format, or some other problem.
djr33
02-15-2011, 10:06 PM
Do you need to check whether it's a valid image or just that a file exists? As traq said, it's overkill to use this if you don't need to verify it, but you do need to verify it, then I could post some code that might help.
Jesdisciple
02-16-2011, 12:27 AM
I've confirmed the previous developer's hunch that Firefox is sometimes sending images in base 64, and that's (by mechanics I don't understand) what triggers the false result from getimagesize. I think other cases are accounted for by this particular check (and not code that executes before it), so...
Yes, I'll be using the above or similar code to validate the file. Currently I have the base 64 check inside this one (using a regex to check for a base64 MIME type in the image data), although I might should move it up in the source?
djr33
02-16-2011, 12:54 AM
That's weird. I've never encountered Base 64 for uploads. It looks like the script you linked to is probably right since I've never dealt with that type of upload, but I'm not sure how to help.
Of course base64_decode() is available... would that help at all?
I've never heard of (or had problems with) Firefox uploading images using base64 either.
Jesdisciple
02-17-2011, 05:49 PM
Sorry I took so long to get back. I'm posting the modified PHP for review and reuse.
In Firefox and other browsers that support sendAsBinary:
$ext = strtolower(getExtension($_FILES['upload']['name']));
$theFileName = strtolower($_FILES['upload']['name']);
$size = filesize($_FILES['upload']['tmp_name']);
if ($size > config::max_size * 1024){
echo "Error: ".$theFileName." is too big";
die();
}
if (($ext != "jpg") && ($ext != "jpeg") && ($ext != "png") && ($ext != "gif")){
echo "Error: ".$theFileName." is not a supported file type";
die();
}
if(getimagesize($_FILES['upload']['tmp_name']) == FALSE){
if(isset($_GET['base64'])){
echo "TESTING";
}else if(0 < preg_match('/^data:image\/.+?;base64,/', file_get_contents($_FILES['upload']['tmp_name']))){
$contents = file_get_contents($_FILES['upload']['tmp_name']);
file_put_contents($_FILES['upload']['tmp_name'], base64_decode(preg_replace('/^data:image\/.+?;base64,/', '', $contents)));
$size = filesize($_FILES['upload']['tmp_name']);
}else{
echo "Error: Unknown";
die();
}
}
and for Chrome (which always sends in base64 but, I've discovered, sometimes prefixes the data with the MIME type) and any other browsers that put the image data in php://input rather than $_FILES:
if(isset($_GET['base64'])) {
$content = file_get_contents('php://input');
if(0 < preg_match('/^data:image\/.+?;base64,/', $content, $matches)){
$content = preg_replace('/^data:image\/.+?;base64,/', '', $content);
}
$content = base64_decode($content);
} else { // not sure this can ever happen...
$content = file_get_contents('php://input');
if(0 < preg_match('/^data:image\/.+?;base64,/', $content, $matches)){
$content = base64_decode(preg_replace('/^data:image\/.+?;base64,/', '', $content));
}
}
$headers = getallheaders(); // UP-* headers are sent by JavaScript
$headers = array_change_key_case($headers, CASE_UPPER); //different case was being used for different browsers
$ext = strtolower(getExtension($headers['UP-FILENAME']));
$size = $headers['UP-SIZE'];
if (($ext != "jpg") && ($ext != "jpeg") && ($ext != "png") && ($ext != "gif")){
echo "Error: ".$theFileName." is too big";
die();
}
if ($size > config::max_size * 1024){
echo "Error: ".$theFileName." is not a supported file type";
die();
}
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.