0

I´m using this php code to upload images to a folder but I would like to allow pdf files to be uploaded also, so I modified a little the code:

<?php

    $target_dir = "extra_images/";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $uploadOk = 1;
    $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
    $textFileType = pathinfo($target_file,PATHINFO_EXTENSION);

    // Check if image file is a actual image or fake image
    if(isset($_POST["submit"])) {
        $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
            if($check !== false) {
             //echo "<div class=\"alert alert-success\" role=\"alert\"><strong><span class=\"glyphicon glyphicon-ok\" aria-hidden=\"true\"></span> Correct image type.</strong></div>";
                    $uploadOk = 1;
                } else {
                    echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>File is not an image.</strong></div>";
                    $uploadOk = 0;
                }
            }
            // Check if file already exists
            if (file_exists($target_file)) {
                echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>File already exists.</strong></div>";
                $uploadOk = 0;
            }
            // Check file size
            if ($_FILES["fileToUpload"]["size"] > 3750000) {
                echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>Your file is too large.</strong></div>";
                $uploadOk = 0;
            }
            // Allow certain file formats
            if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg" && $imageFileType != "gif" && $textFileType != "pdf" ) {
                echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>Only jpg, jpeg, png, gif and pdf (for the Plan Article) files are allowed.</strong></div>";
                $uploadOk = 0;
            }
            // Check if $uploadOk is set to 0 by an error
            if ($uploadOk == 0) {
                echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>The file was not uploaded.</strong></div>";
            // if everything is ok, try to upload file
            } else {
                if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {

                    echo "<div class=\"alert alert-success\" role=\"alert\">The file <strong>". basename( $_FILES["fileToUpload"]["name"]). "</strong> has been uploaded.</div><br>Please copy this filename: <span class=\"form-inline\"><input type=\"text\" value=\"". basename( $_FILES["fileToUpload"]["name"]). "\" class=\"form-control input-sm\" style=\"width:220px;\" /></span> And paste it in an empty Extra image field above and save the form.";
                } else {
                    echo "<div class=\"alert alert-danger\" role=\"alert\">There was an error uploading your file.</div>";
                }
    }
    echo "</br></br><p><button class=\"btn btn-default pull-right\" style=\"margin-right:5px;\" type=\"submit\" onclick=\"javascript:history.go(-1)\"><span class=\"glyphicon glyphicon-step-backward\" aria-hidden=\"true\"></span> Back</button></p>";
 ?>

I added this bit:

&& $textFileType != "pdf" and this: $textFileType = pathinfo($target_file,PATHINFO_EXTENSION);

But this changes I made are not working, it still returns the "this is not an image" message.

What part of the code identifies the filetype? is the $imageFileType a special variable that php uses to identify filetypes?

I´m really confused about this. Can anyone help?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

2 Answers2

0

The file type for pdfs is application/pdf if you want to check the extension.

However, while you can check file extensions, but that's not a very reliable way of identifying whether a file is a pdf or not (it's easy to change a file extension for just about any file, creating a huge security hole).

While there's nothing in php like getimagesize() for pdfs, you can still check the mime type which is a fairly good step in the process like so:

    if (!empty($_FILES['fileToUpload']['tmp_name'])) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mime = finfo_file($finfo, $_FILES['fileToUpload']['tmp_name']);
            if ($mime != 'application/pdf') {

                echo 'this is not a PDF file!';
                exit();
            }
nomistic
  • 2,902
  • 4
  • 20
  • 36
  • Thank you for the reply. I´ve tried your code but I can´t get it to work, I´m a php beginner...Probably I´ll look for a piece of code that does the mime verification for all file formats i´d like to allow. but for now would like to just have this one working since the upload page is only used by a very limited amount of people. – Frederico Lopes Jun 13 '15 at 14:01
  • This may have something to do with it `$_FILES['article_pdf']` if you haven't changed that. @FredericoLopes – Funk Forty Niner Jun 13 '15 at 14:10
  • @Fred-ii- Good spot. I copied this from some of my own code. Missed a variable – nomistic Jun 13 '15 at 15:17
  • @nomistic Let's see if the OP's winds will change ;-) – Funk Forty Niner Jun 13 '15 at 15:18
  • @FredericoLopes note that as I mentioned `getimagesize()` will not work for pdf files, and that this code above WILL work for all file types. I just gave you the pdf one because that was what you requested. – nomistic Jun 13 '15 at 16:59
0

Thank you for all the help, after some code wrestling here it is the final functional version:

