Best way to validate an upload form? - php

Which would be the best way to validate an upload form?
Using the mime type at the moment, but that's not quite working - can't upload mpegs even though am looking for video in the mime type.
Thank you
Tom

This seems to work:
switch (strtolower($_FILES["file"]["type"])){
case "application/msword":
case "application/pdf":
case "application/vnd.ms-excel":
case "application/vnd.ms-powerpoint":
case "application/zip":
case "image/gif":
case "image/jpeg":
case "image/png":
case "image/tiff":
case "text/plain":
case "video/mpeg":
case "video/x-mpeg2":
case "video/msvideo":
case "video/quicktime":
// do it
break;
default:
// don't do it
break;
}
For anyone else this might help have a look at http://www.sfsu.edu/training/mimetype.htm for adding other mime types you might need to check.

I guess you want to check if an uploaded file is a valid video-file. So one thing you can check is the file extension (IE ".mpg" for mpeg video). Because no webframework known to me has an internal video-validation, you have to rely on some external program/library to check if the video file is really a video-file. Maybe FFMPEG is able to do this.

Try something like so:
$mime = strtolower($_FILES["file"]["type"]);
$parts = explode("/",$mime);
switch($parts[0])
{
case 'video':
//Video file, use $parts[1] to check the video subtype
break;
case 'image':
break;
}

Related

Understanding if a file is an image or a video from its content

I can not find a way to understand if a file is really a video or an image.
For example: I have a .jpg image renamed .mp4, if I open it via computer or browser I can not see anything because it is not really a video.
What I'm looking for is a way to understand if a video / image beyond the required extension is also really a video or an image, depending on the request.
In theory I would like a similar result:
$ImageOrVideo = pathinfo($_FILES["file"]["tmp_name"],PATHINFO_EXTENSION);
switch($ImageOrVideo){
case 'jpg': //check if a real image
case 'mp4': // check if a real video
default: exit('stop');
}
I had thought of some solutions, for example in the past I had used for the images getimagesize (), but now the php documentation says:
Caution This function expects filename to be a valid image file. If a
non-image file is supplied, it may be incorrectly detected as an image
and the function will return successfully, but the array may contain
nonsensical values.
Do not use getimagesize() to check that a given file is a valid image.
Use a purpose-built solution such as the Fileinfo extension instead.
$ImageOrVideo = $_FILES["file"]["tmp_name"];
switch(mime_content_type($ImageOrVideo)){
case 'image/jpeg':
// ........
break;
case 'video/mp4':
// ........
break;
default:
exit('stop');
}

Check upload file , accept only file zip formats

In my project , there is a possibility to download/upload a backup of the project (with some configuration/images etc etc).
I have to accept only backups in .zip format (for the upload) , for this i used this code for check the format (client side and server side)
client side , with jQuery form
var ftype=$('#FileInput')[0].files[0].type;
switch(ftype){
case 'multipart/x-zip':
break;
case 'application/zip':
break;
case 'application/x-zip-compressed':
break;
case 'application/x-zip':
break;
default: .... //error type
}
server side
switch(strtolower($_FILES['FileInput']['type'])){
case 'multipart/x-zip':
break;
case 'application/zip':
break;
case 'application/x-zip-compressed':
break;
case 'application/x-zip':
break;
default: exit("1");
}
Every O.S has a different manner to recognize a .zip file (in fact in the switch there isn't the application/octet-stream case , and for this i decided to ask about this because a user tell me this problem).
So , the question is : where i can find a doc about this , or something where i can find a list of the various manner in which the O.S recognize a .zip file.
thanks

Imagecreatefromjpeg With Faulty File

im writing an script that resize and crops the uploaded images.
all valid files are ok...
but some of my visitors are trying to upload non-valid ones.. for example the file extension is jpg, but in fact its a tiff file .. the uploading file's extension looks gif, but in its exif details writes 'its a jpg'.. etc..
As you can imagine, imagecreatefromXX() functions are all giving error in that case (its not a valid jpg etc)..
do you have any idea, how may i solve this problem?
how must i modify my recent codes?
switch($type) {
case 'gif':
$img = imagecreatefromgif($source);
break;
case 'jpg':
case 'JPEG':
case 'jpeg':
$img = imagecreatefromjpeg($source);
break;
case 'png':
$img = imagecreatefrompng($source);
break;
}
Your best bet would probably be to modify the code that sets $type, rather than the code you've shared (though John Conde's suggestion to have a default case is a good one), and use something like exif_imagetype (which your question suggests might already be in play) to determine the type, rather than trusting the extension (which you may even want to change to the appropriate type when writing the file): the extension is user-supplied data, and as such, the least likely to be accurate and/or useful.
e.g.
$type = exif_imagetype($source);
switch ($type){
case IMAGETYPE_GIF:
$img = imagecreatefromgif($source);
break;
case IMAGETYPE_JPG:
$img = imagecreatefromjpeg($source);
break;
case IMAGETYPE_PNG:
... etc ...
default:
//Fail Gracefully
}

