Jump to content

Recommended Posts

Not so long ago I did a CMS for a large website. When the client creates/edits a page, he or she can upload file attachments with it. These are usually PDF files or .doc files. Their hosting is on a Windows server. Whenever they try to upload certain PDF Files, my code tells them that it's not a valid filetype. So, I got them to send me the PDFs via email. I checked their mimetype and sure enough they were application/pdf. I then attempted to upload them with my local copy of the CMS and it worked. They were only a few hundred KB in size, so I'm guessing that size wasn't the problem. In the CMS DB, there is a table that contains the rows of accepted filetypes. When they upload a file, my code checks that table to see if the mime type of the file matches up with a mime type in the table. The function that checks this is in my file class:

 

protected function get_extension($filetype){
        $filetype = $this->db->clean($filetype);
        $res = $this->db->get_row("SELECT filetype_id, extension FROM filetype WHERE mime_type = '$filetype'");
        if(!$res){
            return false;
        }
        else{
            return $res;
        }
    }

 

$db->get_row() returns false if it couldn't find a single unique row. If that single unique rows exists, it returns an array.

 

Oh, and yes, they have successfully uploaded PDFs using that code before.

Link to comment
https://forums.phpfreaks.com/topic/172944-another-server-config-problem-i-think/
Share on other sites

Is your code checking for upload errors $_FILES[$fieldname]['error'] prior to that point so that you know that $filetype even has anything in it?

 

Real applications should log (see error_log) information about things that fail (and even for some things what work, like who logged in when or what search terms are being used...) so that you have a record of problems and can find and fix them. At the point that the query returns an unexpected value you should log all the available who, what (what does $filetype actually contain), when, where, and why (is $res a FALSE value, meaning the query failed to execute at all or is it a result resource with zero rows in it, meaning the query executed but matched zero rows) information and you should also display the $_FILES[$fieldname]['type'] value that failed in the user error message.

Hi, I have this in my code too:

 

if($_FILES[$fieldname]['error'] != 0){
			$error = $_FILES[$fieldname]['error'];

			if($error == 1){
				$this->error->add("Server problem: The uploaded file exceeds the upload_max_filesize directive set by the hosting company.");
				return false;
			}
			if($error == 2){
				$this->error->add("The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.");
				return false;
			}
			if($error == 3){
				$this->error->add("Server/Connection problem: The uploaded file was only partially uploaded.");
				return false;
			}
			if($error == 6){
				$this->error->add("Server problem: No temporary upload folder was found.");
				return false;
			}
			if($error == 7){
				$this->error->add("Server problem: Could not write to disk.");
				return false;
			}
		}

 

I tried it; but still end up getting a message about how the file isn't the right type:

 

if(!$extension){
			$this->error->add("The filetype under the title <strong>".$this->db->output($title)."</strong> has not been recognised and has therefore not been added to the page that you just created.");
			return false;
		}

$_FILES[$fieldname]['type'] is a client set variable, not a server one.  This may have different capitalization or have other slight variations depending on the client computer, which would explain the behavior you're seeing.

 

Why not just filter by extension?

Different browsers, the same browser on different operating systems, and probably different versions of the same browser will provide different mime types for the same identical file.

 

Nothing I have seen so far in this thread indicates what actual value is being received when the customer tries this. For all we know the customer is not actually selecting a file, but is just submitting an empty form or that the HTML of the form is invalid and it uploads a file in one browser but not another. Until you display and/or log what value is actually being put into the query that is failing to indicate a match with something in the database, you will never find out why it is failing.

 

Figured out the problem. Basically, my $db->get_row() function returns an array if one row is found. It returns false if no rows are found OR if more than one row was found. I or somebody else must have ran the setup file twice by accident, meaning that two of every mime type existed inside the db. Should have really put a unique index on the mime_type column but I remember that at the time, I chose not too because my setup file would be inserting these file types manually and performance wouldn't be such an issue with a table so small. I tried using fileinfo(), but their server doesn't have support for it installed. So I got the file's extension instead and worked from there. It was only after I had changed the script to get the extension of the file that I figured out what was wrong. Interesting thing about $_FILES['name']['type'] though. I honestly never knew that.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.