1

I am trying out PHP my first actual script, most of it from tutorial :( Anyway's

I am having a problem on this part

// This is our limit file type condition
if (!($uploaded_type=="text/java")||!($uploaded_type=="file/class")||!($uploaded_type=="file/jar")) {
echo "You may only upload Java files.<br>";

$ok=0;
}

Basically it doesn't allow any files, even those up there help! I want the Java files to be allowed only!

EDIT: Here is the full code

<?php
$target = "upload/";
$target = $target . basename( $_FILES['uploaded']['name']) ;
$uploaded = basename( $_FILES['uploaded']['name']) ;
$ok=1;

//This is our size condition
if ($uploaded_size > 350000) {
    echo "Your file is too large.<br>";
    $ok=0;
}

// This is our limit file type condition
if (!($uploaded_type=="text/java")||!($uploaded_type=="file/class")||! ($uploaded_type=="file/jar")) {
    echo "You may only upload Java files.<br>";
    $ok=0;
}

echo $ok;  //Here we check that $ok was not set to 0 by an error
if ($ok==0) {
    echo "Sorry your file was not uploaded";
}else {
    if(move_uploaded_file($_FILES['uploaded']['tmp_name'], $target)) {
        echo "The file ". $uploaded ." has been uploaded";
    } else {
        echo "Sorry, there was a problem uploading your file.";
    }
}
?>
middus
  • 9,103
  • 1
  • 31
  • 33
AshotN
  • 395
  • 4
  • 15

4 Answers4

2

You're using an OR... that means the whole statement evaluates as TRUE if ANY of its member arguments are true. Since a file can only be of one type, you're excluding ALL files. What you want is an 'and' match:

if (!($uploaded_type == 'text/java') && !($uploaded_type == ....)) {
                                     ^^---boolean and

Pretending that we're working with a file/class file type, then you version reads:

if the (file is not text/java) OR the (file is not file/class) OR the (file is not file/jar)
              TRUE                           FALSE                          TRUE

TRUE or FALSE or TRUE -> TRUE

Switchign to AND gives you

TRUE and FALSE and TRUE -> FALSE
Marc B
  • 356,200
  • 43
  • 426
  • 500
  • Wouldn't a AND make it so that is has to be a .java, .class, .jar at the same time? I do Java so I am probably wrong! – AshotN Oct 24 '11 at 21:33
  • No. Boolean logic is the same in all languages. – Marc B Oct 24 '11 at 21:34
  • @Hego555 Your are doing `not condition AND not condition`, which means it cant be either for the whole clause to evaluate to TRUE. As soon as it matches one, the clause evaluates to FALSE. It would make it less confusing if you changed it to `condition OR condition` (remove the NOTs) - this would have the same effect and be more readable. – DaveRandom Oct 24 '11 at 21:41
0

For client file format limit, refer to this Limit file format when using ?

<input type="file" accept="image/*" /> <!-- all image types --> 
<input type="file" accept="audio/*" /> <!-- all audio types --> 

For server, you can filter the uploaded file by this,

if(in_array(mime_type($file_path),$allowed_mime_types)){
    // save the file
}

$allowed_mime_types = array(
        'image/jpeg',
        'image/jpg',
        'image/png',
        'image/gif',
        'video/mp4'
);


/*
For PHP>=5.3.0, you can use php's `finfo_file`([finfo_file](https://www.php.net/manual/en/function.finfo-file.php)) function to get the file infomation about the file.

For PHP<5.3.0, you can use your's system's `file` command to get the file information.
*/
function mime_type($file_path)
{
    if (function_exists('finfo_open')) {            
        $finfo = new finfo(FILEINFO_MIME_TYPE, null);
        $mime_type = $finfo->file($file_path);
    }
    if (!$mime_type && function_exists('passthru') && function_exists('escapeshellarg')) {
        ob_start();
        passthru(sprintf('file -b --mime %s 2>/dev/null', escapeshellarg($file_path)), $return);
        if ($return > 0) {
            ob_end_clean();
            $mime_type = null;
        }
        $type = trim(ob_get_clean());
        if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
            $mime_type = null;
        }
        $mime_type = $match[1];
    }
    return $mime_type;
}
LF00
  • 27,015
  • 29
  • 156
  • 295
0

Only one of your three conditions could possibly be true, so that you end up with:

if (!false || !false || !true)

Which becomes:

if (true   || true   || false)

So you should either use an && in place of the OR, or use a nicer function to check for multiple things from a set:

if (!in_array($uploaded_type, array("text/java", "file/class","file/jar")) {

So the if will succeed if neither of the allowed values is found.

mario
  • 144,265
  • 20
  • 237
  • 291
  • if (!in_array($uploaded_type, array("text/java", "file/class","file/jar"))) { echo "You may only upload Java files.
    "; $ok=0; } Still gives wrong file type!
    – AshotN Oct 24 '11 at 21:39
  • Debug what `$uploaded_type` contains when that happens. The MIME type might not be what you think it is. – mario Oct 24 '11 at 21:52
  • Well, there's your actual problem then. – mario Oct 24 '11 at 22:13
  • 2
    The problem lies before that. You are not assigning the $uploaded_t variable somewhere. – mario Oct 24 '11 at 22:17
0

You can make this more flexible using in_array():

$allowed_types = array("text/java", "file/class", "file/jar");
if(!in_array($uploaded_type, $allowed_types)) {
  echo "You're not allowed to upload this kind of file.<br />";
  $ok = 0;
}

This makes it very easy to allow more file types later on. If you want to allow "text/html", you just need to add it to the array and do not need to create so many checks. You could even store the allowed types in a config file or a table in a database and create the array $allowed_types dynamically.

middus
  • 9,103
  • 1
  • 31
  • 33
  • Whoops, I just saw that mario proposed this, too. Anyway, I'll leave my answer, because I think it explains it very well. – middus Oct 24 '11 at 22:07