Get remote image with PHP and show it with GD

I have a code in my website to show remote Gravatar portraits or uploaded images. Uploaded is ok, but i can't get the gravatar images.
Cant use file_get_contents because it´s not allowed on my host.
Heres the start check for the file
if(file_exists($arUser['imagem'][0])){
$imgPath = $arUser['imagem'][0]; //Usar a imagem enviada
}elseif(!strlen($arUser['imagem'][0]) && checkRemoteFile('http://www.gravatar.com/avatar/'.md5($arUser['email'][0]).'fs=150')){
$imgPath = 'http://www.gravatar.com/avatar/'.md5($arUser['email'][0]).'fs=150';
}else
$imgPath = '../img/social_noavatar_150.jpg'; //Temporario
So this doesn´t work:
$imgData = getimagesize($imgPath);
$src = imagecreatefromwhatever($imgPath);
I know I should replace:
$imgPath = 'http://www.gravatar.com/avatar/'.md5($arUser['email'][0]).'fs=150';
with something like:
$imgPath = GetFileData('http://www.gravatar.com/avatar/'.md5($arUser['email'][0]).'fs=150');
or
*$imgPath = file_get_contents('http://www.gravatar.com/avatar/'.md5($arUser['email'][0]).'fs=150');*
Got error with both and I can´t create the image:
I´ve searched for the answer but the others didn't fited to me.
Sorry for my bad english. :(
Note:
function imagecreatefromwhatever($image){
$info = pathinfo($image);
$extension = strtolower($info['extension']);
switch($extension) {
case "jpg":
return imagecreatefromjpeg($image);
break;
case "jpeg":
return imagecreatefromjpeg($image);
break;
case "png":
return imagecreatefrompng($image);
break;
case "gif":
return imagecreatefromgif($image);
break;
default:
return imagecreatefromjpeg($image);
}
}
Well, if file_get_content is not available on your host, you might be out of luck. If this is a security feature on your host then you won't find a single function that allows you to get data from another server.
You might want to simply bypass the function and set your image src url to the gravatar one. Something like :
<img src="http://www.gravatar.com/avatar/<?=md5($arUser['email'][0]);?>&fs=150" width="150"/>
(Please double check the url, I added a & before the fs as it makes more sense, but I don't know how gravatar api url looks like)
This way it is the client browser that will make the request and not your server.
The easiest way I have found is to transfer the location:
if(checkRemoteFile('http://www.gravatar.com/avatar/'.md5($arUser['email'][0])))
header('Location: http://www.gravatar.com/avatar/'.md5($arUser['email'][0]).'fs='.$sizePic);
If your PHP security on your server prevents remote grabbing of files via file_get_contents(), then your next best option is a CURL call to get the file contents fed in perhaps.
If your host doesn't allow file_get_contents it's likely other methods will not work. From my experience the hosts will prevent any external socket connections from script. So check with the host first.
Assuming that is the issue, you could still echo out an tag with the src attribute to the same location you're trying to get in script.
<img src="<?php echo('http://www.gravatar.com/avatar/'.md5($arUser['email'][0]).'fs=150');?>" />
You could also use the same trick to put the url into a style if you don't want to use the tag.

PHP imagecreate() PNG from any commonly used file-format?

I currently have an image upload input that only accepts PNG, JPG/JPEG, GIF images.
If the file is valid, it then proceeds to create a thumbnail from the image using
imagecreatefrompng()
imagecopy()
imagejpg()
This works fine, but ONLY for png images, obviously.
What is the most logical and efficient way to use "imagecreatefrompng()" except using the proper file format that was submitted? All I can think of is if/else using multiple "imagecreatefrom__()" but that doesn't seem right.
Also, how can my outputted format always be PNG no matter what was submitted instead of the current imagejpg() I have now.
You will have to use a switch and determine the image type like so:
$extension = strtolower(strrchr($file, '.'));
switch ($extension) {
case '.jpg':
case '.jpeg':
$img = #imagecreatefromjpeg($file);
break;
case '.gif':
$img = #imagecreatefromgif($file);
break;
case '.png':
$img = #imagecreatefrompng($file);
break;
default:
$img = false;
break;
}
-EDIT- Didn't see the second part of your question, you just need to save it using imagepng to save it to a PNG, no need to do anything else.
Using imagecreatefromstring( file_get_contents( $filename)) would be the lazy option here.
And if you always want a png output, then just exchanging imagejpg for imagepng would do.

Categories