Cron.php does not check for maintenance mode correctly

Created on 18 October 2018, over 6 years ago
Updated 6 June 2023, over 1 year ago

Problem/Motivation

Cron.php does not check for maintenance mode correctly and causes drupal_deliver_html_page() to call drupal_render_page() with an integer argument under some circumstances.

The problem is when a site has a custom 403 page set, maintenance mode is active and cron.php is accessed.

1. cron.php will call drupal_access_denied().
2. drupal_access_denied() will call drupal_deliver_html_page().
3. And drupal_deliver_html_page() will fail to recognize the maintenance mode, as the $return variable will have a value of MENU_SITE_OFFLINE:

      case MENU_ACCESS_DENIED:
        // Print a 403 page.
        drupal_add_http_header('Status', '403 Forbidden');
        watchdog('access denied', check_plain($_GET['q']), NULL, WATCHDOG_WARNING);

        // Keep old path for reference, and to allow forms to redirect to it.
        if (!isset($_GET['destination'])) {
          // Make sure that the current path is not interpreted as external URL.
          if (!url_is_external($_GET['q'])) {
            $_GET['destination'] = $_GET['q'];
          }
        }

        $path = drupal_get_normal_path(variable_get('site_403', ''));
        if ($path && $path != $_GET['q']) {
          // Custom 403 handler. Set the active item in case there are tabs to
          // display or other dependencies on the path.
          menu_set_active_item($path);
          $return = menu_execute_active_handler($path, FALSE);
        }

        if (empty($return) || $return == MENU_NOT_FOUND || $return == MENU_ACCESS_DENIED) {
          // Standard 403 handler.
          drupal_set_title(t('Access denied'));
          $return = t('You are not authorized to access this page.');
        }

        print drupal_render_page($return);
        break;

This will cause errors:

Cannot use a scalar value as an array block.module:271 
Invalid argument supplied for foreach() common.inc:6594         
Cannot use a scalar value as an array common.inc:6051      
Cannot use a scalar value as an array common.inc:6106

Steps to reproduce

Start with a clean site (ie. minimal profile), then:

  1. Switch on maintenance_mode drush vset maintenance_mode 1
  2. Set a custom access denied page drush vset site_403 'non-empty'
  3. Access the cron.php of your site curl https://example.com/cron.php

The result is this set of errors:

Cannot use a scalar value as an array block.module:271                                                                                                                                                   
Invalid argument supplied for foreach() common.inc:6594                                                                                                                                                  
Cannot use a scalar value as an array common.inc:6051                                                                                                                                                   
Cannot use a scalar value as an array common.inc:6106

Depending on what othen modules you have activated there might be even more errors.

Proposed resolution

Fix the conditions in cron.php to return drupal_site_offline() instead of drupal_access_denied() when the maintenance mode is active.

==== Original report ====

Summary

In drupal_deliver_html_page() in some circumstances menu_execute_active_handler() is called and its return value is directly passed to drupal_render_page() even if it is an integer

Steps to reproduce

Start with a clean site (ie. minimal profile), then:

  1. Switch on maintenance_mode drush vset maintenance_mode 1
  2. Set a custom access denied page drush vset site_403 'non-empty'
  3. Access the cron.php of your site curl https://example.com/cron.php

The result is this set of errors:

Cannot use a scalar value as an array block.module:271                                                                                                                                                   
Invalid argument supplied for foreach() common.inc:6594                                                                                                                                                  
Cannot use a scalar value as an array common.inc:6051                                                                                                                                                   
Cannot use a scalar value as an array common.inc:6106

Depending on what othen modules you have activated there might be even more errors.

Analysis

drupal_deliver_html_page() checks only for MENU_NOT_FOUND and MENU_ACCESS_DENIED before passing the value to drupal_render_page(). This is not sufficent.

Proposed solution

Check for is_int($return) instead of just specific integers.

πŸ› Bug report
Status

Fixed

Version

7.0 ⚰️

Component
RenderΒ  β†’

Last updated 3 days ago

Created by

πŸ‡¦πŸ‡ΉAustria torotil

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024