diff --git includes/menu.inc includes/menu.inc
index 8e2fb1f..c444671 100644
--- includes/menu.inc
+++ includes/menu.inc
@@ -650,11 +650,10 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
       else {
         $item['title'] = call_user_func_array($callback, menu_unserialize($item['title_arguments'], $map));
       }
-      // Avoid calling check_plain again on l() function.
-      if ($callback == 'check_plain') {
-        $item['localized_options']['html'] = TRUE;
-      }
     }
+    // Avoid calling check_plain again on l() function.  All title callbacks
+    // must return sanitized strings.
+    $item['localized_options']['html'] = TRUE;
   }
   elseif ($link_translate) {
     $item['title'] = $item['link_title'];
@@ -2181,7 +2180,9 @@ function menu_get_active_title() {
 
   foreach (array_reverse($active_trail) as $item) {
     if (!(bool)($item['type'] & MENU_IS_LOCAL_TASK)) {
-      return $item['title'];
+      // Text that is user-entered or not passed through a title callback
+      // will not have html set to TRUE.
+      return empty($item['localized_options']['html']) ? check_plain($item['title']) : $item['title'];
     }
   }
 }
diff --git includes/path.inc includes/path.inc
index 68a92a7..2411551 100644
--- includes/path.inc
+++ includes/path.inc
@@ -293,7 +293,7 @@ function drupal_get_title() {
 
   // During a bootstrap, menu.inc is not included and thus we cannot provide a title.
   if (!isset($title) && function_exists('menu_get_active_title')) {
-    $title = check_plain(menu_get_active_title());
+    $title = menu_get_active_title();
   }
 
   return $title;
diff --git modules/simpletest/tests/menu.test modules/simpletest/tests/menu.test
index 53ee3b7..ae02934 100644
--- modules/simpletest/tests/menu.test
+++ modules/simpletest/tests/menu.test
@@ -403,6 +403,13 @@ class MenuRebuildTestCase extends DrupalWebTestCase {
   }
 
   /**
+   * Enable menu_test.module.
+   */
+  public function setUp() {
+    parent::setUp('menu_test');
+  }
+
+  /**
    * Test if the 'menu_rebuild_needed' variable triggers a menu_rebuild() call.
    */
   function testMenuRebuildByVariable() {
@@ -426,6 +433,16 @@ class MenuRebuildTestCase extends DrupalWebTestCase {
     $this->assertEqual($admin_exists, 'admin', t("The menu has been rebuilt, the path 'admin' now exists again."));
   }
 
+  /**
+   * Test title pass through.
+   */
+  function testMenuTitlePassThrough() {
+    $this->drupalGet('menu-test/passthrough');
+    $title = '<span>test</span>';
+    $this->assertRaw($title);
+    $this->assertNoRaw(check_plain($title));
+  }
+
 }
 
 /**
diff --git modules/simpletest/tests/menu_test.module modules/simpletest/tests/menu_test.module
index a51d9fc..34d9f5a 100644
--- modules/simpletest/tests/menu_test.module
+++ modules/simpletest/tests/menu_test.module
@@ -172,7 +172,12 @@ function menu_test_menu() {
     'type' => MENU_LOCAL_TASK,
     'context' => MENU_CONTEXT_NONE,
   );
-
+  $items['menu-test/passthrough'] = array(
+    'title' => '<span>test</span>',
+    'page callback' => 'menu_test_passthrough',
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 }
 
@@ -313,3 +318,10 @@ function menu_test_static_variable($value = NULL) {
   }
   return $variable;
 }
+
+/**
+ * Empty menu callback.
+ */
+function menu_test_passthrough() {
+  return '&nbsp;';
+}
