Page 1 of 1

Form Validation Help.

Posted: Tue Feb 03, 2009 5:30 am
by ne0_dev
Hi,

I have managed to get the form to process ok, however I think I may have got the validation mixed up. At present the form submits ok if all required fields are completed. As the file attachment is not a required field this works as intended. However if a file is attached that is either too large or not of the permitted file types the form still sends the rest of the information minus the file. The correct error message is being output to the form, but the mail processing script is not being halted if there is a problem with the file being attached.

I think it must be pretty simple but it's driving me mad! Any suggestions/help will be greatly appreciated.

Here is my code:

Code: Select all

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
// define a constant for the maximum file size
define ('MAX_FILE_SIZE', 1048576);
//mail processing script
if (array_key_exists('send', $_POST)) {
  // remove escape characters from POST array
  if (get_magic_quotes_gpc()) {
    function stripslashes_deep($value) {
      $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
      return $value;
      }
    $_POST = array_map('stripslashes_deep', $_POST);
    }
  
  $to = 'test@foo.co.uk';
  if (!empty($_POST['address'])) {
     $subject = 'SUSPECTED SPAM';
   }
   else {
  $subject = 'Project Brief Form';
  }
  // Obtain file upload vars
  $fileatt      = $_FILES['fileatt']['tmp_name'];
  $fileatt_type = $_FILES['fileatt']['type'];
  $fileatt_name = $_FILES['fileatt']['name'];
  // convert the maximum size to KB
  $max = number_format(MAX_FILE_SIZE/1024, 1).'KB';
  // create an array of permitted MIME types
  $permitted = array('application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'application/pdf', 'application/vnd.ms-powerpoint');
  // begin by assuming the file is unacceptable
  $sizeOK = false;
  $typeOK = false;
  // check that file is within the permitted size
  if ($_FILES['fileatt']['size'] > 0 && $_FILES['fileatt']['size'] <= MAX_FILE_SIZE) {
    $sizeOK = true;
   } 
   else {
      $error = 'The attachment exceeds the maximum file size of 1mb.';
   }
 
  // check that file is of an permitted MIME type
  foreach ($permitted as $type) {
    if ($type == $_FILES['fileatt']['type']) {
      $typeOK = true;
     break;
   }
   }
   
    if (!$typeOK) {
     $error = 'The file is not one of the permitted types (see below).';
     }
    
    if ($_FILES['fileatt']['error'] == 4) {
     $error = '';
  }
 
  // list expected fields
  $expected = array('name', 'company', 'email', 'phone', 'projecttitle', 'projectdetails', 'fileatt');
  // set required fields
  $required = array('name', 'email', 'phone', 'projecttitle', 'projectdetails');
  // create empty array for any missing fields
  $missing = array();
  
  // assume that there is nothing suspect
  $suspect = false;
  // create a pattern to locate suspect phrases
  $pattern = '/Content-Type:|Bcc:|Cc:/i';
  
  // function to check for suspect phrases
  function isSuspect($val, $pattern, &$suspect) {
    // if the variable is an array, loop through each element
   // and pass it recursively back to the same function
   if (is_array($val)) {
      foreach ($val as $item) {
       isSuspect($item, $pattern, $suspect);
       }
     }
    else {
      // if one of the suspect phrases is found, set Boolean to true
     if (preg_match($pattern, $val)) {
        $suspect = true;
       }
     }
    }
 
  // check the $_POST array and any subarrays for suspect content
  isSuspect($_POST, $pattern, $suspect);
  
  if ($suspect) {
    $mailSent = false;
   unset($missing);
   }
  else {
    // process the $_POST variables
    foreach ($_POST as $key => $value) {
      // assign to temporary variable and strip whitespace if not an array
      $temp = is_array($value) ? $value : trim($value);
      // if empty and required, add to $missing array
      if (empty($temp) && in_array($key, $required)) {
        array_push($missing, $key);
        }
      // otherwise, assign to a variable of the same name as $key
      elseif (in_array($key, $expected)) {
        ${$key} = $temp;
        }
      }  
    }
   
  // validate the email address
  if (!empty($email)) {
    // regex to identify illegal characters in email address
    $checkEmail = '/^[^@]+@[^\s\r\n\'";,@%]+$/';
   // reject the email address if it deosn't match
   if (!preg_match($checkEmail, $email)) {
     $suspect = true;
     $mailSent = false;
     unset($missing);
     }
   }
   
  // go ahead only if not suspsect and all required fields OK
  if (!$suspect && empty($missing)) {
 
  
  // Generate a boundary string
  $semi_rand = md5(time());
  $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
 
 // build the message   
   $htmlmsg = "<html>\n";
   $htmlmsg .= "<body style=\"font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#666666;\">\n";
   $htmlmsg .= "<b>Name:</b> $name<br><br>\n";
   $htmlmsg .= "<b>Company Name:</b> $company<br><br>\n";
   $htmlmsg .= "<b>Email:</b> $email<br><br>\n";
   $htmlmsg .= "<b>Telephone Number:</b> $phone<br><br>\n";
   $htmlmsg .= "<b>Project Title:</b> $projecttitle<br><br>\n";
   $htmlmsg .= "<b>Project Details:</b> $projectdetails<br><br>\n";
   $htmlmsg .= "</body>\n";
   $htmlmsg .= "</html>\n";
 
  // Add a multipart boundary above the html message
  $message = "This is a multi-part message in MIME format.\n\n" .
             "--{$mime_boundary}\n" .
             "Content-Type: text/html; charset=\"iso-8859-1\"\n" .
             "Content-Transfer-Encoding: 7bit\n\n" .
             $htmlmsg . "\n\n";
   
  //check if file has been uploaded and is of allowed MIME type and size
  if (is_uploaded_file($fileatt) && $typeOK && $sizeOK) {   
       
  // Read the file to be attached ('rb' = read binary)
  $file = fopen($fileatt,'rb');
  $data = fread($file,filesize($fileatt));
  fclose($file);
  // Base64 encode the file data
  $data = chunk_split(base64_encode($data));
 
  // Add file attachment to the message
  $message .= "--{$mime_boundary}\n" .
              "Content-Type: {$fileatt_type};\n" .
              " name=\"{$fileatt_name}\"\n" .
              //"Content-Disposition: attachment;\n" .
              //" filename=\"{$fileatt_name}\"\n" .
              "Content-Transfer-Encoding: base64\n\n" .
              $data . "\n\n" .
              "--{$mime_boundary}--\n";   
   }
       // create additional headers
   $headers = "From: http://www.foo.co.uk<enquiry@foo.co.uk>";
   // Add the headers for a file attachment
    $headers .= "\nMIME-Version: 1.0\n" .
              "Content-Type: multipart/mixed;\n" .
              " boundary=\"{$mime_boundary}\"";
 
   if (!empty($email)) {
     $headers .= "\nReply-To: $email";
     }
   
    // send it  
    $mailSent = mail($to, $subject, $message, $headers);
     if ($mailSent) {
      // $missing is no longer needed if the email is sent, so unset it
      unset($missing);
      }
   }
  }
?>
 

Re: Form Validation Help.

Posted: Tue Feb 03, 2009 5:55 am
by mickeyunderscore
The script is a little hard to follow, but it doesn't look like you have anything to stop the e-mail being sent if there is a problem with the file. The mail function is enclosed in the if statement:

Code: Select all

if (!$suspect && empty($missing)) {
Which doesn't check to see whether the uploaded file is bad.

You need something along the lines of:

Code: Select all

if (is_uploaded_file($fileatt) && ((!$typeOK) || (!$sizeOK)) ) { 
//dont sent email
}else{
//send email
}

Re: Form Validation Help.

Posted: Tue Feb 03, 2009 7:24 am
by ne0_dev
Thanks for the advice, and this may sound stupid but where in my code would I need to implement your suggestion?

Many Thanks