diff --git a/core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php b/core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php index 904e59c..1c4c23a 100644 --- a/core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php +++ b/core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php @@ -12,6 +12,8 @@ use Drupal\Core\EventSubscriber\MainContentViewSubscriber; use Drupal\Core\Form\FormAjaxException; use Drupal\Core\Form\FormAjaxResponseBuilderInterface; +use Drupal\Core\Form\FormBase; +use Drupal\Core\Form\FormBuilder; use Drupal\Core\Form\FormBuilderInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; @@ -68,9 +70,11 @@ public function onView(GetResponseForControllerResultEvent $event) { */ public function onException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); + $request = $event->getRequest(); - // @todo Comment. - if ($exception instanceof BadRequestHttpException) { + // Render a nice error message in case you have a file upload which exceeds + // the configured upload limit. + if ($exception instanceof BadRequestHttpException && $request->query->get(FormBuilder::AJAX_FORM_REQUEST)) { drupal_set_message($exception->getMessage(), 'error'); $response = new AjaxResponse(); $status_messages = array('#type' => 'status_messages'); diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php index f31471e..fd3c4a7 100644 --- a/core/lib/Drupal/Core/Form/FormBuilder.php +++ b/core/lib/Drupal/Core/Form/FormBuilder.php @@ -265,7 +265,9 @@ public function buildForm($form_id, FormStateInterface &$form_state) { // can use it to know or update information about the state of the form. $response = $this->processForm($form_id, $form, $form_state); - // @todo Comment. + // In case the post request exceeds the configured allowed size + // (post_max_size), the post request is potentially broken. Add some + // protection against that and at the same time have a nice error message. if ($ajax_form_request && !isset($form_state->getUserInput()['form_id'])) { throw new BadRequestHttpException(t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', array('@size' => format_size(file_upload_max_size())))); } diff --git a/core/modules/file/src/Tests/FileManagedFileElementTest.php b/core/modules/file/src/Tests/FileManagedFileElementTest.php index 8368610..1bd46c0 100644 --- a/core/modules/file/src/Tests/FileManagedFileElementTest.php +++ b/core/modules/file/src/Tests/FileManagedFileElementTest.php @@ -6,6 +6,8 @@ */ namespace Drupal\file\Tests; +use Drupal\Component\Utility\SafeMarkup; +use Drupal\file\Entity\File; /** * Tests the 'managed_file' element type. @@ -106,6 +108,31 @@ function testManagedFile() { $this->drupalPostForm(NULL, array(), t('Save')); $this->assertRaw(t('The file ids are %fids.', array('%fids' => '')), 'Submission after file upload and removal was successful.'); + + // Upload a file which exceeds the configured post_max_size limit. + $post_max_size_init = ini_get('post_max_size'); + if ($post_max_size_init) { + // Parse the upload size in order to produce a file bigger as it. + $regex = '/^([0-9]+)([bkmgtpezy])$/i'; + preg_match($regex, $post_max_size_init, $match); + $post_max_size = round($match[1] * pow(1024, stripos('bkmgtpezy', strtolower($match[2])))); + $big_test_data = str_repeat('a', $post_max_size * 1.1); + file_put_contents('public://test.dat', $big_test_data); + + /** @var \Drupal\Core\File\FileSystemInterface $file_system */ + $file_system = \Drupal::service('file_system'); + $edit = array($file_field_name => $file_system->realpath('public://test.dat')); + if ($ajax) { + $this->drupalPostAjaxForm(NULL, $edit, $input_base_name . '_upload_button'); + $this->assertText(SafeMarkup::format('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@post_max_size) that this server supports.', ['@post_max_size' => $post_max_size_init])); + } + else { + // @todo Currently the post request just fails, as there is no + // input, so I guess we can't protect against it? This would + // be odd. + $this->drupalPostForm(NULL, $edit, t('Upload')); + } + } } } }