Index: modules/field/field.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.module,v
retrieving revision 1.81
diff -u -p -r1.81 field.module
--- modules/field/field.module	14 Aug 2010 03:10:04 -0000	1.81
+++ modules/field/field.module	18 Aug 2010 22:55:43 -0000
@@ -219,7 +219,7 @@ function field_modules_disabled($modules
     ->condition('storage_module', $modules, 'IN')
     ->execute();
 
-  field_cache_clear(TRUE);
+  field_cache_clear();
 }
 
 /**
Index: modules/field/modules/text/text.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.module,v
retrieving revision 1.61
diff -u -p -r1.61 text.module
--- modules/field/modules/text/text.module	17 Aug 2010 18:25:31 -0000	1.61
+++ modules/field/modules/text/text.module	18 Aug 2010 23:09:07 -0000
@@ -649,3 +649,20 @@ function text_field_prepare_translation(
     }
   }
 }
+
+/**
+ * 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();
+}
Index: modules/filter/filter.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v
retrieving revision 1.338
diff -u -p -r1.338 filter.module
--- modules/filter/filter.module	17 Aug 2010 13:50:52 -0000	1.338
+++ modules/filter/filter.module	18 Aug 2010 23:15:34 -0000
@@ -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 = 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 
   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);
Index: modules/filter/filter.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.test,v
retrieving revision 1.71
diff -u -p -r1.71 filter.test
--- modules/filter/filter.test	5 Aug 2010 23:53:38 -0000	1.71
+++ modules/filter/filter.test	18 Aug 2010 23:17:58 -0000
@@ -640,6 +640,55 @@ class FilterNoFormatTestCase extends Dru
 }
 
 /**
+ * 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.
  */
 class FilterUnitTestCase extends DrupalUnitTestCase {
Index: modules/simpletest/tests/filter_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/filter_test.module,v
retrieving revision 1.4
diff -u -p -r1.4 filter_test.module
--- modules/simpletest/tests/filter_test.module	4 Dec 2009 16:49:47 -0000	1.4
+++ modules/simpletest/tests/filter_test.module	18 Aug 2010 22:55:43 -0000
@@ -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);
+}
+
Index: modules/system/system-messages.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system-messages.css,v
retrieving revision 1.2
diff -u -p -r1.2 system-messages.css
--- modules/system/system-messages.css	26 May 2010 19:51:01 -0000	1.2
+++ modules/system/system-messages.css	18 Aug 2010 22:55:43 -0000
@@ -12,7 +12,7 @@ div.messages {
 }
 
 div.error,
-tr.error {
+table tr.error {
   background-color: #fcc;
 }
 
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.296
diff -u -p -r1.296 system.admin.inc
--- modules/system/system.admin.inc	18 Aug 2010 18:41:30 -0000	1.296
+++ modules/system/system.admin.inc	18 Aug 2010 23:03:56 -0000
@@ -1243,16 +1243,12 @@ function system_modules_submit($form, &$
     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, &$
 
   // Synchronize to catch any actions that were added or removed.
   actions_synchronize();
-
-  return;
 }
 
 /**
