public function validate($value, $form) { $input_name = 'input_' . $this->id; $allowed_extensions = !empty($this->allowedExtensions) ? GFCommon::clean_extensions(explode(',', strtolower($this->allowedExtensions))) : array(); if ($this->multipleFiles) { $file_names = isset(GFFormsModel::$uploaded_files[$form['id']][$input_name]) ? GFFormsModel::$uploaded_files[$form['id']][$input_name] : array(); } else { $max_upload_size_in_bytes = isset($this->maxFileSize) && $this->maxFileSize > 0 ? $this->maxFileSize * 1048576 : wp_max_upload_size(); $max_upload_size_in_mb = $max_upload_size_in_bytes / 1048576; if (!empty($_FILES[$input_name]['name']) && $_FILES[$input_name]['error'] > 0) { $uploaded_file_name = isset(GFFormsModel::$uploaded_files[$form['id']][$input_name]) ? GFFormsModel::$uploaded_files[$form['id']][$input_name] : ''; if (empty($uploaded_file_name)) { $this->failed_validation = true; switch ($_FILES[$input_name]['error']) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $fileupload_validation_message = sprintf(esc_html__('File exceeds size limit. Maximum file size: %dMB', 'gravityforms'), $max_upload_size_in_mb); break; default: $fileupload_validation_message = sprintf(esc_html__('There was an error while uploading the file. Error code: %d', 'gravityforms'), $_FILES[$input_name]['error']); } $this->validation_message = empty($this->errorMessage) ? $fileupload_validation_message : $this->errorMessage; return; } } elseif ($_FILES[$input_name]['size'] > 0 && $_FILES[$input_name]['size'] > $max_upload_size_in_bytes) { $this->failed_validation = true; $this->validation_message = sprintf(esc_html__('File exceeds size limit. Maximum file size: %dMB', 'gravityforms'), $max_upload_size_in_mb); return; } $whitelisting_disabled = apply_filters('gform_file_upload_whitelisting_disabled', false); if (!empty($_FILES[$input_name]['name']) && empty($allowed_extensions) && !$whitelisting_disabled) { $check_result = GFCommon::check_type_and_ext($_FILES[$input_name]); if (is_wp_error($check_result)) { $this->failed_validation = true; $this->validation_message = esc_html__('The uploaded file type is not allowed.', 'gravityforms'); return; } } $single_file_name = $_FILES[$input_name]['name']; $file_names = array(array('uploaded_filename' => $single_file_name)); } foreach ($file_names as $file_name) { $info = pathinfo(rgar($file_name, 'uploaded_filename')); if (empty($allowed_extensions)) { if (GFCommon::file_name_has_disallowed_extension(rgar($file_name, 'uploaded_filename'))) { $this->failed_validation = true; $this->validation_message = empty($this->errorMessage) ? esc_html__('The uploaded file type is not allowed.', 'gravityforms') : $this->errorMessage; } } else { if (!empty($info['basename']) && !GFCommon::match_file_extension(rgar($file_name, 'uploaded_filename'), $allowed_extensions)) { $this->failed_validation = true; $this->validation_message = empty($this->errorMessage) ? sprintf(esc_html__('The uploaded file type is not allowed. Must be one of the following: %s', 'gravityforms'), strtolower($this->allowedExtensions)) : $this->errorMessage; } } } }
/** * Renames files with a .bak extension if they have a file extension that is not allowed in the Gravity Forms uploads folder. */ private static function rename_suspicious_files_recursive($dir, $flag_security_alert = false) { if (!is_dir($dir) || is_link($dir)) { return; } if (!($dir_handle = opendir($dir))) { return; } // ignores all errors set_error_handler(create_function('', 'return 0;'), E_ALL); while (false !== ($file = readdir($dir_handle))) { if (is_dir($dir . DIRECTORY_SEPARATOR . $file) && $file != '.' && $file != '..') { $flag_security_alert = self::rename_suspicious_files_recursive($dir . DIRECTORY_SEPARATOR . $file, $flag_security_alert); } elseif (GFCommon::file_name_has_disallowed_extension($file) && !GFCommon::match_file_extension($file, array('htaccess', 'bak', 'html'))) { $mini_hash = substr(wp_hash($file), 0, 6); $newName = sprintf('%s/%s.%s.bak', $dir, $file, $mini_hash); rename($dir . '/' . $file, $newName); $flag_security_alert = true; } } closedir($dir_handle); return $flag_security_alert; }
private static function upload_files($form, $files) { $form_upload_path = GFFormsModel::get_upload_path($form['id']); GFCommon::log_debug("GFFormDisplay::upload_files(): Upload path {$form_upload_path}"); //Creating temp folder if it does not exist $target_path = $form_upload_path . '/tmp/'; wp_mkdir_p($target_path); GFCommon::recursive_add_index_file($form_upload_path); foreach ($form['fields'] as $field) { $input_name = "input_{$field->id}"; //skip fields that are not file upload fields or that don't have a file to be uploaded or that have failed validation $input_type = RGFormsModel::get_input_type($field); if (!in_array($input_type, array('fileupload', 'post_image')) || $field->multipleFiles) { continue; } /*if ( $field->failed_validation || empty( $_FILES[ $input_name ]['name'] ) ) { GFCommon::log_debug( "GFFormDisplay::upload_files(): Skipping field: {$field->label}({$field->id} - {$field->type})." ); continue; }*/ if ($field->failed_validation) { GFCommon::log_debug("GFFormDisplay::upload_files(): Skipping field because it failed validation: {$field->label}({$field->id} - {$field->type})."); continue; } if (empty($_FILES[$input_name]['name'])) { GFCommon::log_debug("GFFormDisplay::upload_files(): Skipping field because " . $_FILES[$input_name]['name'] . " could not be found: {$field->label}({$field->id} - {$field->type})."); continue; } $file_name = $_FILES[$input_name]['name']; if (GFCommon::file_name_has_disallowed_extension($file_name)) { GFCommon::log_debug(__METHOD__ . "(): Illegal file extension: {$file_name}"); continue; } $allowed_extensions = !empty($field->allowedExtensions) ? GFCommon::clean_extensions(explode(',', strtolower($field->allowedExtensions))) : array(); if (!empty($allowed_extensions)) { if (!GFCommon::match_file_extension($file_name, $allowed_extensions)) { GFCommon::log_debug(__METHOD__ . "(): The uploaded file type is not allowed: {$file_name}"); continue; } } /** * Allows the disabling of file upload whitelisting * * @param bool false Set to 'true' to disable whitelisting. Defaults to 'false'. */ $whitelisting_disabled = apply_filters('gform_file_upload_whitelisting_disabled', false); if (empty($allowed_extensions) && !$whitelisting_disabled) { // Whitelist the file type $valid_file_name = GFCommon::check_type_and_ext($_FILES[$input_name], $file_name); if (is_wp_error($valid_file_name)) { GFCommon::log_debug(__METHOD__ . "(): The uploaded file type is not allowed: {$file_name}"); continue; } } $file_info = RGFormsModel::get_temp_filename($form['id'], $input_name); GFCommon::log_debug('GFFormDisplay::upload_files(): Temp file info: ' . print_r($file_info, true)); if ($file_info && move_uploaded_file($_FILES[$input_name]['tmp_name'], $target_path . $file_info['temp_filename'])) { GFFormsModel::set_permissions($target_path . $file_info['temp_filename']); $files[$input_name] = $file_info['uploaded_filename']; GFCommon::log_debug("GFFormDisplay::upload_files(): File uploaded successfully: {$file_info['uploaded_filename']}"); } else { GFCommon::log_error("GFFormDisplay::upload_files(): File could not be uploaded: tmp_name: {$_FILES[$input_name]['tmp_name']} - target location: " . $target_path . $file_info['temp_filename']); } } return $files; }
public static function upload() { GFCommon::log_debug('GFAsyncUpload::upload(): Starting.'); if ($_SERVER['REQUEST_METHOD'] != 'POST') { status_header(404); die; } header('Content-Type: text/html; charset=' . get_option('blog_charset')); send_nosniff_header(); nocache_headers(); status_header(200); // If the file is bigger than the server can accept then the form_id might not arrive. // This might happen if the file is bigger than the max post size ini setting. // Validation in the browser reduces the risk of this happening. if (!isset($_REQUEST['form_id'])) { GFCommon::log_debug('GFAsyncUpload::upload(): File upload aborted because the form_id was not found. The file may have been bigger than the max post size ini setting.'); self::die_error(500, __('Failed to upload file.', 'gravityforms')); } $form_id = absint($_REQUEST['form_id']); $form_unique_id = rgpost('gform_unique_id'); $form = GFAPI::get_form($form_id); if (empty($form) || !$form['is_active']) { die; } if (rgar($form, 'requireLogin')) { if (!is_user_logged_in()) { die; } check_admin_referer('gform_file_upload_' . $form_id, '_gform_file_upload_nonce_' . $form_id); } if (!ctype_alnum($form_unique_id)) { die; } $target_dir = GFFormsModel::get_upload_path($form_id) . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR; if (!is_dir($target_dir)) { if (!wp_mkdir_p($target_dir)) { GFCommon::log_debug("GFAsyncUpload::upload(): Couldn't create the tmp folder: " . $target_dir); self::die_error(500, __('Failed to upload file.', 'gravityforms')); } } $time = current_time('mysql'); $y = substr($time, 0, 4); $m = substr($time, 5, 2); //adding index.html files to all subfolders if (!file_exists(GFFormsModel::get_upload_root() . '/index.html')) { GFForms::add_security_files(); } else { if (!file_exists(GFFormsModel::get_upload_path($form_id) . '/index.html')) { GFCommon::recursive_add_index_file(GFFormsModel::get_upload_path($form_id)); } else { if (!file_exists(GFFormsModel::get_upload_path($form_id) . "/{$y}/index.html")) { GFCommon::recursive_add_index_file(GFFormsModel::get_upload_path($form_id) . "/{$y}"); } else { GFCommon::recursive_add_index_file(GFFormsModel::get_upload_path($form_id) . "/{$y}/{$m}"); } } } if (!file_exists($target_dir . '/index.html')) { GFCommon::recursive_add_index_file($target_dir); } $uploaded_filename = $_FILES['file']['name']; $file_name = isset($_REQUEST['name']) ? $_REQUEST['name'] : ''; $field_id = rgpost('field_id'); $field_id = absint($field_id); $field = GFFormsModel::get_field($form, $field_id); if (empty($field) || GFFormsModel::get_input_type($field) != 'fileupload') { die; } $file_name = sanitize_file_name($file_name); $uploaded_filename = sanitize_file_name($uploaded_filename); $allowed_extensions = !empty($field->allowedExtensions) ? GFCommon::clean_extensions(explode(',', strtolower($field->allowedExtensions))) : array(); $max_upload_size_in_bytes = $field->maxFileSize > 0 ? $field->maxFileSize * 1048576 : wp_max_upload_size(); $max_upload_size_in_mb = $max_upload_size_in_bytes / 1048576; if ($_FILES['file']['size'] > 0 && $_FILES['file']['size'] > $max_upload_size_in_bytes) { self::die_error(104, sprintf(__('File exceeds size limit. Maximum file size: %dMB', 'gravityforms'), $max_upload_size_in_mb)); } if (GFCommon::file_name_has_disallowed_extension($file_name) || GFCommon::file_name_has_disallowed_extension($uploaded_filename)) { GFCommon::log_debug("GFAsyncUpload::upload(): Illegal file extension: {$file_name}"); self::die_error(104, __('The uploaded file type is not allowed.', 'gravityforms')); } if (!empty($allowed_extensions)) { if (!GFCommon::match_file_extension($file_name, $allowed_extensions) || !GFCommon::match_file_extension($uploaded_filename, $allowed_extensions)) { GFCommon::log_debug("GFAsyncUpload::upload(): The uploaded file type is not allowed: {$file_name}"); self::die_error(104, sprintf(__('The uploaded file type is not allowed. Must be one of the following: %s', 'gravityforms'), strtolower($field['allowedExtensions']))); } } $whitelisting_disabled = apply_filters('gform_file_upload_whitelisting_disabled', false); if (empty($allowed_extensions) && !$whitelisting_disabled) { // Whitelist the file type $valid_uploaded_filename = GFCommon::check_type_and_ext($_FILES['file'], $uploaded_filename); if (is_wp_error($valid_uploaded_filename)) { self::die_error($valid_uploaded_filename->get_error_code(), $valid_uploaded_filename->get_error_message()); } $valid_file_name = GFCommon::check_type_and_ext($_FILES['file'], $file_name); if (is_wp_error($valid_uploaded_filename)) { self::die_error($valid_file_name->get_error_code(), $valid_file_name->get_error_message()); } } $tmp_file_name = $form_unique_id . '_input_' . $field_id . '_' . $file_name; $tmp_file_name = sanitize_file_name($tmp_file_name); $file_path = $target_dir . $tmp_file_name; $cleanup_target_dir = true; // Remove old files $max_file_age = 5 * 3600; // Temp file age in seconds // Remove old temp files if ($cleanup_target_dir) { if (is_dir($target_dir) && ($dir = opendir($target_dir))) { while (($file = readdir($dir)) !== false) { $tmp_file_path = $target_dir . $file; // Remove temp file if it is older than the max age and is not the current file if (preg_match('/\\.part$/', $file) && filemtime($tmp_file_path) < time() - $max_file_age && $tmp_file_path != "{$file_path}.part") { GFCommon::log_debug('GFAsyncUpload::upload(): Deleting file: ' . $tmp_file_path); @unlink($tmp_file_path); } } closedir($dir); } else { GFCommon::log_debug('GFAsyncUpload::upload(): Failed to open temp directory: ' . $target_dir); self::die_error(100, __('Failed to open temp directory.', 'gravityforms')); } } if (isset($_SERVER['HTTP_CONTENT_TYPE'])) { $contentType = $_SERVER['HTTP_CONTENT_TYPE']; } if (isset($_SERVER['CONTENT_TYPE'])) { $contentType = $_SERVER['CONTENT_TYPE']; } $chunk = isset($_REQUEST['chunk']) ? intval($_REQUEST['chunk']) : 0; $chunks = isset($_REQUEST['chunks']) ? intval($_REQUEST['chunks']) : 0; // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5 if (strpos($contentType, 'multipart') !== false) { if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) { // Open temp file $out = @fopen("{$file_path}.part", $chunk == 0 ? 'wb' : 'ab'); if ($out) { // Read binary input stream and append it to temp file $in = @fopen($_FILES['file']['tmp_name'], 'rb'); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } else { self::die_error(101, __('Failed to open input stream.', 'gravityforms')); } @fclose($in); @fclose($out); @unlink($_FILES['file']['tmp_name']); } else { self::die_error(102, __('Failed to open output stream.', 'gravityforms')); } } else { self::die_error(103, __('Failed to move uploaded file.', 'gravityforms')); } } else { // Open temp file $out = @fopen("{$file_path}.part", $chunk == 0 ? 'wb' : 'ab'); if ($out) { // Read binary input stream and append it to temp file $in = @fopen('php://input', 'rb'); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } else { self::die_error(101, __('Failed to open input stream.', 'gravityforms')); } @fclose($in); @fclose($out); } else { self::die_error(102, __('Failed to open output stream.', 'gravityforms')); } } // Check if file has been uploaded if (!$chunks || $chunk == $chunks - 1) { // Strip the temp .part suffix off rename("{$file_path}.part", $file_path); } if (file_exists($file_path)) { GFFormsModel::set_permissions($file_path); } else { self::die_error(105, __('Upload unsuccessful', 'gravityforms') . ' ' . $uploaded_filename); } $output = array('status' => 'ok', 'data' => array('temp_filename' => $tmp_file_name, 'uploaded_filename' => str_replace("\\'", "'", urldecode($uploaded_filename)))); $output = json_encode($output); GFCommon::log_debug(sprintf('GFAsyncUpload::upload(): File upload complete. temp_filename: %s uploaded_filename: %s ', $tmp_file_name, $uploaded_filename)); gf_do_action('gform_post_multifile_upload', $form['id'], $form, $field, $uploaded_filename, $tmp_file_name, $file_path); die($output); }
public function validate($value, $form) { $input_name = 'input_' . $this->id; GFCommon::log_debug(__METHOD__ . '(): Validating field ' . $input_name); $allowed_extensions = !empty($this->allowedExtensions) ? GFCommon::clean_extensions(explode(',', strtolower($this->allowedExtensions))) : array(); if ($this->multipleFiles) { $file_names = isset(GFFormsModel::$uploaded_files[$form['id']][$input_name]) ? GFFormsModel::$uploaded_files[$form['id']][$input_name] : array(); } else { $max_upload_size_in_bytes = isset($this->maxFileSize) && $this->maxFileSize > 0 ? $this->maxFileSize * 1048576 : wp_max_upload_size(); $max_upload_size_in_mb = $max_upload_size_in_bytes / 1048576; if (!empty($_FILES[$input_name]['name']) && $_FILES[$input_name]['error'] > 0) { $uploaded_file_name = isset(GFFormsModel::$uploaded_files[$form['id']][$input_name]) ? GFFormsModel::$uploaded_files[$form['id']][$input_name] : ''; if (empty($uploaded_file_name)) { $this->failed_validation = true; switch ($_FILES[$input_name]['error']) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: GFCommon::log_debug(__METHOD__ . '(): File ' . $_FILES[$input_name]['name'] . ' exceeds size limit. Maximum file size: ' . $max_upload_size_in_mb . 'MB'); $fileupload_validation_message = sprintf(esc_html__('File exceeds size limit. Maximum file size: %dMB', 'gravityforms'), $max_upload_size_in_mb); break; default: GFCommon::log_debug(__METHOD__ . '(): The following error occurred while uploading - ' . $_FILES[$input_name]['error']); $fileupload_validation_message = sprintf(esc_html__('There was an error while uploading the file. Error code: %d', 'gravityforms'), $_FILES[$input_name]['error']); } $this->validation_message = empty($this->errorMessage) ? $fileupload_validation_message : $this->errorMessage; return; } } elseif ($_FILES[$input_name]['size'] > 0 && $_FILES[$input_name]['size'] > $max_upload_size_in_bytes) { $this->failed_validation = true; GFCommon::log_debug(__METHOD__ . '(): File ' . $_FILES[$input_name]['name'] . ' exceeds size limit. Maximum file size: ' . $max_upload_size_in_mb . 'MB'); $this->validation_message = sprintf(esc_html__('File exceeds size limit. Maximum file size: %dMB', 'gravityforms'), $max_upload_size_in_mb); return; } /** * A filter to allow or disallow whitelisting when uploading a file * * @param bool false To set upload whitelisting to true or false (default is false, which means it is enabled) */ $whitelisting_disabled = apply_filters('gform_file_upload_whitelisting_disabled', false); if (!empty($_FILES[$input_name]['name']) && empty($allowed_extensions) && !$whitelisting_disabled) { $check_result = GFCommon::check_type_and_ext($_FILES[$input_name]); if (is_wp_error($check_result)) { $this->failed_validation = true; GFCommon::log_debug(__METHOD__ . '(): The uploaded file type is not allowed.'); $this->validation_message = esc_html__('The uploaded file type is not allowed.', 'gravityforms'); return; } } $single_file_name = $_FILES[$input_name]['name']; $file_names = array(array('uploaded_filename' => $single_file_name)); } foreach ($file_names as $file_name) { GFCommon::log_debug(__METHOD__ . '(): Validating file upload for ' . $file_name['uploaded_filename']); $info = pathinfo(rgar($file_name, 'uploaded_filename')); if (empty($allowed_extensions)) { if (GFCommon::file_name_has_disallowed_extension(rgar($file_name, 'uploaded_filename'))) { GFCommon::log_debug(__METHOD__ . '(): The file has a disallowed extension, failing validation.'); $this->failed_validation = true; $this->validation_message = empty($this->errorMessage) ? esc_html__('The uploaded file type is not allowed.', 'gravityforms') : $this->errorMessage; } } else { if (!empty($info['basename']) && !GFCommon::match_file_extension(rgar($file_name, 'uploaded_filename'), $allowed_extensions)) { GFCommon::log_debug(__METHOD__ . '(): The file is of a type that cannot be uploaded, failing validation.'); $this->failed_validation = true; $this->validation_message = empty($this->errorMessage) ? sprintf(esc_html__('The uploaded file type is not allowed. Must be one of the following: %s', 'gravityforms'), strtolower($this->allowedExtensions)) : $this->errorMessage; } } } GFCommon::log_debug(__METHOD__ . '(): Validation complete.'); }
public static function validate(&$form, $field_values, $page_number = 0, &$failed_validation_page = 0) { $form = apply_filters('gform_pre_validation', $form); // validate form schedule if (self::validate_form_schedule($form)) { return false; } // validate entry limit if (self::validate_entry_limit($form)) { return false; } if (empty($_POST["is_submit_" . $form["id"]])) { return false; } foreach ($form["fields"] as &$field) { //If a page number is specified, only validates fields that are on current page $field_in_other_page = $page_number > 0 && $field["pageNumber"] != $page_number; //validate fields with "no duplicate" functionality when they are present on pages before the current page. $validate_duplicate_feature = $field["noDuplicates"] && $page_number > 0 && $field["pageNumber"] <= $page_number; //if(($page_number > 0 && $field["pageNumber"] != $page_number) && $field["noDuplicates"] <> "1"){ if ($field_in_other_page && !$validate_duplicate_feature) { continue; } //ignore validation if field is hidden or admin only if (RGFormsModel::is_field_hidden($form, $field, $field_values) || $field["adminOnly"]) { continue; } $value = RGFormsModel::get_field_value($field); //display error message if field is marked as required and the submitted value is empty if ($field["isRequired"] && self::is_empty($field, $form["id"])) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("This field is required.", "gravityforms") : $field["errorMessage"]; } else { if ($field["noDuplicates"] && RGFormsModel::is_duplicate($form["id"], $field, $value)) { $field["failed_validation"] = true; //set page number so the failed field displays if on multi-page form $failed_validation_page = $field["pageNumber"]; $input_type = RGFormsModel::get_input_type($field); switch ($input_type) { case "date": $default_message = __("This date has already been taken. Please select a new date.", "gravityforms"); break; default: $default_message = is_array($value) ? __("This field requires a unique entry and the values you entered have been already been used.", "gravityforms") : sprintf(__("This field requires a unique entry and '%s' has already been used", "gravityforms"), $value); break; } $field["validation_message"] = apply_filters("gform_duplicate_message_{$form["id"]}", apply_filters("gform_duplicate_message", $default_message, $form, $field, $value), $form, $field, $value); } else { if (self::failed_state_validation($form["id"], $field, $value)) { $field["failed_validation"] = true; $field["validation_message"] = in_array($field["inputType"], array("singleproduct", "singleshipping", "hiddenproduct")) ? __("Please enter a valid value.", "gravityforms") : __("Invalid selection. Please select one of the available choices.", "gravityforms"); } else { switch (RGFormsModel::get_input_type($field)) { case "password": $password = $_POST["input_" . $field["id"]]; $confirm = $_POST["input_" . $field["id"] . "_2"]; if ($password != $confirm) { $field["failed_validation"] = true; $field["validation_message"] = __("Your passwords do not match.", "gravityforms"); } else { if (rgar($field, "passwordStrengthEnabled") && !rgempty("minPasswordStrength", $field) && !empty($password)) { $strength = $_POST["input_" . $field["id"] . "_strength"]; $levels = array("short" => 1, "bad" => 2, "good" => 3, "strong" => 4); if ($levels[$strength] < $levels[$field["minPasswordStrength"]]) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("Your password does not meet the required strength. <br/>Hint: To make it stronger, use upper and lower case letters, numbers and symbols like ! \" ? \$ % ^ & ).", "gravityforms") : $field["errorMessage"]; } } } break; case "name": if ($field["isRequired"] && $field["nameFormat"] != "simple") { $first = $_POST["input_" . $field["id"] . "_3"]; $last = $_POST["input_" . $field["id"] . "_6"]; if (empty($first) || empty($last)) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("This field is required. Please enter the first and last name.", "gravityforms") : $field["errorMessage"]; } } break; case "address": if ($field["isRequired"]) { $street = $_POST["input_" . $field["id"] . "_1"]; $city = $_POST["input_" . $field["id"] . "_3"]; $state = $_POST["input_" . $field["id"] . "_4"]; $zip = $_POST["input_" . $field["id"] . "_5"]; $country = $_POST["input_" . $field["id"] . "_6"]; if (empty($street) || empty($city) || empty($zip) || empty($state) && !$field["hideState"] || empty($country) && !$field["hideCountry"]) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("This field is required. Please enter a complete address.", "gravityforms") : $field["errorMessage"]; } } break; case "creditcard": $card_number = rgpost("input_" . $field["id"] . "_1"); $expiration_date = rgpost("input_" . $field["id"] . "_2"); $security_code = rgpost("input_" . $field["id"] . "_3"); if (rgar($field, "isRequired") && (empty($card_number) || empty($security_code) || empty($expiration_date[0]) || empty($expiration_date[1]))) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("Please enter your credit card information.", "gravityforms") : $field["errorMessage"]; } else { if (!empty($card_number)) { $card_type = GFCommon::get_card_type($card_number); $security_code = rgpost("input_" . $field["id"] . "_3"); if (empty($security_code)) { $field["failed_validation"] = true; $field["validation_message"] = __("Please enter your card's security code.", "gravityforms"); } else { if (!$card_type) { $field["failed_validation"] = true; $field["validation_message"] = __("Invalid credit card number.", "gravityforms"); } else { if (!GFCommon::is_card_supported($field, $card_type["slug"])) { $field["failed_validation"] = true; $field["validation_message"] = $card_type["name"] . " " . __("is not supported. Please enter one of the supported credit cards.", "gravityforms"); } } } } } break; case "email": if (!rgblank($value) && !GFCommon::is_valid_email($value)) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("Please enter a valid email address.", "gravityforms") : $field["errorMessage"]; } else { if (rgget("emailConfirmEnabled", $field) && !empty($value)) { $confirm = rgpost("input_" . $field["id"] . "_2"); if ($confirm != $value) { $field["failed_validation"] = true; $field["validation_message"] = __("Your emails do not match.", "gravityforms"); } } } break; case "donation": case "price": if (!class_exists("RGCurrency")) { require_once "currency.php"; } $donation = GFCommon::to_number($value); if (!rgblank($value) && ($donation === false || $donation < 0)) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("Please enter a valid amount.", "gravityforms") : $field["errorMessage"]; } break; case "number": // the POST value has already been converted from currency or decimal_comma to decimal_dot and then cleaned in get_field_value() $value = GFCommon::maybe_add_leading_zero($value); $raw_value = $_POST["input_" . $field["id"]]; //Raw value will be tested against the is_numeric() function to make sure it is in the right format. $requires_valid_number = !rgblank($raw_value) && !GFCommon::has_field_calculation($field); $is_valid_number = self::validate_range($field, $value) && GFCommon::is_numeric($raw_value, $field["numberFormat"]); if ($requires_valid_number && !$is_valid_number) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? GFCommon::get_range_message($field) : $field["errorMessage"]; } else { if ($field['type'] == 'quantity') { if (intval($value) != $value) { $field['failed_validation'] = true; $field['validation_message'] = empty($field['errorMessage']) ? __('Please enter a valid quantity. Quantity cannot contain decimals.', 'gravityforms') : $field['errorMessage']; } else { if (!empty($value) && (!is_numeric($value) || intval($value) != floatval($value) || intval($value) < 0)) { $field['failed_validation'] = true; $field['validation_message'] = empty($field['errorMessage']) ? __('Please enter a valid quantity', 'gravityforms') : $field['errorMessage']; } } } } break; case "phone": $regex = '/^\\D?(\\d{3})\\D?\\D?(\\d{3})\\D?(\\d{4})$/'; if ($field["phoneFormat"] == "standard" && $value !== "" && $value !== 0 && !preg_match($regex, $value)) { $field["failed_validation"] = true; if (!empty($field["errorMessage"])) { $field["validation_message"] = $field["errorMessage"]; } } break; case "date": if (is_array($value) && rgempty(0, $value) && rgempty(1, $value) && rgempty(2, $value)) { $value = null; } if (!empty($value)) { $format = empty($field["dateFormat"]) ? "mdy" : $field["dateFormat"]; $date = GFCommon::parse_date($value, $format); if (empty($date) || !self::checkdate($date["month"], $date["day"], $date["year"])) { $field["failed_validation"] = true; $format_name = ""; switch ($format) { case "mdy": $format_name = "mm/dd/yyyy"; break; case "dmy": $format_name = "dd/mm/yyyy"; break; case "dmy_dash": $format_name = "dd-mm-yyyy"; break; case "dmy_dot": $format_name = "dd.mm.yyyy"; break; case "ymd_slash": $format_name = "yyyy/mm/dd"; break; case "ymd_dash": $format_name = "yyyy-mm-dd"; break; case "ymd_dot": $format_name = "yyyy.mm.dd"; break; } $message = $field["dateType"] == "datepicker" ? sprintf(__("Please enter a valid date in the format (%s).", "gravityforms"), $format_name) : __("Please enter a valid date.", "gravityforms"); $field["validation_message"] = empty($field["errorMessage"]) ? $message : $field["errorMessage"]; } } break; case "time": //create variable values if time came in one field if (!is_array($value) && !empty($value)) { preg_match('/^(\\d*):(\\d*) ?(.*)$/', $value, $matches); $value = array(); $value[0] = $matches[1]; $value[1] = $matches[2]; } $hour = $value[0]; $minute = $value[1]; if (empty($hour) && empty($minute)) { break; } $is_valid_format = is_numeric($hour) && is_numeric($minute); $min_hour = rgar($field, "timeFormat") == "24" ? 0 : 1; $max_hour = rgar($field, "timeFormat") == "24" ? 23 : 12; if (!$is_valid_format || $hour < $min_hour || $hour > $max_hour || $minute < 0 || $minute >= 60) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("Please enter a valid time.", "gravityforms") : $field["errorMessage"]; } break; case "website": if (empty($value) || $value == "http://") { $value = ""; if ($field["isRequired"]) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("This field is required.", "gravityforms") : $field["errorMessage"]; } } if (!empty($value) && !GFCommon::is_valid_url($value)) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("Please enter a valid Website URL (i.e. http://www.gravityforms.com).", "gravityforms") : $field["errorMessage"]; } break; case "captcha": switch ($field["captchaType"]) { case "simple_captcha": if (class_exists("ReallySimpleCaptcha")) { $prefix = $_POST["input_captcha_prefix_{$field["id"]}"]; $captcha_obj = GFCommon::get_simple_captcha(); if (!$captcha_obj->check($prefix, str_replace(" ", "", $value))) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("The CAPTCHA wasn't entered correctly. Go back and try it again.", "gravityforms") : $field["errorMessage"]; } //removes old files in captcha folder (older than 1 hour); $captcha_obj->cleanup(); } break; case "math": $prefixes = explode(",", $_POST["input_captcha_prefix_{$field["id"]}"]); $captcha_obj = GFCommon::get_simple_captcha(); //finding first number $first = 0; for ($first = 0; $first < 10; $first++) { if ($captcha_obj->check($prefixes[0], $first)) { break; } } //finding second number $second = 0; for ($second = 0; $second < 10; $second++) { if ($captcha_obj->check($prefixes[2], $second)) { break; } } //if it is a +, perform the sum if ($captcha_obj->check($prefixes[1], "+")) { $result = $first + $second; } else { $result = $first - $second; } if (intval($result) != intval($value)) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("The CAPTCHA wasn't entered correctly. Go back and try it again.", "gravityforms") : $field["errorMessage"]; } //removes old files in captcha folder (older than 1 hour); $captcha_obj->cleanup(); break; default: if (!function_exists("recaptcha_get_html")) { require_once GFCommon::get_base_path() . '/recaptchalib.php'; } $privatekey = get_option("rg_gforms_captcha_private_key"); $resp = recaptcha_check_answer($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]); if (!$resp->is_valid) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("The reCAPTCHA wasn't entered correctly. Go back and try it again.", "gravityforms") : $field["errorMessage"]; } } break; case "fileupload": case "post_image": $input_name = "input_" . $field["id"]; if (rgar($field, "multipleFiles")) { $file_names = isset(GFFormsModel::$uploaded_files[$form["id"]][$input_name]) ? GFFormsModel::$uploaded_files[$form["id"]][$input_name] : array(); } else { $max_upload_size_in_bytes = isset($field["maxFileSize"]) && $field["maxFileSize"] > 0 ? $field["maxFileSize"] * 1048576 : wp_max_upload_size(); $max_upload_size_in_mb = $max_upload_size_in_bytes / 1048576; if (!empty($_FILES[$input_name]["name"]) && $_FILES[$input_name]["error"] > 0) { $uploaded_file_name = isset(GFFormsModel::$uploaded_files[$form["id"]][$input_name]) ? GFFormsModel::$uploaded_files[$form["id"]][$input_name] : ""; if (empty($uploaded_file_name)) { $field["failed_validation"] = true; switch ($_FILES[$input_name]["error"]) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $fileupload_validation_message = sprintf(__("File exceeds size limit. Maximum file size: %dMB", "gravityforms"), $max_upload_size_in_mb); break; default: $fileupload_validation_message = sprintf(__("There was an error while uploading the file. Error code: %d", "gravityforms"), $_FILES[$input_name]["error"]); } $field["validation_message"] = empty($field["errorMessage"]) ? $fileupload_validation_message : $field["errorMessage"]; break; } } elseif ($_FILES[$input_name]['size'] > 0 && $_FILES[$input_name]['size'] > $max_upload_size_in_bytes) { $field["failed_validation"] = true; $field["validation_message"] = sprintf(__('File exceeds size limit. Maximum file size: %dMB', 'gravityforms'), $max_upload_size_in_mb); } $single_file_name = $_FILES[$input_name]["name"]; $file_names = array(array("uploaded_filename" => $single_file_name)); } foreach ($file_names as $file_name) { $info = pathinfo(rgar($file_name, "uploaded_filename")); $allowed_extensions = isset($field["allowedExtensions"]) && !empty($field["allowedExtensions"]) ? GFCommon::clean_extensions(explode(",", strtolower($field["allowedExtensions"]))) : array(); if (empty($field["allowedExtensions"]) && GFCommon::file_name_has_disallowed_extension(rgar($file_name, 'uploaded_filename'))) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("The uploaded file type is not allowed.", "gravityforms") : $field["errorMessage"]; } else { if (!empty($field["allowedExtensions"]) && !empty($info["basename"]) && !GFCommon::match_file_extension(rgar($file_name, 'uploaded_filename'), $allowed_extensions)) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? sprintf(__("The uploaded file type is not allowed. Must be one of the following: %s", "gravityforms"), strtolower($field["allowedExtensions"])) : $field["errorMessage"]; } } } break; case "calculation": case "singleproduct": case "hiddenproduct": $quantity_id = $field["id"] . ".3"; $quantity = rgget($quantity_id, $value); if ($field["isRequired"] && rgblank($quantity) && !rgar($field, "disableQuantity")) { $field["failed_validation"] = true; $field["validation_message"] = rgempty("errorMessage", $field) ? __("This field is required.", "gravityforms") : rgar($field, "errorMessage"); } else { if (!empty($quantity) && (!is_numeric($quantity) || intval($quantity) != floatval($quantity) || intval($quantity) < 0)) { $field["failed_validation"] = true; $field["validation_message"] = __("Please enter a valid quantity", "gravityforms"); } } break; case "radio": if (rgar($field, 'enableOtherChoice') && $value == 'gf_other_choice') { $value = rgpost("input_{$field['id']}_other"); } if ($field["isRequired"] && rgar($field, 'enableOtherChoice') && $value == GFCommon::get_other_choice_value()) { $field["failed_validation"] = true; $field["validation_message"] = empty($field["errorMessage"]) ? __("This field is required.", "gravityforms") : $field["errorMessage"]; } break; } } } } $custom_validation_result = apply_filters("gform_field_validation", array("is_valid" => rgar($field, "failed_validation") ? false : true, "message" => rgar($field, "validation_message")), $value, $form, $field); $custom_validation_result = apply_filters("gform_field_validation_{$form["id"]}", $custom_validation_result, $value, $form, $field); $custom_validation_result = apply_filters("gform_field_validation_{$form["id"]}_{$field["id"]}", $custom_validation_result, $value, $form, $field); $field["failed_validation"] = rgar($custom_validation_result, "is_valid") ? false : true; $field["validation_message"] = rgar($custom_validation_result, "message"); } $is_valid = true; foreach ($form["fields"] as $f) { if (rgar($f, "failed_validation")) { $is_valid = false; break; } } $validation_result = apply_filters("gform_validation_{$form["id"]}", apply_filters("gform_validation", array("is_valid" => $is_valid, "form" => $form))); $is_valid = $validation_result["is_valid"]; $form = $validation_result["form"]; return $is_valid; }
public static function upload() { GFCommon::log_debug("GFAsyncUpload::upload() - Starting"); header('Content-Type: text/html; charset=' . get_option('blog_charset')); send_nosniff_header(); nocache_headers(); status_header(200); // If the file is bigger than the server can accept then the form_id might not arrive. // This might happen if the file is bigger than the max post size ini setting. // Validation in the browser reduces the risk of this happening. if (!isset($_REQUEST["form_id"])) { GFCommon::log_debug("GFAsyncUpload::upload() - File upload aborted because the form_id was not found. The file may have been bigger than the max post size ini setting."); die('{"status" : "error", "error" : {"code": 500, "message": "' . __("Failed to upload file.", "gravityforms") . '"}}'); } $form_id = $_REQUEST["form_id"]; $form_unique_id = rgpost("gform_unique_id"); $form = GFFormsModel::get_form_meta($form_id); if (empty($form)) { die; } $target_dir = GFFormsModel::get_upload_path($form_id) . DIRECTORY_SEPARATOR . "tmp" . DIRECTORY_SEPARATOR; wp_mkdir_p($target_dir); $cleanup_target_dir = true; // Remove old files $maxFileAge = 5 * 3600; // Temp file age in seconds // Chunking is not currently implemented in the front-end because it's not widely supported. The code is left here for when browsers catch up. $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0; $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0; $uploaded_filename = $_FILES["file"]["name"]; $file_name = isset($_REQUEST["name"]) ? $_REQUEST["name"] : ''; $field_id = rgpost("field_id"); $field = GFFormsModel::get_field($form, $field_id); if (empty($field)) { die; } // Clean the fileName for security reasons $file_name = preg_replace('/[^\\w\\._]+/', '_', $file_name); $allowed_extensions = isset($field["allowedExtensions"]) && !empty($field["allowedExtensions"]) ? GFCommon::clean_extensions(explode(",", strtolower($field["allowedExtensions"]))) : array(); $max_upload_size_in_bytes = isset($field["maxFileSize"]) && $field["maxFileSize"] > 0 ? $field["maxFileSize"] * 1048576 : wp_max_upload_size(); $max_upload_size_in_mb = $max_upload_size_in_bytes / 1048576; if ($_FILES['file']['size'] > 0 && $_FILES['file']['size'] > $max_upload_size_in_bytes) { die('{"status" : "error", "error" : {"code": 104, "message": "' . sprintf(__('File exceeds size limit. Maximum file size: %dMB', 'gravityforms'), $max_upload_size_in_mb) . '"}}'); } if (empty($allowed_extensions) && GFCommon::file_name_has_disallowed_extension($uploaded_filename)) { GFCommon::log_debug("GFAsyncUpload::upload() - illegal file extension: {$file_name})"); die('{"status" : "error", "error" : {"code": 104, "message": "' . __("The uploaded file type is not allowed.", "gravityforms") . '"}}'); } elseif (!empty($allowed_extensions) && !GFCommon::match_file_extension($uploaded_filename, $allowed_extensions)) { GFCommon::log_debug("GFAsyncUpload::upload() - The uploaded file type is not allowed: {$file_name})"); die('{"status" : "error", "error" : {"code": 104, "message": "' . sprintf(__("The uploaded file type is not allowed. Must be one of the following: %s", "gravityforms"), strtolower($field["allowedExtensions"])) . '"}}'); } $tmp_file_name = $form_unique_id . "_input_" . $field_id . "_" . $file_name; $file_path = $target_dir . $tmp_file_name; // Remove old temp files if ($cleanup_target_dir) { if (is_dir($target_dir) && ($dir = opendir($target_dir))) { while (($file = readdir($dir)) !== false) { $tmp_file_path = $target_dir . $file; // Remove temp file if it is older than the max age and is not the current file if (preg_match('/\\.part$/', $file) && filemtime($tmp_file_path) < time() - $maxFileAge && $tmp_file_path != "{$file_path}.part") { GFCommon::log_debug("GFAsyncUpload::upload() - Deleting file: " . $tmp_file_path); @unlink($tmp_file_path); } } closedir($dir); } else { GFCommon::log_debug("GFAsyncUpload::upload() - Failed to open temp directory: " . $target_dir); die('{"status" : "error", "error" : {"code": 100, "message": "' . __("Failed to open temp directory.", "gravityforms") . '"}}'); } } // Look for the content type header if (isset($_SERVER["HTTP_CONTENT_TYPE"])) { $contentType = $_SERVER["HTTP_CONTENT_TYPE"]; } if (isset($_SERVER["CONTENT_TYPE"])) { $contentType = $_SERVER["CONTENT_TYPE"]; } // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5 if (strpos($contentType, "multipart") !== false) { if (isset($_FILES["file"]['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) { // Open temp file $out = @fopen("{$file_path}.part", $chunk == 0 ? "wb" : "ab"); if ($out) { // Read binary input stream and append it to temp file $in = @fopen($_FILES["file"]['tmp_name'], "rb"); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } else { die('{"status" : "error", "error" : {"code": 101, "message": "' . __("Failed to open input stream.", "gravityforms") . '"}}'); } @fclose($in); @fclose($out); @unlink($_FILES["file"]['tmp_name']); } else { die('{"status" : "error", "error" : {"code": 102, "message": "' . __("Failed to open output stream.", "gravityforms") . '"}}'); } } else { die('{"status" : "error", "error" : {"code": 103, "message": "' . __("Failed to move uploaded file.", "gravityforms") . '"}}'); } } else { // Open temp file $out = @fopen("{$file_path}.part", $chunk == 0 ? "wb" : "ab"); if ($out) { // Read binary input stream and append it to temp file $in = @fopen("php://input", "rb"); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } else { die('{"status" : "error", "error" : {"code": 101, "message": "' . __("Failed to open input stream.", "gravityforms") . '"}}'); } @fclose($in); @fclose($out); } else { die('{"status" : "error", "error" : {"code": 102, "message": "' . __("Failed to open output stream.", "gravityforms") . '"}}'); } } // Check if file has been uploaded if (!$chunks || $chunk == $chunks - 1) { // Strip the temp .part suffix off rename("{$file_path}.part", $file_path); } if (file_exists($file_path)) { GFFormsModel::set_permissions($file_path); } else { die('{"status" : "error", "error" : {"code": 105, "message": "' . __('Upload unsuccessful:', 'gravityforms') . ' ' . $uploaded_filename . '"}}'); } $output = array("status" => "ok", "data" => array("temp_filename" => $tmp_file_name, "uploaded_filename" => str_replace("\\'", "'", urldecode($uploaded_filename)))); $output = json_encode($output); GFCommon::log_debug(sprintf("GFAsyncUpload::upload() - File upload complete. temp_filename: %s uploaded_filename: %s ", $tmp_file_name, $uploaded_filename)); do_action('gform_post_multifile_upload', $form, $field, $uploaded_filename, $tmp_file_name, $file_path); do_action("gform_post_multifile_upload_{$form["id"]}", $form, $field, $uploaded_filename, $tmp_file_name, $file_path); die($output); }