<?php

            $target_dir = "extra_images/";
            $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
            $uploadOk = 1;
            $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);

            // Check if image file is a actual image or fake image
            /*if(isset($_POST["submit"])) {
                $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
                if($check !== false) {
                    //echo "<div class=\"alert alert-success\" role=\"alert\"><strong><span class=\"glyphicon glyphicon-ok\" aria-hidden=\"true\"></span> Correct image type.</strong></div>";
                    $uploadOk = 1;
                } else {
                    echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>File is not an image.</strong></div>";
                    $uploadOk = 0;
                }
            }*/
            // Check if file already exists
            if (file_exists($target_file)) {
                echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>File already exists.</strong></div>";
                $uploadOk = 0;
            }
            // Check file size
            if ($_FILES["fileToUpload"]["size"] > 3750000) {
                echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>Your file is too large.</strong></div>";
                $uploadOk = 0;
            }

            // Allow certain file formats
            /*if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg" && $imageFileType != "gif" ) {
                echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>Only jpg, jpeg, png, gif and pdf (for the Plan Article) files are allowed.</strong></div>";
                $uploadOk = 0;
            }*/

            //Check for pdf format
            if (!empty($_FILES['fileToUpload']['tmp_name'])) {
                $finfo = finfo_open(FILEINFO_MIME_TYPE);
                $mime = finfo_file($finfo, $_FILES['fileToUpload']['tmp_name']);
                if (($mime != 'application/pdf') && ($mime != 'image/jpg') && ($mime != 'image/jpeg') && ($mime != 'image/gif') && ($mime != 'image/png')) {

                    $uploadOk = 0;
                    echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>This file is not a valid file.</strong></div>";

                    //exit();

                }} //this bracket was missing I think



            // Check if $uploadOk is set to 0 by an error
            if ($uploadOk == 0) {
                echo "<div class=\"alert alert-danger\" role=\"alert\"><strong>The file was not uploaded.</strong></div>";
            // if everything is ok, try to upload file
            } else {
                if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {

                    echo "<div class=\"alert alert-success\" role=\"alert\">The file <strong>". basename( $_FILES["fileToUpload"]["name"]). "</strong> has been uploaded.</div><br>Please copy this filename: <span class=\"form-inline\"><input type=\"text\" value=\"". basename( $_FILES["fileToUpload"]["name"]). "\" class=\"form-control input-sm\" style=\"width:220px;\" /></span> And paste it in an empty Extra image field above and save the form.";
                } else {
                    echo "<div class=\"alert alert-danger\" role=\"alert\">There was an error uploading your file.</div>";
                }
            }
            echo "</br></br><p><button class=\"btn btn-default pull-right\" style=\"margin-right:5px;\" type=\"submit\" onclick=\"javascript:history.go(-1)\"><span class=\"glyphicon glyphicon-step-backward\" aria-hidden=\"true\"></span> Back</button></p>";

?>

Regarding the && / || issue, at first I also had the idea of using the || operator, I tried it and it did´t worked, probably because we are using the != to compare so if some file is NOT jpg, NOT pdf... and so on it is not allowed and gets the error message and the &uploadOK = 0 so won´t upload.

Looking at the code this is what is written but still goes against my logic :)

Thank you very much for the help ;)

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • Nice work. One thing that the w3schools site (it is a good place to start) doesn't cover is the security flaws in php itself. PHP is weakly typed which means that it keeps running in the background after many errors (especially those soft errors you see like "notice" or "warning"). I find it's a good idea to kill the script at any point of an error with an `exit();` just in case. I recommend looking over this: https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet – nomistic Jun 14 '15 at 12:41
  • Thanks! I used to know Pascal :) and C But these languages like Java and PHP leave me a bit confused, its so much things to have in consideration that I rarely can solve things by myself but its getting better ;) Do you think I can kill the script at the end, before the closing php tag? this script will work inside an iframe so the idea is to have it there for as many uploads as the user wants. – Frederico Lopes Jun 14 '15 at 13:39
  • I just mean after the errors, like these: `$uploadOk = 0;` This is a personal preference, but I generally like to generate an error, and then just stop the script with the `exit();` I'm not sure how much difference it makes (I'm not an ace; still learning here myself) but it makes me feel safer. If someone needs to upload more files, the script can start again. – nomistic Jun 14 '15 at 13:46
  • ok, I tried leaving the exit function where you placed it in the code but then it would not show the button, I could put the button inside every error message, after the echo and before the exit() or create a function with the button and call it before every exit()... I will investigate this. – Frederico Lopes Jun 14 '15 at 16:28
  • no worries, just a personal preference. the code you have is mostly fine. I just use it if I want the code to stop entirely. If the button is needed to show, then you need to place the line AFTER the button – nomistic Jun 15 '15 at 01:04