- Patch #358437 by David_Rothstein, Berdir, sun: filter system security fixes from SA-2008-073 not applied to Drupal 7.x.
parent
b0894ceaa7
commit
b36d4959ef
|
@ -219,7 +219,7 @@ function field_modules_disabled($modules) {
|
|||
->condition('storage_module', $modules, 'IN')
|
||||
->execute();
|
||||
|
||||
field_cache_clear(TRUE);
|
||||
field_cache_clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -649,3 +649,20 @@ function text_field_prepare_translation($entity_type, $entity, $field, $instance
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_filter_format_update().
|
||||
*/
|
||||
function text_filter_format_update() {
|
||||
field_cache_clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_filter_format_delete().
|
||||
*
|
||||
* @todo D8: Properly update filter format references in all fields. See
|
||||
* http://drupal.org/node/556022 for details.
|
||||
*/
|
||||
function text_filter_format_delete() {
|
||||
field_cache_clear();
|
||||
}
|
||||
|
|
|
@ -187,6 +187,10 @@ function filter_format_load($format_id) {
|
|||
function filter_format_save(&$format) {
|
||||
$format->name = trim($format->name);
|
||||
$format->cache = _filter_format_is_cacheable($format);
|
||||
// Programmatic saves may not contain any filters.
|
||||
if (!isset($format->filters)) {
|
||||
$format->filters = array();
|
||||
}
|
||||
|
||||
// Add a new text format.
|
||||
if (empty($format->format)) {
|
||||
|
@ -197,10 +201,6 @@ function filter_format_save(&$format) {
|
|||
}
|
||||
|
||||
$filter_info = filter_get_filters();
|
||||
// Programmatic saves may not contain any filters.
|
||||
if (!isset($format->filters)) {
|
||||
$format->filters = array();
|
||||
}
|
||||
foreach ($filter_info as $name => $filter) {
|
||||
// Add new filters without weight to the bottom.
|
||||
if (!isset($format->filters[$name]['weight'])) {
|
||||
|
@ -280,6 +280,7 @@ function filter_format_delete($format, $fallback_id = NULL) {
|
|||
$fallback = filter_format_load($fallback_id);
|
||||
module_invoke_all('filter_format_delete', $format, $fallback);
|
||||
|
||||
// Clear the filter cache whenever a text format is deleted.
|
||||
filter_formats_reset();
|
||||
cache_clear_all($format->format . ':', 'cache_filter', TRUE);
|
||||
}
|
||||
|
@ -681,7 +682,11 @@ function check_markup($text, $format_id = NULL, $langcode = '', $cache = FALSE)
|
|||
if (empty($format_id)) {
|
||||
$format_id = filter_fallback_format();
|
||||
}
|
||||
$format = filter_format_load($format_id);
|
||||
// If the requested text format does not exist, the text cannot be filtered.
|
||||
if (!$format = filter_format_load($format_id)) {
|
||||
watchdog('filter', 'Missing text format: %format.', array('%format' => $format_id), WATCHDOG_ALERT);
|
||||
return '';
|
||||
}
|
||||
|
||||
// Check for a cached version of this piece of text.
|
||||
$cache = $cache && !empty($format->cache);
|
||||
|
|
|
@ -639,6 +639,55 @@ class FilterNoFormatTestCase extends DrupalWebTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Security tests for missing/vanished text formats or filters.
|
||||
*/
|
||||
class FilterSecurityTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Security',
|
||||
'description' => 'Test the behavior of check_markup() when a filter or text format vanishes.',
|
||||
'group' => 'Filter',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('php', 'filter_test');
|
||||
$this->admin_user = $this->drupalCreateUser(array('administer modules', 'administer filters', 'administer site configuration'));
|
||||
$this->drupalLogin($this->admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that filtered content is emptied when an actively used filter module is disabled.
|
||||
*/
|
||||
function testDisableFilterModule() {
|
||||
// Create a new node.
|
||||
$node = $this->drupalCreateNode(array('promote' => 1));
|
||||
$body_raw = $node->body[LANGUAGE_NONE][0]['value'];
|
||||
$format_id = $node->body[LANGUAGE_NONE][0]['format'];
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->assertText($body_raw, t('Node body found.'));
|
||||
|
||||
// Enable the filter_test_replace filter.
|
||||
$edit = array(
|
||||
'filters[filter_test_replace][status]' => 1,
|
||||
);
|
||||
$this->drupalPost('admin/config/content/formats/' . $format_id, $edit, t('Save configuration'));
|
||||
|
||||
// Verify that filter_test_replace filter replaced the content.
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->assertNoText($body_raw, t('Node body not found.'));
|
||||
$this->assertText('Filter: Testing filter', t('Testing filter output found.'));
|
||||
|
||||
// Delete the text format entirely.
|
||||
$this->drupalPost('admin/config/content/formats/' . $format_id . '/delete', array(), t('Delete'));
|
||||
|
||||
// Verify that the content is empty, because the text format does not exist.
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->assertNoText($body_raw, t('Node body not found.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests for core filters.
|
||||
*/
|
||||
|
|
|
@ -36,6 +36,28 @@ function filter_test_filter_info() {
|
|||
'description' => 'Does nothing, but makes a text format uncacheable.',
|
||||
'cache' => FALSE,
|
||||
);
|
||||
$filters['filter_test_replace'] = array(
|
||||
'title' => 'Testing filter',
|
||||
'description' => 'Replaces all content with filter and text format information.',
|
||||
'process callback' => 'filter_test_replace',
|
||||
);
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process handler for filter_test_replace filter.
|
||||
*
|
||||
* Replaces all text with filter and text format information.
|
||||
*/
|
||||
function filter_test_replace($text, $filter, $format, $langcode, $cache, $cache_id) {
|
||||
$text = array();
|
||||
$text[] = 'Filter: ' . $filter->title . ' (' . $filter->name . ')';
|
||||
$text[] = 'Format: ' . $format->name . ' (' . $format->format . ')';
|
||||
$text[] = 'Language: ' . $langcode;
|
||||
$text[] = 'Cache: ' . ($cache ? 'Enabled' : 'Disabled');
|
||||
if ($cache_id) {
|
||||
$text[] = 'Cache ID: ' . $cache_id;
|
||||
}
|
||||
return implode("<br />\n", $text);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ div.messages {
|
|||
}
|
||||
|
||||
div.error,
|
||||
tr.error {
|
||||
table tr.error {
|
||||
background-color: #fcc;
|
||||
}
|
||||
|
||||
|
|
|
@ -1243,16 +1243,12 @@ function system_modules_submit($form, &$form_state) {
|
|||
drupal_set_message(t('The configuration options have been saved.'));
|
||||
}
|
||||
|
||||
// Clear all caches.
|
||||
registry_rebuild();
|
||||
system_rebuild_theme_data();
|
||||
drupal_theme_rebuild();
|
||||
node_types_rebuild();
|
||||
menu_rebuild();
|
||||
cache_clear_all('schema', 'cache');
|
||||
// Clear all caches. We need to invoke drupal_flush_all_caches() to ensure
|
||||
// that also dependent caches are flushed, e.g. the filter cache and field
|
||||
// cache, and also registered themes are rebuilt, since modules can also
|
||||
// register themes.
|
||||
drupal_flush_all_caches();
|
||||
entity_info_cache_clear();
|
||||
drupal_clear_css_cache();
|
||||
drupal_clear_js_cache();
|
||||
|
||||
$form_state['redirect'] = 'admin/modules';
|
||||
|
||||
|
@ -1263,8 +1259,6 @@ function system_modules_submit($form, &$form_state) {
|
|||
|
||||
// Synchronize to catch any actions that were added or removed.
|
||||
actions_synchronize();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue