From be14203534c5f09d0c70c2bf59b81b80f2a90b32 Mon Sep 17 00:00:00 2001
From: Steven Wittens <steven@10.no-reply.drupal.org>
Date: Thu, 31 Mar 2005 09:25:33 +0000
Subject: [PATCH] - #18817: Clean up plain-text checking (see drupal-devel!)

---
 includes/bootstrap.inc                    | 12 ++--
 includes/common.inc                       | 72 ++++++++++-------------
 includes/file.inc                         |  8 +--
 includes/locale.inc                       | 52 ++++++++--------
 includes/pager.inc                        |  6 +-
 includes/tablesort.inc                    |  4 +-
 includes/theme.inc                        | 22 +++++--
 modules/aggregator.module                 | 48 +++++++--------
 modules/aggregator/aggregator.module      | 48 +++++++--------
 modules/archive.module                    |  2 +-
 modules/archive/archive.module            |  2 +-
 modules/block.module                      |  8 +--
 modules/block/block.module                |  8 +--
 modules/blogapi.module                    |  4 +-
 modules/blogapi/blogapi.module            |  4 +-
 modules/book.module                       | 18 +++---
 modules/book/book.module                  | 18 +++---
 modules/comment.module                    | 31 +++++-----
 modules/comment/comment.module            | 31 +++++-----
 modules/contact.module                    |  2 +-
 modules/contact/contact.module            |  2 +-
 modules/drupal.module                     |  4 +-
 modules/drupal/drupal.module              |  4 +-
 modules/filter.module                     | 18 +++---
 modules/filter/filter.module              | 18 +++---
 modules/forum.module                      | 12 ++--
 modules/forum/forum.module                | 12 ++--
 modules/locale.module                     |  9 +--
 modules/locale/locale.module              |  9 +--
 modules/menu.module                       | 14 ++---
 modules/menu/menu.module                  | 14 ++---
 modules/node.module                       | 29 +++++----
 modules/node/node.module                  | 29 +++++----
 modules/path.module                       |  6 +-
 modules/path/path.module                  |  6 +-
 modules/poll.module                       | 10 ++--
 modules/poll/poll.module                  | 10 ++--
 modules/profile.module                    | 36 ++++++------
 modules/profile/profile.module            | 36 ++++++------
 modules/queue.module                      | 10 ++--
 modules/search.module                     | 10 ++--
 modules/search/search.module              | 10 ++--
 modules/statistics.module                 |  2 +-
 modules/statistics/statistics.module      |  2 +-
 modules/taxonomy.module                   | 18 +++---
 modules/taxonomy/taxonomy.module          | 18 +++---
 modules/upload.module                     |  8 +--
 modules/upload/upload.module              |  8 +--
 modules/user.module                       | 58 +++++++++---------
 modules/user/user.module                  | 58 +++++++++---------
 themes/chameleon/chameleon.theme          |  8 ++-
 themes/engines/xtemplate/xtemplate.engine |  4 +-
 52 files changed, 454 insertions(+), 438 deletions(-)

diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 509779049897..3ec57384612a 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -393,7 +393,7 @@ function drupal_get_title() {
   if (!isset($title)) {
     // during a bootstrap, menu.inc is not included and thus we cannot provide a title
     if (function_exists('menu_get_active_title')) {
-      $title = menu_get_active_title();
+      $title = check_plain(menu_get_active_title());
     }
   }
 
@@ -509,7 +509,7 @@ function drupal_unpack($obj, $field = 'data') {
  */
 function referer_uri() {
   if (isset($_SERVER['HTTP_REFERER'])) {
-    return check_url($_SERVER['HTTP_REFERER']);
+    return $_SERVER['HTTP_REFERER'];
   }
 }
 
@@ -537,14 +537,14 @@ function arg($index) {
 }
 
 /**
- * Prepare user input for use in a URI.
+ * Prepare a URL for use in an HTML attribute.
  *
- * We replace ( and ) with their entity equivalents to prevent XSS attacks.
+ * We replace ( and ) with their url-encoded equivalents to prevent XSS attacks.
  */
 function check_url($uri) {
   $uri = htmlspecialchars($uri, ENT_QUOTES);
 
-  $uri = strtr($uri, array('(' => '&040;', ')' => '&041;'));
+  $uri = strtr($uri, array('(' => '%28', ')' => '%29'));
 
   return $uri;
 }
@@ -567,7 +567,7 @@ function request_uri() {
     }
   }
 
-  return check_url($uri);
+  return $uri;
 }
 
 /**
diff --git a/includes/common.inc b/includes/common.inc
index f3abbac85a52..b6a8807c8fe5 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -173,8 +173,7 @@ function drupal_goto($path = '', $query = NULL, $fragment = NULL) {
     extract(parse_url($_REQUEST['edit']['destination']));
   }
 
-  // Translate &amp; to simply & in the absolute URL.
-  $url = str_replace('&amp;', '&', url($path, $query, $fragment, TRUE));
+  $url = url($path, $query, $fragment, TRUE);
 
   if (ini_get('session.use_trans_sid') && session_id() && !strstr($url, session_id())) {
     $sid = session_name() . '=' . session_id();
@@ -203,7 +202,7 @@ function drupal_goto($path = '', $query = NULL, $fragment = NULL) {
  */
 function drupal_not_found() {
   header('HTTP/1.0 404 Not Found');
-  watchdog('page not found', t('%page not found.', array('%page' => '<em>'. db_escape_string($_GET['q']) .'</em>')), WATCHDOG_WARNING);
+  watchdog('page not found', t('%page not found.', array('%page' => theme('placeholder', $_GET['q']))), WATCHDOG_WARNING);
 
   $path = drupal_get_normal_path(variable_get('site_404', ''));
   $status = MENU_NOT_FOUND;
@@ -223,7 +222,7 @@ function drupal_not_found() {
  */
 function drupal_access_denied() {
   header('HTTP/1.0 403 Forbidden');
-  watchdog('access denied', t('%page denied access.', array('%page' => '<em>'. db_escape_string($_GET['q']) .'</em>')), WATCHDOG_WARNING, l(t('view'), $_GET['q']));
+  watchdog('access denied', t('%page denied access.', array('%page' => theme('placeholder', $_GET['q']))), WATCHDOG_WARNING, l(t('view'), $_GET['q']));
 
   $path = drupal_get_normal_path(variable_get('site_403', ''));
   $status = MENU_NOT_FOUND;
@@ -549,15 +548,10 @@ function t($string, $args = 0) {
 }
 
 /**
- * Encode special characters in a string for display as HTML.
- *
- * Note that we'd like to use htmlspecialchars($input, $quotes, 'utf-8')
- * as outlined in the PHP manual, but we can't because there's a bug in
- * PHP < 4.3 that makes it mess up multibyte charsets if we specify the
- * charset. This will be changed later once we make PHP 4.3 a requirement.
+ * Encode special characters in a plain-text string for display as HTML.
  */
-function drupal_specialchars($input, $quotes = ENT_NOQUOTES) {
-  return htmlspecialchars($input, $quotes);
+function check_plain($text) {
+  return htmlspecialchars($text, ENT_QUOTES);
 }
 
 /**
@@ -642,7 +636,7 @@ function valid_input_data($data) {
     $match += preg_match("/<\s*(applet|script|object|style|embed|form|blink|meta|html|frame|iframe|layer|ilayer|head|frameset|xml)/i", $data);
 
     if ($match) {
-      watchdog('security', t('Terminated request because of suspicious input data: %data.', array('%data' => '<em>'. drupal_specialchars($data) .'</em>')));
+      watchdog('security', t('Terminated request because of suspicious input data: %data.', array('%data' => theme('placeholder', $data))));
       return FALSE;
     }
   }
@@ -680,10 +674,6 @@ function flood_is_allowed($name, $threshold) {
   return ($number < $threshold ? TRUE : FALSE);
 }
 
-function check_form($text) {
-  return drupal_specialchars($text, ENT_QUOTES);
-}
-
 function check_file($filename) {
   return is_uploaded_file($filename);
 }
@@ -703,12 +693,12 @@ function format_rss_channel($title, $link, $description, $items, $language = 'en
   // arbitrary elements may be added using the $args associative array
 
   $output = "<channel>\n";
-  $output .= ' <title>'. drupal_specialchars(strip_tags($title)) ."</title>\n";
-  $output .= ' <link>'. drupal_specialchars(strip_tags($link)) ."</link>\n";
-  $output .= ' <description>'. drupal_specialchars(strip_tags($description)) ."</description>\n";
-  $output .= ' <language>'. drupal_specialchars(strip_tags($language)) ."</language>\n";
+  $output .= ' <title>'. check_plain($title) ."</title>\n";
+  $output .= ' <link>'. check_url($link) ."</link>\n";
+  $output .= ' <description>'. check_plain($description) ."</description>\n";
+  $output .= ' <language>'. check_plain($language) ."</language>\n";
   foreach ($args as $key => $value) {
-    $output .= ' <'. $key .'>'. drupal_specialchars(strip_tags($value)) ."</$key>\n";
+    $output .= ' <'. $key .'>'. check_plain($value) ."</$key>\n";
   }
   $output .= $items;
   $output .= "</channel>\n";
@@ -723,9 +713,9 @@ function format_rss_channel($title, $link, $description, $items, $language = 'en
  */
 function format_rss_item($title, $link, $description, $args = array()) {
   $output = "<item>\n";
-  $output .= ' <title>'. drupal_specialchars(strip_tags($title)) ."</title>\n";
-  $output .= ' <link>'. drupal_specialchars(strip_tags($link)) ."</link>\n";
-  $output .= ' <description>'. drupal_specialchars($description) ."</description>\n";
+  $output .= ' <title>'. check_plain($title) ."</title>\n";
+  $output .= ' <link>'. check_url($link) ."</link>\n";
+  $output .= ' <description>'. check_plain($description) ."</description>\n";
   foreach ($args as $key => $value) {
     if (is_array($value)) {
       if ($value['key']) {
@@ -743,7 +733,7 @@ function format_rss_item($title, $link, $description, $args = array()) {
       }
     }
     else {
-      $output .= ' <'. $key .'>'. drupal_specialchars(strip_tags($value)) ."</$key>\n";
+      $output .= ' <'. $key .'>'. check_plain($value) ."</$key>\n";
     }
   }
   $output .= "</item>\n";
@@ -1212,7 +1202,7 @@ function form_checkboxes($title, $name, $values, $options, $description = NULL,
  */
 function form_textfield($title, $name, $value, $size, $maxlength, $description = NULL, $attributes = NULL, $required = FALSE) {
   $size = $size ? ' size="'. $size .'"' : '';
-  return theme('form_element', $title, '<input type="text" maxlength="'. $maxlength .'" class="'. _form_get_class('form-text', $required, _form_get_error($name)) .'" name="edit['. $name .']" id="edit-'. $name .'"'. $size .' value="'. check_form($value) .'"'. drupal_attributes($attributes) .' />', $description, 'edit-'. $name, $required, _form_get_error($name));
+  return theme('form_element', $title, '<input type="text" maxlength="'. $maxlength .'" class="'. _form_get_class('form-text', $required, _form_get_error($name)) .'" name="edit['. $name .']" id="edit-'. $name .'"'. $size .' value="'. check_plain($value) .'"'. drupal_attributes($attributes) .' />', $description, 'edit-'. $name, $required, _form_get_error($name));
 }
 
 /**
@@ -1239,7 +1229,7 @@ function form_textfield($title, $name, $value, $size, $maxlength, $description =
  */
 function form_password($title, $name, $value, $size, $maxlength, $description = NULL, $attributes = NULL, $required = FALSE) {
   $size = $size ? ' size="'. $size .'"' : '';
-  return theme('form_element', $title, '<input type="password" class="'. _form_get_class('form-password', $required, _form_get_error($name)) .'" maxlength="'. $maxlength .'" name="edit['. $name .']" id="edit-'. $name .'"'. $size .' value="'. check_form($value) .'"'. drupal_attributes($attributes) .' />', $description, 'edit-'. $name, $required, _form_get_error($name));
+  return theme('form_element', $title, '<input type="password" class="'. _form_get_class('form-password', $required, _form_get_error($name)) .'" maxlength="'. $maxlength .'" name="edit['. $name .']" id="edit-'. $name .'"'. $size .' value="'. check_plain($value) .'"'. drupal_attributes($attributes) .' />', $description, 'edit-'. $name, $required, _form_get_error($name));
 }
 
 /**
@@ -1275,7 +1265,7 @@ function form_textarea($title, $name, $value, $cols, $rows, $description = NULL,
     }
   }
 
-  $output .= theme('form_element', $title, '<textarea wrap="virtual"'. $cols .' rows="'. $rows .'" name="edit['. $name .']" id="edit-'. $name .'" class="'. _form_get_class('textarea', $required, _form_get_error($name)) .'"'. drupal_attributes($attributes) .'>'. check_form($value) .'</textarea>', $description, 'edit-'. $name, $required, _form_get_error($name));
+  $output .= theme('form_element', $title, '<textarea wrap="virtual"'. $cols .' rows="'. $rows .'" name="edit['. $name .']" id="edit-'. $name .'" class="'. _form_get_class('textarea', $required, _form_get_error($name)) .'"'. drupal_attributes($attributes) .'>'. check_plain($value) .'</textarea>', $description, 'edit-'. $name, $required, _form_get_error($name));
 
   // e.g. optionally plug in a WYSIWYG editor
   foreach (module_list() as $module_name) {
@@ -1321,12 +1311,12 @@ function form_select($title, $name, $value, $options, $description = NULL, $extr
     if (is_array($choice)) {
       $select .= '<optgroup label="'. $key .'">';
       foreach ($choice as $key => $choice) {
-        $select .= '<option value="'. $key .'"'. (is_array($value) ? (in_array($key, $value) ? ' selected="selected"' : '') : ($value == $key ? ' selected="selected"' : '')) .'>'. check_form($choice) .'</option>';
+        $select .= '<option value="'. $key .'"'. (is_array($value) ? (in_array($key, $value) ? ' selected="selected"' : '') : ($value == $key ? ' selected="selected"' : '')) .'>'. check_plain($choice) .'</option>';
       }
       $select .= '</optgroup>';
     }
     else {
-      $select .= '<option value="'. $key .'"'. (is_array($value) ? (in_array($key, $value) ? ' selected="selected"' : '') : ($value == $key ? ' selected="selected"' : '')) .'>'. check_form($choice) .'</option>';
+      $select .= '<option value="'. $key .'"'. (is_array($value) ? (in_array($key, $value) ? ' selected="selected"' : '') : ($value == $key ? ' selected="selected"' : '')) .'>'. check_plain($choice) .'</option>';
     }
   }
   return theme('form_element', $title, '<select name="edit['. $name .']'. ($multiple ? '[]' : '') .'"'. ($multiple ? ' multiple="multiple" ' : '') . ($extra ? ' '. $extra : '') .' id="edit-'. $name .'">'. $select .'</select>', $description, 'edit-'. $name, $required, _form_get_error($name));
@@ -1370,7 +1360,7 @@ function form_file($title, $name, $size, $description = NULL, $required = FALSE)
  * an attacker to change the value before it is submitted.
  */
 function form_hidden($name, $value) {
-  return '<input type="hidden" name="edit['. $name .']" value="'. check_form($value) ."\" />\n";
+  return '<input type="hidden" name="edit['. $name .']" value="'. check_plain($value) ."\" />\n";
 }
 
 /**
@@ -1389,7 +1379,7 @@ function form_hidden($name, $value) {
  *   A themed HTML string representing the button.
  */
 function form_button($value, $name = 'op', $type = 'submit', $attributes = NULL) {
-  return '<input type="'. $type .'" class="form-'. $type .'" name="'. $name .'" value="'. check_form($value) .'" '. drupal_attributes($attributes) ." />\n";
+  return '<input type="'. $type .'" class="form-'. $type .'" name="'. $name .'" value="'. check_plain($value) .'" '. drupal_attributes($attributes) ." />\n";
 }
 
 /**
@@ -1476,12 +1466,12 @@ function url($path = NULL, $query = NULL, $fragment = NULL, $absolute = FALSE) {
     $fragment = '#'. $fragment;
   }
 
-  $base = ($absolute ? $base_url . '/' : '');
+  $base = ($absolute ? $base_url .'/' : '');
 
   if (variable_get('clean_url', '0') == '0') {
     if (isset($path)) {
       if (isset($query)) {
-        return $base . $script .'?q='. $path .'&amp;'. $query . $fragment;
+        return $base . $script .'?q='. $path .'&'. $query . $fragment;
       }
       else {
         return $base . $script .'?q='. $path . $fragment;
@@ -1528,7 +1518,7 @@ function drupal_attributes($attributes = array()) {
   if ($attributes) {
     $t = array();
     foreach ($attributes as $key => $value) {
-      $t[] = $key .'="'. $value .'"';
+      $t[] = $key .'="'. check_plain($value) .'"';
     }
 
     return ' '. implode($t, ' ');
@@ -1555,10 +1545,12 @@ function drupal_attributes($attributes = array()) {
  * @param $absolute
  *   Whether to force the output to be an absolute link (beginning with http:).
  *   Useful for links that will be displayed outside the site, such as in an RSS feed.
+ * @param $html
+ *   Whether the title is HTML, or just plain-text.
  * @return
  *   an HTML string containing a link to the given path.
  */
-function l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE) {
+function l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE) {
   if (drupal_get_normal_path($path) == $_GET['q']) {
     if (isset($attributes['class'])) {
       $attributes['class'] .= ' active';
@@ -1567,7 +1559,7 @@ function l($text, $path, $attributes = array(), $query = NULL, $fragment = NULL,
       $attributes['class'] = 'active';
     }
   }
-  return '<a href="'. url($path, $query, $fragment, $absolute) .'"'. drupal_attributes($attributes) .'>'. $text .'</a>';
+  return '<a href="'. check_url(url($path, $query, $fragment, $absolute)) .'"'. drupal_attributes($attributes) .'>'. ($html ? $text : check_plain($text)) .'</a>';
 }
 
 /**
@@ -1679,7 +1671,7 @@ function drupal_convert_to_utf8($data, $encoding) {
     $out = @mb_convert_encoding($data, 'utf-8', $encoding);
   }
   else if (function_exists('recode_string')) {
-    $out = @recode_string($encoding . '..utf-8', $data);
+    $out = @recode_string($encoding .'..utf-8', $data);
   }
   else {
     watchdog('php', t("Unsupported encoding '%s'. Please install iconv, GNU recode or mbstring for PHP.", $encoding), WATCHDOG_ERROR);
@@ -1705,7 +1697,7 @@ function drupal_convert_to_utf8($data, $encoding) {
  * @param $len
  *   An upper limit on the returned string length.
  * @param $wordsafe
- *   Flag to truncate at nearest word boundary. Defaults to FALSE.
+ *   Flag to truncate at nearest space. Defaults to FALSE.
  * @return
  *   The truncated string.
  */
diff --git a/includes/file.inc b/includes/file.inc
index b8bf30b1135e..18ce0f9d917d 100644
--- a/includes/file.inc
+++ b/includes/file.inc
@@ -76,11 +76,11 @@ function file_check_directory(&$directory, $mode = 0, $form_item = NULL) {
   // Check if directory exists.
   if (!is_dir($directory)) {
     if (($mode & FILE_CREATE_DIRECTORY) && @mkdir($directory, 0760)) {
-      drupal_set_message(t('Created directory %directory.', array('%directory' => "<em>$directory</em>")));
+      drupal_set_message(t('Created directory %directory.', array('%directory' => theme('placeholder', $directory))));
     }
     else {
       if ($form_item) {
-        form_set_error($form_item, t('The directory %directory does not exist.', array('%directory' => "<em>$directory</em>")));
+        form_set_error($form_item, t('The directory %directory does not exist.', array('%directory' => theme('placeholder', $directory))));
       }
       return false;
     }
@@ -89,10 +89,10 @@ function file_check_directory(&$directory, $mode = 0, $form_item = NULL) {
   // Check to see if the directory is writable.
   if (!is_writable($directory)) {
     if (($mode & FILE_MODIFY_PERMISSIONS) && @chmod($directory, 0760)) {
-      drupal_set_message(t('Modified permissions on directory %directory.', array('%directory' => "<em>$directory</em>")));
+      drupal_set_message(t('Modified permissions on directory %directory.', array('%directory' => theme('placeholder', $directory))));
     }
     else {
-      form_set_error($form_item, t('The directory %directory is not writable.', array('%directory' => "<em>$directory</em>")));
+      form_set_error($form_item, t('The directory %directory is not writable.', array('%directory' => theme('placeholder', $directory))));
       return false;
     }
   }
diff --git a/includes/locale.inc b/includes/locale.inc
index 03e6dd098283..77bae2b81db2 100644
--- a/includes/locale.inc
+++ b/includes/locale.inc
@@ -23,14 +23,14 @@ function _locale_add_language($code, $name, $onlylanguage = TRUE) {
   // the language addition, we need to inform the user on how to start
   // a translation
   if ($onlylanguage) {
-    $message = t('%locale language added. You can now import a translation. See the <a href="%locale-help">help screen</a> for more information.', array('%locale' => '<em>'. t($name) .'</em>', '%locale-help' => url('admin/help/locale')));
+    $message = t('%locale language added. You can now import a translation. See the <a href="%locale-help">help screen</a> for more information.', array('%locale' => theme('placeholder', t($name)), '%locale-help' => url('admin/help/locale')));
   }
   else {
-    $message = t('%locale language added.', array('%locale' => '<em>'. t($name) .'</em>'));
+    $message = t('%locale language added.', array('%locale' => theme('placeholder', t($name))));
   }
 
   drupal_set_message($message);
-  watchdog('locale', t('%language language (%locale) added.', array('%language' => "<em>$name</em>", '%locale' => "<em>$code</em>")));
+  watchdog('locale', t('%language language (%locale) added.', array('%language' => theme('placeholder', $name), '%locale' => theme('placeholder', $code))));
 }
 
 /**
@@ -47,7 +47,7 @@ function _locale_admin_manage_screen() {
     $status = db_fetch_object(db_query("SELECT isdefault, enabled FROM {locales_meta} WHERE locale = '%s'", $key));
 
     if ($key == 'en') {
-      $rows[] = array('en', $lang, form_checkbox('', 'enabled][en', 1, $status->enabled), form_radio('', 'sitedefault', $key, $status->isdefault), message_na(), '');
+      $rows[] = array('en', check_plain($lang), form_checkbox('', 'enabled][en', 1, $status->enabled), form_radio('', 'sitedefault', $key, $status->isdefault), message_na(), '');
     }
     else {
       $original = db_fetch_object(db_query("SELECT COUNT(*) AS strings FROM {locales_source}"));
@@ -55,7 +55,7 @@ function _locale_admin_manage_screen() {
 
       $ratio = ($original->strings > 0 && $translation->translation > 0) ? round(($translation->translation/$original->strings)*100., 2) : 0;
 
-      $rows[] = array($key, ($key != 'en' ? form_textfield('', 'name]['. $key, $lang, 15, 64) : $lang), form_checkbox('', 'enabled]['. $key, 1, $status->enabled), form_radio('', 'sitedefault', $key, $status->isdefault), "$translation->translation/$original->strings ($ratio%)", ($key != 'en' ? l(t('delete'), 'admin/locale/language/delete/'. urlencode($key)) : ''));
+      $rows[] = array(check_plain($key), ($key != 'en' ? form_textfield('', 'name]['. $key, $lang, 15, 64) : $lang), form_checkbox('', 'enabled]['. $key, 1, $status->enabled), form_radio('', 'sitedefault', $key, $status->isdefault), "$translation->translation/$original->strings ($ratio%)", ($key != 'en' ? l(t('delete'), 'admin/locale/language/delete/'. urlencode($key)) : ''));
     }
   }
 
@@ -132,7 +132,7 @@ function _locale_import_po($file, $lang, $mode) {
 
   // Check if we can get the strings from the file
   if (!($strings = _locale_import_read_po($file))) {
-    drupal_set_message(t('Translation file %filename broken: Could not be read.', array('%filename' => "<em>$file->filename</em>")), 'error');
+    drupal_set_message(t('Translation file %filename broken: Could not be read.', array('%filename' => theme('placeholder', $file->filename))), 'error');
     return FALSE;
   }
 
@@ -154,7 +154,7 @@ function _locale_import_po($file, $lang, $mode) {
     }
   }
   else {
-    drupal_set_message(t('Translation file %filename broken: No header.', array('%filename' => "<em>$file->filename</em>")), 'error');
+    drupal_set_message(t('Translation file %filename broken: No header.', array('%filename' => theme('placeholder', $file->filename))), 'error');
     return FALSE;
   }
 
@@ -257,7 +257,7 @@ function _locale_import_po($file, $lang, $mode) {
   menu_rebuild();
 
   drupal_set_message(t('Translation successfully imported. %number translated strings added to language, %update strings updated.', array('%number' => $additions, '%update' => $updates)));
-  watchdog('locale', t('Imported %file into %locale: %number new strings added and %update updated.', array('%file' => "<em>$file->filename</em>", '%locale' => "<em>$lang</em>", '%number' => $additions, '%update' => $updates)));
+  watchdog('locale', t('Imported %file into %locale: %number new strings added and %update updated.', array('%file' => theme('placeholder', $file->filename), '%locale' => theme('placeholder', $lang), '%number' => $additions, '%update' => $updates)));
   return TRUE;
 }
 
@@ -269,9 +269,10 @@ function _locale_import_po($file, $lang, $mode) {
  */
 function _locale_import_read_po($file) {
 
+  $message = theme('placeholder', $file->filename);
   $fd = fopen($file->filepath, "rb");
   if (!$fd) {
-    drupal_set_message(t('Translation import failed: file %filename cannot be read.', array('%filename' => "<em>$file->filename</em>")), 'error');
+    drupal_set_message(t('Translation import failed: file %filename cannot be read.', array('%filename' => $message)), 'error');
     return FALSE;
   }
   $info = fstat($fd);
@@ -303,19 +304,19 @@ function _locale_import_read_po($file) {
         $context = "COMMENT";
       }
       else { // Parse error
-        drupal_set_message(t("Translation file %filename broken: expected 'msgstr' in line %line.", array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t("Translation file %filename broken: expected 'msgstr' in line %line.", array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
     }
     elseif (!strncmp("msgid_plural", $line, 12)) {
       if ($context != "MSGID") { // Must be plural form for current entry
-        drupal_set_message(t("Translation file %filename broken: unexpected 'msgid_plural' in line %line.", array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t("Translation file %filename broken: unexpected 'msgid_plural' in line %line.", array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
       $line = trim(substr($line, 12));
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === false) {
-        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
       $current["msgid"] = $current["msgid"] ."\0". $quoted;
@@ -327,13 +328,13 @@ function _locale_import_read_po($file) {
         $current = array();
       }
       elseif ($context == "MSGID") { // Already in this context? Parse error
-        drupal_set_message(t("Translation file %filename broken: unexpected 'msgid' in line %line.", array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t("Translation file %filename broken: unexpected 'msgid' in line %line.", array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
       $line = trim(substr($line, 5));
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === false) {
-        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
       $current["msgid"] = $quoted;
@@ -341,11 +342,11 @@ function _locale_import_read_po($file) {
     }
     elseif (!strncmp("msgstr[", $line, 7)) {
       if (($context != "MSGID") && ($context != "MSGID_PLURAL") && ($context != "MSGSTR_ARR")) { // Must come after msgid, msgid_plural, or msgstr[]
-        drupal_set_message(t("Translation file %filename broken: unexpected 'msgstr[]' in line %line.", array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t("Translation file %filename broken: unexpected 'msgstr[]' in line %line.", array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
       if (strpos($line, "]") === false) {
-        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
       $frombracket = strstr($line, "[");
@@ -353,7 +354,7 @@ function _locale_import_read_po($file) {
       $line = trim(strstr($line, " "));
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === false) {
-        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
       $current["msgstr"][$plural] = $quoted;
@@ -361,13 +362,13 @@ function _locale_import_read_po($file) {
     }
     elseif (!strncmp("msgstr", $line, 6)) {
       if ($context != "MSGID") {   // Should come just after a msgid block
-        drupal_set_message(t("Translation file %filename broken: unexpected 'msgstr' in line %line.", array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t("Translation file %filename broken: unexpected 'msgstr' in line %line.", array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
       $line = trim(substr($line, 6));
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === false) {
-        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
       $current["msgstr"] = $quoted;
@@ -376,7 +377,7 @@ function _locale_import_read_po($file) {
     elseif ($line != "") {
       $quoted = _locale_import_parse_quoted($line);
       if ($quoted === false) {
-        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t('Translation file %filename broken: syntax error in line %line.', array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
       if (($context == "MSGID") || ($context == "MSGID_PLURAL")) {
@@ -389,7 +390,7 @@ function _locale_import_read_po($file) {
         $current["msgstr"][$plural] .= $quoted;
       }
       else {
-        drupal_set_message(t('Translation file %filename broken: unexpected string in line %line.', array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+        drupal_set_message(t('Translation file %filename broken: unexpected string in line %line.', array('%filename' => $message, '%line' => $lineno)), 'error');
         return FALSE;
       }
     }
@@ -400,7 +401,7 @@ function _locale_import_read_po($file) {
     $strings[$current["msgid"]] = $current;
   }
   elseif ($context != "COMMENT") {
-    drupal_set_message(t('Translation file %filename broken: unexpected end file at line %line.', array('%filename' => "<em>$file->filename</em>", '%line' => $lineno)), 'error');
+    drupal_set_message(t('Translation file %filename broken: unexpected end of file at line %line.', array('%filename' => $message, '%line' => $lineno)), 'error');
     return FALSE;
   }
 
@@ -465,7 +466,7 @@ function _locale_import_parse_plural_forms($pluralforms, $filename) {
     return array($nplurals, $plural);
   }
   else {
-    drupal_set_message(t("Translation file %filename broken: plural formula couldn't get parsed.", array('%filename' => "<em>$filename</em>")), 'error');
+    drupal_set_message(t("Translation file %filename broken: plural formula couldn't get parsed.", array('%filename' => theme('placeholder', $filename))), 'error');
     return FALSE;
   }
 }
@@ -768,7 +769,7 @@ function _locale_export_po($language) {
       $header .= "\"Plural-Forms: nplurals=". $meta->plurals ."; plural=". strtr($meta->formula, '$', '') .";\\n\"\n";
     }
     $header .= "\n";
-    watchdog('locale', t('Exported %locale translation file: %filename.', array('%locale' => "<em>$meta->name</em>", '%filename' => "<em>$filename</em>")));
+    watchdog('locale', t('Exported %locale translation file: %filename.', array('%locale' => theme('placeholder', $meta->name), '%filename' => theme('placeholder', $filename))));
   }
 
   // Generating Portable Object Template
@@ -789,7 +790,7 @@ function _locale_export_po($language) {
     $header .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
     $header .= "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n";
     $header .= "\n";
-    watchdog('locale', t('Exported translation file: %filename.', array('%filename' => "<em>$filename</em>")));
+    watchdog('locale', t('Exported translation file: %filename.', array('%filename' => theme('placeholder', $filename))));
   }
 
   // Start download process
@@ -1080,6 +1081,7 @@ function _locale_string_seek_form() {
   // Get *all* languages set up
   $languages = locale_supported_languages(FALSE, TRUE);
   asort($languages['name']); unset($languages['name']['en']);
+  $languages['name'] = array_map('check_plain', $languages['name']);
 
   // Present edit form preserving previous user settings
   $query = _locale_string_seek_query();
diff --git a/includes/pager.inc b/includes/pager.inc
index 43639c7a683f..ddd6c399df23 100644
--- a/includes/pager.inc
+++ b/includes/pager.inc
@@ -384,19 +384,19 @@ function pager_link($from_new, $element, $attributes = array()) {
   $q = $_GET['q'];
   $from = array_key_exists('from', $_GET) ? $_GET['from'] : '';
 
-  foreach($attributes as $key => $value) {
+  foreach ($attributes as $key => $value) {
     $query[] = $key .'='. $value;
   }
 
   $from_new = pager_load_array($from_new[$element], $element, explode(',', $from));
   if (count($attributes)) {
-    $url = url($q, 'from='. implode($from_new, ',') .'&amp;'. implode('&amp;', $query));
+    $url = url($q, 'from='. implode($from_new, ',') .'&'. implode('&', $query));
   }
   else {
     $url = url($q, 'from='. implode($from_new, ','));
   }
 
-  return $url;
+  return check_url($url);
 }
 
 function pager_load_array($value, $element, $old_array) {
diff --git a/includes/tablesort.inc b/includes/tablesort.inc
index ad02683524e4..e4f044d89c76 100644
--- a/includes/tablesort.inc
+++ b/includes/tablesort.inc
@@ -87,7 +87,7 @@ function tablesort_header($cell, $header, $ts) {
       $ts['sort'] = 'asc';
       $image = '';
     }
-    $cell['data'] = l($cell['data'] . $image, $_GET['q'], array('title' => $title), 'sort='. $ts['sort'] .'&amp;order='. urlencode($cell['data']). $ts['query_string']);
+    $cell['data'] = l($cell['data'] . $image, $_GET['q'], array('title' => $title), 'sort='. $ts['sort'] .'&order='. urlencode($cell['data']). $ts['query_string'], NULL, FALSE, TRUE);
 
     unset($cell['field'], $cell['sort']);
   }
@@ -139,7 +139,7 @@ function tablesort_get_querystring() {
   $query_string = '';
   foreach ($cgi as $key => $val) {
     if ($key != 'order' && $key != 'sort' && $key != 'q') {
-      $query_string .= '&amp;'. $key .'='. $val;
+      $query_string .= '&'. $key .'='. $val;
     }
   }
   return $query_string;
diff --git a/includes/theme.inc b/includes/theme.inc
index 14b2181e3040..789841152928 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -225,8 +225,8 @@ function path_to_theme() {
  */
 function theme_get_settings($key = NULL) {
   $defaults = array(
-    'primary_links'                 =>  l('edit primary links', 'admin/themes/settings'),
-    'secondary_links'               =>  l('edit secondary links', 'admin/themes/settings'),
+    'primary_links'                 =>  l(t('edit primary links'), 'admin/themes/settings'),
+    'secondary_links'               =>  l(t('edit secondary links'), 'admin/themes/settings'),
     'mission'                       =>  '',
     'default_logo'                  =>  1,
     'logo_path'                     =>  '',
@@ -348,6 +348,20 @@ function theme_get_styles() {
  *
  * The theme system is described and defined in theme.inc.
  */
+ 
+/**
+ * Format a dynamic text string for emphasised display in a placeholder.
+ *
+ * E.g. t('Added term %term', array('%term' => theme('placeholder', $term)))
+ *
+ * @param $text
+ *   The text to format (plain-text).
+ * @return
+ *   The formatted text (html).
+ */
+function theme_placeholder($text) {
+  return '<em>'. check_plain($text) .'</em>';
+}
 
 /**
  * Return an entire Drupal page displaying the supplied content.
@@ -361,7 +375,7 @@ function theme_page($content) {
   $output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
   $output .= '<html xmlns="http://www.w3.org/1999/xhtml">';
   $output .= '<head>';
-  $output .= ' <title>'. (drupal_get_title() ? drupal_get_title() : variable_get('site_name', 'drupal')) .'</title>';
+  $output .= ' <title>'. (drupal_get_title() ? strip_tags(drupal_get_title()) : variable_get('site_name', 'drupal')) .'</title>';
   $output .= drupal_get_html_head();
   $output .= theme_get_styles();
 
@@ -500,7 +514,7 @@ function theme_node($node, $teaser = FALSE, $page = FALSE) {
   }
 
   if ($page == 0) {
-    $output = '<h2 class="title">'. $node->title .'</h2> by '. format_name($node);
+    $output = '<h2 class="title">'. check_plain($node->title) .'</h2> by '. format_name($node);
   }
   else {
     $output = 'by '. format_name($node);
diff --git a/modules/aggregator.module b/modules/aggregator.module
index edd23ad1e8cc..2374afd9c60e 100644
--- a/modules/aggregator.module
+++ b/modules/aggregator.module
@@ -198,11 +198,11 @@ function aggregator_block($op, $delta = 0, $edit = array()) {
     if ($op == 'list') {
       $result = db_query('SELECT cid, title FROM {aggregator_category} ORDER BY title');
       while ($category = db_fetch_object($result)) {
-        $block['category:'. $category->cid]['info'] = t('%title category latest items', array('%title' => $category->title));
+        $block['category:'. $category->cid]['info'] = t('%title category latest items', array('%title' => theme('placeholder', $category->title)));
       }
       $result = db_query('SELECT fid, title FROM {aggregator_feed} ORDER BY fid');
       while ($feed = db_fetch_object($result)) {
-        $block['feed:'. $feed->fid]['info'] = t('%title feed latest items', array('%title' => $feed->title));
+        $block['feed:'. $feed->fid]['info'] = t('%title feed latest items', array('%title' => theme('placeholder', $feed->title)));
       }
     }
     else if ($op == 'configure') {
@@ -231,7 +231,7 @@ function aggregator_block($op, $delta = 0, $edit = array()) {
       switch ($type) {
         case 'feed':
           if ($feed = db_fetch_object(db_query('SELECT fid, title, block FROM {aggregator_feed} WHERE fid = %d', $id))) {
-            $block['subject'] = $feed->title;
+            $block['subject'] = check_plain($feed->title);
             $result = db_query_range('SELECT * FROM {aggregator_item} WHERE fid = %d ORDER BY timestamp DESC, iid DESC', $feed->fid, 0, $feed->block);
             $block['content'] = '<div class="more-link">'. l(t('more'), 'aggregator/sources/'. $feed->fid, array('title' => t('View this feed\'s recent news.'))) .'</div>';
           }
@@ -239,7 +239,7 @@ function aggregator_block($op, $delta = 0, $edit = array()) {
 
         case 'category':
           if ($category = db_fetch_object(db_query('SELECT cid, title, block FROM {aggregator_category} WHERE cid = %d', $id))) {
-            $block['subject'] = $category->title;
+            $block['subject'] = check_plain($category->title);
             $result = db_query_range('SELECT i.* FROM {aggregator_category_item} ci LEFT JOIN {aggregator_item} i ON ci.iid = i.iid WHERE ci.cid = %d ORDER BY i.timestamp DESC, i.iid DESC', $category->cid, 0, $category->block);
             $block['content'] = '<div class="more-link">'. l(t('more'), 'aggregator/categories/'. $category->cid, array('title' => t('View this category\'s recent news.'))) .'</div>';
           }
@@ -265,7 +265,7 @@ function aggregator_remove($feed) {
   }
   db_query('DELETE FROM {aggregator_item} WHERE fid = %d', $feed['fid']);
   db_query("UPDATE {aggregator_feed} SET checked = 0, etag = '', modified = 0 WHERE fid = %d", $feed['fid']);
-  drupal_set_message(t('Removed news items from %site.', array('%site' => '<em>'. $feed['title'] .'</em>')));
+  drupal_set_message(t('Removed news items from %site.', array('%site' => theme('placeholder', $feed['title']))));
 }
 
 /**
@@ -345,11 +345,11 @@ function aggregator_refresh($feed) {
   switch ($result->code) {
     case 304:
       db_query('UPDATE {aggregator_feed} SET checked = %d WHERE fid = %d', time(), $feed['fid']);
-      drupal_set_message(t('No new syndicated content from %site.', array('%site' => '<em>'. $feed['title'] .'</em>')));
+      drupal_set_message(t('No new syndicated content from %site.', array('%site' => theme('placeholder', $feed['title']))));
       break;
     case 301:
       $feed['url'] = $result->redirect_url;
-      watchdog('aggregator', t('Updated URL for feed %title to %url.', array('%title' => '<em>'. $feed['title'] .'</em>', '%url' => '<em>'. $feed['url'] .'</em>')));
+      watchdog('aggregator', t('Updated URL for feed %title to %url.', array('%title' => theme('placeholder', $feed['title']), '%url' => theme('placeholder', $feed['url']))));
       break;
 
     case 200:
@@ -397,13 +397,13 @@ function aggregator_refresh($feed) {
 
         cache_clear_all();
 
-        $message = t('Syndicated content from %site.', array('%site' => '<em>'. $feed[title] .'</em>'));
+        $message = t('Syndicated content from %site.', array('%site' => theme('placeholder', $feed[title])));
         watchdog('aggregator', $message);
         drupal_set_message($message);
       }
       break;
     default:
-      $message = t('Failed to parse RSS feed %site: %error.', array('%site' => '<em>'. $feed['title'] .'</em>', '%error' => "<em>$result->code $result->error</em>"));
+      $message = t('Failed to parse RSS feed %site: %error.', array('%site' => theme('placeholder', $feed['title']), '%error' => theme('placeholder', $result->code .' '. $result->error)));
       watchdog('aggregator', $message, WATCHDOG_WARNING);
       drupal_set_message($message);
   }
@@ -461,7 +461,7 @@ function aggregator_parse_feed(&$data, $feed) {
   xml_set_character_data_handler($xml_parser, 'aggregator_element_data');
 
   if (!xml_parse($xml_parser, $data, 1)) {
-    $message = t('Failed to parse RSS feed %site: %error at line %line.', array('%site' => '<em>'. $feed['title'] .'</em>', '%error' => xml_error_string(xml_get_error_code($xml_parser)), '%line' => xml_get_current_line_number($xml_parser)));
+    $message = t('Failed to parse RSS feed %site: %error at line %line.', array('%site' => theme('placeholder', $feed['title']), '%error' => xml_error_string(xml_get_error_code($xml_parser)), '%line' => xml_get_current_line_number($xml_parser)));
     watchdog('aggregator', $message, WATCHDOG_WARNING);
     drupal_set_message($message, 'error');
     return 0;
@@ -554,7 +554,7 @@ function aggregator_parse_feed(&$data, $feed) {
     }
 
     if (!valid_input_data($item['DESCRIPTION'])) {
-      drupal_set_message(t('Failed to parse entry from %site feed: suspicious input data.', array('%site' => '<em>'. $feed['title'] .'</em>')), 'error');
+      drupal_set_message(t('Failed to parse entry from %site feed: suspicious input data.', array('%site' => theme('placeholder', $feed['title']))), 'error');
     }
     else {
       aggregator_save_item(array('iid' => $entry->iid, 'fid' => $feed['fid'], 'timestamp' => $timestamp, 'title' => $title, 'link' => $link, 'author' => $item['AUTHOR'], 'description' => $item['DESCRIPTION']));
@@ -643,7 +643,7 @@ function aggregator_form_feed($edit = array()) {
   $categories = db_query('SELECT c.cid, c.title, f.fid FROM {aggregator_category} c LEFT JOIN {aggregator_category_feed} f ON c.cid = f.cid AND f.fid = %d ORDER BY title', $edit['fid']);
   while ($category = db_fetch_object($categories)) {
     $options[$category->cid] = $category->title;
-    if ($category->fid) $values[] = $category->cid;
+    if ($category->fid) $values[] = check_plain($category->cid);
   }
   if ($options) {
     $form .= form_checkboxes(t('Categorize news items'), 'category', $values, $options, t('New items in this feed will be automatically filed in the the checked categories as they are received.'));
@@ -920,7 +920,7 @@ function _aggregator_page_list($sql, $op, $header = '') {
         $selected = array();
         while ($category = db_fetch_object($categories_result)) {
           if (!$done) {
-            $categories[$category->cid] = check_form($category->title);
+            $categories[$category->cid] = check_plain($category->title);
           }
           if ($category->iid) {
             $selected[] = $category->cid;
@@ -932,7 +932,7 @@ function _aggregator_page_list($sql, $op, $header = '') {
       else {
         $form = '';
         while ($category = db_fetch_object($categories_result)) {
-          $form .= form_checkbox(check_form($category->title), 'categories]['. $item->iid .'][', $category->cid, !is_null($category->iid));
+          $form .= form_checkbox(check_plain($category->title), 'categories]['. $item->iid .'][', $category->cid, !is_null($category->iid));
         }
       }
       $rows[] = array(theme('aggregator_page_item', $item), array('data' => $form, 'class' => 'categorize-item'));
@@ -960,7 +960,7 @@ function aggregator_page_sources() {
   $result = db_query('SELECT f.fid, f.title, f.description, f.image, MAX(i.timestamp) AS last FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid');
   $output = "<div id=\"aggregator\">\n";
   while ($feed = db_fetch_object($result)) {
-    $output .= "<h2>$feed->title</h2>\n";
+    $output .= '<h2>'. check_plain($feed->title) ."</h2>\n";
 
     // Most recent items:
     $list = array();
@@ -987,13 +987,13 @@ function aggregator_page_opml() {
   $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
   $output .= "<opml version=\"1.1\">\n";
   $output .= "<head>\n";
-  $output .= '<title>'. drupal_specialchars(variable_get('site_name', 'Drupal')) ."</title>\n";
+  $output .= '<title>'. check_plain(variable_get('site_name', 'Drupal')) ."</title>\n";
   $output .= '<dateModified>'. gmdate('r') ."</dateModified>\n";
   $output .= "</head>\n";
   $output .= "<body>\n";
 
   while ($feed = db_fetch_object($result)) {
-    $output .= '<outline text="'. drupal_specialchars($feed->title) .'" xmlUrl="'. drupal_specialchars($feed->url) ."\" />\n";
+    $output .= '<outline text="'. check_plain($feed->title) .'" xmlUrl="'. check_url($feed->url) ."\" />\n";
   }
 
   $output .= "</body>\n";
@@ -1011,7 +1011,7 @@ function aggregator_page_categories() {
   $output = "<div id=\"aggregator\">\n";
 
   while ($category = db_fetch_object($result)) {
-    $output .= "<h2>$category->title</h2>\n";
+    $output .= '<h2>'. check_plain($category->title) ."</h2>\n";
     if (variable_get('aggregator_summary_items', 3)) {
       $list = array();
       $items = db_query_range('SELECT i.title, i.timestamp, i.link, f.title as feed_title, f.link as feed_link FROM {aggregator_category_item} ci LEFT JOIN {aggregator_item} i ON i.iid = ci.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE ci.cid = %d ORDER BY i.timestamp DESC', $category->cid, 0, variable_get('aggregator_summary_items', 3));
@@ -1042,7 +1042,7 @@ function theme_aggregator_feed($feed) {
   $output .= $feed->description;
   $output .= '<h3>'. t('URL') ."</h3>\n";
   $output .= theme('xml_icon', $feed->url);
-  $output .= "<a href=\"$feed->link\">$feed->link</a>\n";
+  $output .= '<a href="'. check_url($feed->link) .'">'. check_plain($feed->link) ."</a>\n";
   $output .= '<h3>'. t('Last update') ."</h3>\n";
   $updated = t('%time ago', array('%time' => format_interval(time() - $feed->checked)));
 
@@ -1066,12 +1066,12 @@ function theme_aggregator_block_item($item, $feed = 0) {
 
   if ($user->uid && module_exist('blog') && user_access('edit own blog')) {
     if ($image = theme('image', 'misc/blog.png', t('blog it'), t('blog it'))) {
-      $output .= '<div class="icon">'. l($image, 'node/add/blog', array('title' => t('Comment on this news item in your personal blog.'), 'class' => 'blog-it'), "iid=$item->iid") .'</div>';
+      $output .= '<div class="icon">'. l($image, 'node/add/blog', array('title' => t('Comment on this news item in your personal blog.'), 'class' => 'blog-it'), "iid=$item->iid", NULL, FALSE, TRUE) .'</div>';
     }
   }
 
   // Display the external link to the item.
-  $output .= "<a href=\"$item->link\">$item->title</a>\n";
+  $output .= '<a href="'. check_url($item->link) .'">'. check_plain($item->title) ."</a>\n";
 
   return $output;
 }
@@ -1086,7 +1086,7 @@ function theme_aggregator_block_item($item, $feed = 0) {
  * @ingroup themeable
  */
 function theme_aggregator_summary_item($item) {
-  $output = '<a href="'. check_url($item->link) .'">'. $item->title .'</a> <span class="age">'. t('%age old', array('%age' => format_interval(time() - $item->timestamp))) .'</span>';
+  $output = '<a href="'. check_url($item->link) .'">'. check_plain($item->title) .'</a> <span class="age">'. t('%age old', array('%age' => format_interval(time() - $item->timestamp))) .'</span>';
   if ($item->feed_link) {
     $output .= ', <span class="source"><a href="'. $item->feed_link .'">'. $item->feed_title .'</a></span>';
   }
@@ -1110,9 +1110,9 @@ function theme_aggregator_page_item($item) {
   $output .= "<div class=\"news-item\">\n";
   $output .= ' <div class="date">'. date('H:i', $item->timestamp) ."</div>\n";
   $output .= " <div class=\"body\">\n";
-  $output .= "  <div class=\"title\"><a href=\"$item->link\">$item->title</a></div>\n";
+  $output .= '  <div class="title"><a href="'. check_url($item->link) .'">'. check_plain($item->title) ."</a></div>\n";
   if ($item->description) {
-    $output .= "  <div class=\"description\">$item->description</div>\n";
+    $output .= '  <div class="description">'. check_plain($item->description) ."</div>\n";
   }
   if ($item->ftitle && $item->fid) {
     $output .= '  <div class="source">'. t('Source') .': '. l($item->ftitle, "aggregator/sources/$item->fid") ."</div>\n";
diff --git a/modules/aggregator/aggregator.module b/modules/aggregator/aggregator.module
index edd23ad1e8cc..2374afd9c60e 100644
--- a/modules/aggregator/aggregator.module
+++ b/modules/aggregator/aggregator.module
@@ -198,11 +198,11 @@ function aggregator_block($op, $delta = 0, $edit = array()) {
     if ($op == 'list') {
       $result = db_query('SELECT cid, title FROM {aggregator_category} ORDER BY title');
       while ($category = db_fetch_object($result)) {
-        $block['category:'. $category->cid]['info'] = t('%title category latest items', array('%title' => $category->title));
+        $block['category:'. $category->cid]['info'] = t('%title category latest items', array('%title' => theme('placeholder', $category->title)));
       }
       $result = db_query('SELECT fid, title FROM {aggregator_feed} ORDER BY fid');
       while ($feed = db_fetch_object($result)) {
-        $block['feed:'. $feed->fid]['info'] = t('%title feed latest items', array('%title' => $feed->title));
+        $block['feed:'. $feed->fid]['info'] = t('%title feed latest items', array('%title' => theme('placeholder', $feed->title)));
       }
     }
     else if ($op == 'configure') {
@@ -231,7 +231,7 @@ function aggregator_block($op, $delta = 0, $edit = array()) {
       switch ($type) {
         case 'feed':
           if ($feed = db_fetch_object(db_query('SELECT fid, title, block FROM {aggregator_feed} WHERE fid = %d', $id))) {
-            $block['subject'] = $feed->title;
+            $block['subject'] = check_plain($feed->title);
             $result = db_query_range('SELECT * FROM {aggregator_item} WHERE fid = %d ORDER BY timestamp DESC, iid DESC', $feed->fid, 0, $feed->block);
             $block['content'] = '<div class="more-link">'. l(t('more'), 'aggregator/sources/'. $feed->fid, array('title' => t('View this feed\'s recent news.'))) .'</div>';
           }
@@ -239,7 +239,7 @@ function aggregator_block($op, $delta = 0, $edit = array()) {
 
         case 'category':
           if ($category = db_fetch_object(db_query('SELECT cid, title, block FROM {aggregator_category} WHERE cid = %d', $id))) {
-            $block['subject'] = $category->title;
+            $block['subject'] = check_plain($category->title);
             $result = db_query_range('SELECT i.* FROM {aggregator_category_item} ci LEFT JOIN {aggregator_item} i ON ci.iid = i.iid WHERE ci.cid = %d ORDER BY i.timestamp DESC, i.iid DESC', $category->cid, 0, $category->block);
             $block['content'] = '<div class="more-link">'. l(t('more'), 'aggregator/categories/'. $category->cid, array('title' => t('View this category\'s recent news.'))) .'</div>';
           }
@@ -265,7 +265,7 @@ function aggregator_remove($feed) {
   }
   db_query('DELETE FROM {aggregator_item} WHERE fid = %d', $feed['fid']);
   db_query("UPDATE {aggregator_feed} SET checked = 0, etag = '', modified = 0 WHERE fid = %d", $feed['fid']);
-  drupal_set_message(t('Removed news items from %site.', array('%site' => '<em>'. $feed['title'] .'</em>')));
+  drupal_set_message(t('Removed news items from %site.', array('%site' => theme('placeholder', $feed['title']))));
 }
 
 /**
@@ -345,11 +345,11 @@ function aggregator_refresh($feed) {
   switch ($result->code) {
     case 304:
       db_query('UPDATE {aggregator_feed} SET checked = %d WHERE fid = %d', time(), $feed['fid']);
-      drupal_set_message(t('No new syndicated content from %site.', array('%site' => '<em>'. $feed['title'] .'</em>')));
+      drupal_set_message(t('No new syndicated content from %site.', array('%site' => theme('placeholder', $feed['title']))));
       break;
     case 301:
       $feed['url'] = $result->redirect_url;
-      watchdog('aggregator', t('Updated URL for feed %title to %url.', array('%title' => '<em>'. $feed['title'] .'</em>', '%url' => '<em>'. $feed['url'] .'</em>')));
+      watchdog('aggregator', t('Updated URL for feed %title to %url.', array('%title' => theme('placeholder', $feed['title']), '%url' => theme('placeholder', $feed['url']))));
       break;
 
     case 200:
@@ -397,13 +397,13 @@ function aggregator_refresh($feed) {
 
         cache_clear_all();
 
-        $message = t('Syndicated content from %site.', array('%site' => '<em>'. $feed[title] .'</em>'));
+        $message = t('Syndicated content from %site.', array('%site' => theme('placeholder', $feed[title])));
         watchdog('aggregator', $message);
         drupal_set_message($message);
       }
       break;
     default:
-      $message = t('Failed to parse RSS feed %site: %error.', array('%site' => '<em>'. $feed['title'] .'</em>', '%error' => "<em>$result->code $result->error</em>"));
+      $message = t('Failed to parse RSS feed %site: %error.', array('%site' => theme('placeholder', $feed['title']), '%error' => theme('placeholder', $result->code .' '. $result->error)));
       watchdog('aggregator', $message, WATCHDOG_WARNING);
       drupal_set_message($message);
   }
@@ -461,7 +461,7 @@ function aggregator_parse_feed(&$data, $feed) {
   xml_set_character_data_handler($xml_parser, 'aggregator_element_data');
 
   if (!xml_parse($xml_parser, $data, 1)) {
-    $message = t('Failed to parse RSS feed %site: %error at line %line.', array('%site' => '<em>'. $feed['title'] .'</em>', '%error' => xml_error_string(xml_get_error_code($xml_parser)), '%line' => xml_get_current_line_number($xml_parser)));
+    $message = t('Failed to parse RSS feed %site: %error at line %line.', array('%site' => theme('placeholder', $feed['title']), '%error' => xml_error_string(xml_get_error_code($xml_parser)), '%line' => xml_get_current_line_number($xml_parser)));
     watchdog('aggregator', $message, WATCHDOG_WARNING);
     drupal_set_message($message, 'error');
     return 0;
@@ -554,7 +554,7 @@ function aggregator_parse_feed(&$data, $feed) {
     }
 
     if (!valid_input_data($item['DESCRIPTION'])) {
-      drupal_set_message(t('Failed to parse entry from %site feed: suspicious input data.', array('%site' => '<em>'. $feed['title'] .'</em>')), 'error');
+      drupal_set_message(t('Failed to parse entry from %site feed: suspicious input data.', array('%site' => theme('placeholder', $feed['title']))), 'error');
     }
     else {
       aggregator_save_item(array('iid' => $entry->iid, 'fid' => $feed['fid'], 'timestamp' => $timestamp, 'title' => $title, 'link' => $link, 'author' => $item['AUTHOR'], 'description' => $item['DESCRIPTION']));
@@ -643,7 +643,7 @@ function aggregator_form_feed($edit = array()) {
   $categories = db_query('SELECT c.cid, c.title, f.fid FROM {aggregator_category} c LEFT JOIN {aggregator_category_feed} f ON c.cid = f.cid AND f.fid = %d ORDER BY title', $edit['fid']);
   while ($category = db_fetch_object($categories)) {
     $options[$category->cid] = $category->title;
-    if ($category->fid) $values[] = $category->cid;
+    if ($category->fid) $values[] = check_plain($category->cid);
   }
   if ($options) {
     $form .= form_checkboxes(t('Categorize news items'), 'category', $values, $options, t('New items in this feed will be automatically filed in the the checked categories as they are received.'));
@@ -920,7 +920,7 @@ function _aggregator_page_list($sql, $op, $header = '') {
         $selected = array();
         while ($category = db_fetch_object($categories_result)) {
           if (!$done) {
-            $categories[$category->cid] = check_form($category->title);
+            $categories[$category->cid] = check_plain($category->title);
           }
           if ($category->iid) {
             $selected[] = $category->cid;
@@ -932,7 +932,7 @@ function _aggregator_page_list($sql, $op, $header = '') {
       else {
         $form = '';
         while ($category = db_fetch_object($categories_result)) {
-          $form .= form_checkbox(check_form($category->title), 'categories]['. $item->iid .'][', $category->cid, !is_null($category->iid));
+          $form .= form_checkbox(check_plain($category->title), 'categories]['. $item->iid .'][', $category->cid, !is_null($category->iid));
         }
       }
       $rows[] = array(theme('aggregator_page_item', $item), array('data' => $form, 'class' => 'categorize-item'));
@@ -960,7 +960,7 @@ function aggregator_page_sources() {
   $result = db_query('SELECT f.fid, f.title, f.description, f.image, MAX(i.timestamp) AS last FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid');
   $output = "<div id=\"aggregator\">\n";
   while ($feed = db_fetch_object($result)) {
-    $output .= "<h2>$feed->title</h2>\n";
+    $output .= '<h2>'. check_plain($feed->title) ."</h2>\n";
 
     // Most recent items:
     $list = array();
@@ -987,13 +987,13 @@ function aggregator_page_opml() {
   $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
   $output .= "<opml version=\"1.1\">\n";
   $output .= "<head>\n";
-  $output .= '<title>'. drupal_specialchars(variable_get('site_name', 'Drupal')) ."</title>\n";
+  $output .= '<title>'. check_plain(variable_get('site_name', 'Drupal')) ."</title>\n";
   $output .= '<dateModified>'. gmdate('r') ."</dateModified>\n";
   $output .= "</head>\n";
   $output .= "<body>\n";
 
   while ($feed = db_fetch_object($result)) {
-    $output .= '<outline text="'. drupal_specialchars($feed->title) .'" xmlUrl="'. drupal_specialchars($feed->url) ."\" />\n";
+    $output .= '<outline text="'. check_plain($feed->title) .'" xmlUrl="'. check_url($feed->url) ."\" />\n";
   }
 
   $output .= "</body>\n";
@@ -1011,7 +1011,7 @@ function aggregator_page_categories() {
   $output = "<div id=\"aggregator\">\n";
 
   while ($category = db_fetch_object($result)) {
-    $output .= "<h2>$category->title</h2>\n";
+    $output .= '<h2>'. check_plain($category->title) ."</h2>\n";
     if (variable_get('aggregator_summary_items', 3)) {
       $list = array();
       $items = db_query_range('SELECT i.title, i.timestamp, i.link, f.title as feed_title, f.link as feed_link FROM {aggregator_category_item} ci LEFT JOIN {aggregator_item} i ON i.iid = ci.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE ci.cid = %d ORDER BY i.timestamp DESC', $category->cid, 0, variable_get('aggregator_summary_items', 3));
@@ -1042,7 +1042,7 @@ function theme_aggregator_feed($feed) {
   $output .= $feed->description;
   $output .= '<h3>'. t('URL') ."</h3>\n";
   $output .= theme('xml_icon', $feed->url);
-  $output .= "<a href=\"$feed->link\">$feed->link</a>\n";
+  $output .= '<a href="'. check_url($feed->link) .'">'. check_plain($feed->link) ."</a>\n";
   $output .= '<h3>'. t('Last update') ."</h3>\n";
   $updated = t('%time ago', array('%time' => format_interval(time() - $feed->checked)));
 
@@ -1066,12 +1066,12 @@ function theme_aggregator_block_item($item, $feed = 0) {
 
   if ($user->uid && module_exist('blog') && user_access('edit own blog')) {
     if ($image = theme('image', 'misc/blog.png', t('blog it'), t('blog it'))) {
-      $output .= '<div class="icon">'. l($image, 'node/add/blog', array('title' => t('Comment on this news item in your personal blog.'), 'class' => 'blog-it'), "iid=$item->iid") .'</div>';
+      $output .= '<div class="icon">'. l($image, 'node/add/blog', array('title' => t('Comment on this news item in your personal blog.'), 'class' => 'blog-it'), "iid=$item->iid", NULL, FALSE, TRUE) .'</div>';
     }
   }
 
   // Display the external link to the item.
-  $output .= "<a href=\"$item->link\">$item->title</a>\n";
+  $output .= '<a href="'. check_url($item->link) .'">'. check_plain($item->title) ."</a>\n";
 
   return $output;
 }
@@ -1086,7 +1086,7 @@ function theme_aggregator_block_item($item, $feed = 0) {
  * @ingroup themeable
  */
 function theme_aggregator_summary_item($item) {
-  $output = '<a href="'. check_url($item->link) .'">'. $item->title .'</a> <span class="age">'. t('%age old', array('%age' => format_interval(time() - $item->timestamp))) .'</span>';
+  $output = '<a href="'. check_url($item->link) .'">'. check_plain($item->title) .'</a> <span class="age">'. t('%age old', array('%age' => format_interval(time() - $item->timestamp))) .'</span>';
   if ($item->feed_link) {
     $output .= ', <span class="source"><a href="'. $item->feed_link .'">'. $item->feed_title .'</a></span>';
   }
@@ -1110,9 +1110,9 @@ function theme_aggregator_page_item($item) {
   $output .= "<div class=\"news-item\">\n";
   $output .= ' <div class="date">'. date('H:i', $item->timestamp) ."</div>\n";
   $output .= " <div class=\"body\">\n";
-  $output .= "  <div class=\"title\"><a href=\"$item->link\">$item->title</a></div>\n";
+  $output .= '  <div class="title"><a href="'. check_url($item->link) .'">'. check_plain($item->title) ."</a></div>\n";
   if ($item->description) {
-    $output .= "  <div class=\"description\">$item->description</div>\n";
+    $output .= '  <div class="description">'. check_plain($item->description) ."</div>\n";
   }
   if ($item->ftitle && $item->fid) {
     $output .= '  <div class="source">'. t('Source') .': '. l($item->ftitle, "aggregator/sources/$item->fid") ."</div>\n";
diff --git a/modules/archive.module b/modules/archive.module
index 446071c33872..de6b8794847e 100644
--- a/modules/archive.module
+++ b/modules/archive.module
@@ -91,7 +91,7 @@ function archive_calendar($original = 0) {
   $output .= "\n<!-- calendar -->\n";
   $output .= '<div class="calendar">';
   $output .= '<table summary="'. t('A calendar to browse the archives') .".\">\n";
-  $output .= ' <caption>'. l('&laquo;', 'archive/'. date('Y/m/d', $prev), array('title' => t('Previous month'))) .' '. format_date($requested, 'custom', 'F') . date(' Y', $requested) .' '. ($nextmonth <= time() ? l('&raquo;', 'archive/'. date('Y/m/d', $next), array('title' => t('Next month'))) : '&nbsp;') ."</caption>\n";
+  $output .= ' <caption>'. l('«', 'archive/'. date('Y/m/d', $prev), array('title' => t('Previous month'))) .' '. format_date($requested, 'custom', 'F') . date(' Y', $requested) .' '. ($nextmonth <= time() ? l('»', 'archive/'. date('Y/m/d', $next), array('title' => t('Next month'))) : ' ') ."</caption>\n";
 
   // First day of week (0 => Sunday, 1 => Monday, ...)
   $weekstart = variable_get('date_first_day', 0);
diff --git a/modules/archive/archive.module b/modules/archive/archive.module
index 446071c33872..de6b8794847e 100644
--- a/modules/archive/archive.module
+++ b/modules/archive/archive.module
@@ -91,7 +91,7 @@ function archive_calendar($original = 0) {
   $output .= "\n<!-- calendar -->\n";
   $output .= '<div class="calendar">';
   $output .= '<table summary="'. t('A calendar to browse the archives') .".\">\n";
-  $output .= ' <caption>'. l('&laquo;', 'archive/'. date('Y/m/d', $prev), array('title' => t('Previous month'))) .' '. format_date($requested, 'custom', 'F') . date(' Y', $requested) .' '. ($nextmonth <= time() ? l('&raquo;', 'archive/'. date('Y/m/d', $next), array('title' => t('Next month'))) : '&nbsp;') ."</caption>\n";
+  $output .= ' <caption>'. l('«', 'archive/'. date('Y/m/d', $prev), array('title' => t('Previous month'))) .' '. format_date($requested, 'custom', 'F') . date(' Y', $requested) .' '. ($nextmonth <= time() ? l('»', 'archive/'. date('Y/m/d', $next), array('title' => t('Next month'))) : ' ') ."</caption>\n";
 
   // First day of week (0 => Sunday, 1 => Monday, ...)
   $weekstart = variable_get('date_first_day', 0);
diff --git a/modules/block.module b/modules/block.module
index 78a848f5ebb1..caeee3691a3e 100644
--- a/modules/block.module
+++ b/modules/block.module
@@ -86,7 +86,7 @@ function block_block($op = 'list', $delta = 0, $edit = array()) {
     case 'list':
       $result = db_query('SELECT bid, title, info FROM {boxes} ORDER BY title');
       while ($block = db_fetch_object($result)) {
-        $blocks[$block->bid]['info'] = $block->info ? $block->info : $block->title;
+        $blocks[$block->bid]['info'] = $block->info ? check_plain($block->info) : check_plain($block->title);
       }
       return $blocks;
 
@@ -103,7 +103,7 @@ function block_block($op = 'list', $delta = 0, $edit = array()) {
 
     case 'view':
       $block = db_fetch_object(db_query('SELECT * FROM {boxes} WHERE bid = %d', $delta));
-      $data['subject'] = $block->title;
+      $data['subject'] = check_plain($block->title);
       $data['content'] = check_output($block->body, $block->format);
       return $data;
   }
@@ -335,13 +335,13 @@ function block_box_delete($bid = 0) {
 
   if ($_POST['edit']['confirm']) {
     db_query('DELETE FROM {boxes} WHERE bid = %d', $bid);
-    drupal_set_message(t('The block %name has been deleted.', array('%name' => '<em>'. $info .'</em>')));
+    drupal_set_message(t('The block %name has been deleted.', array('%name' => theme('placeholder', $info))));
     cache_clear_all();
     drupal_goto('admin/block');
   }
   else {
     $output = theme('confirm',
-                    t('Are you sure you want to delete the block %name?', array('%name' => '<em>'. $info .'</em>')),
+                    t('Are you sure you want to delete the block %name?', array('%name' => theme('placeholder', $info))),
                     'admin/block',
                     NULL,
                     t('Delete'));
diff --git a/modules/block/block.module b/modules/block/block.module
index 78a848f5ebb1..caeee3691a3e 100644
--- a/modules/block/block.module
+++ b/modules/block/block.module
@@ -86,7 +86,7 @@ function block_block($op = 'list', $delta = 0, $edit = array()) {
     case 'list':
       $result = db_query('SELECT bid, title, info FROM {boxes} ORDER BY title');
       while ($block = db_fetch_object($result)) {
-        $blocks[$block->bid]['info'] = $block->info ? $block->info : $block->title;
+        $blocks[$block->bid]['info'] = $block->info ? check_plain($block->info) : check_plain($block->title);
       }
       return $blocks;
 
@@ -103,7 +103,7 @@ function block_block($op = 'list', $delta = 0, $edit = array()) {
 
     case 'view':
       $block = db_fetch_object(db_query('SELECT * FROM {boxes} WHERE bid = %d', $delta));
-      $data['subject'] = $block->title;
+      $data['subject'] = check_plain($block->title);
       $data['content'] = check_output($block->body, $block->format);
       return $data;
   }
@@ -335,13 +335,13 @@ function block_box_delete($bid = 0) {
 
   if ($_POST['edit']['confirm']) {
     db_query('DELETE FROM {boxes} WHERE bid = %d', $bid);
-    drupal_set_message(t('The block %name has been deleted.', array('%name' => '<em>'. $info .'</em>')));
+    drupal_set_message(t('The block %name has been deleted.', array('%name' => theme('placeholder', $info))));
     cache_clear_all();
     drupal_goto('admin/block');
   }
   else {
     $output = theme('confirm',
-                    t('Are you sure you want to delete the block %name?', array('%name' => '<em>'. $info .'</em>')),
+                    t('Are you sure you want to delete the block %name?', array('%name' => theme('placeholder', $info))),
                     'admin/block',
                     NULL,
                     t('Delete'));
diff --git a/modules/blogapi.module b/modules/blogapi.module
index a3a5c75de4a6..58807c87be2d 100644
--- a/modules/blogapi.module
+++ b/modules/blogapi.module
@@ -153,7 +153,7 @@ function blogapi_new_post($req_params) {
 
   $nid = node_save($node);
   if ($nid) {
-    watchdog('content', t('%type: added %title using blog API.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => "<em>$node->title</em>")), WATCHDOG_NOTICE, l(t('view'), "node/$nid"));
+    watchdog('content', t('%type: added %title using blog API.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$nid"));
     return new xmlrpcresp(new xmlrpcval($nid, 'string'));
   }
 
@@ -215,7 +215,7 @@ function blogapi_edit_post($req_params) {
   }
   $nid = node_save($node);
   if ($nid) {
-    watchdog('content', t('%type: updated %title using blog API.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => "<em>$node->title</em>")), WATCHDOG_NOTICE, l(t('view'), "node/$nid"));
+    watchdog('content', t('%type: updated %title using blog API.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$nid"));
     return new xmlrpcresp(new xmlrpcval(true, 'boolean'));
   }
 
diff --git a/modules/blogapi/blogapi.module b/modules/blogapi/blogapi.module
index a3a5c75de4a6..58807c87be2d 100644
--- a/modules/blogapi/blogapi.module
+++ b/modules/blogapi/blogapi.module
@@ -153,7 +153,7 @@ function blogapi_new_post($req_params) {
 
   $nid = node_save($node);
   if ($nid) {
-    watchdog('content', t('%type: added %title using blog API.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => "<em>$node->title</em>")), WATCHDOG_NOTICE, l(t('view'), "node/$nid"));
+    watchdog('content', t('%type: added %title using blog API.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$nid"));
     return new xmlrpcresp(new xmlrpcval($nid, 'string'));
   }
 
@@ -215,7 +215,7 @@ function blogapi_edit_post($req_params) {
   }
   $nid = node_save($node);
   if ($nid) {
-    watchdog('content', t('%type: updated %title using blog API.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => "<em>$node->title</em>")), WATCHDOG_NOTICE, l(t('view'), "node/$nid"));
+    watchdog('content', t('%type: updated %title using blog API.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$nid"));
     return new xmlrpcresp(new xmlrpcval(true, 'boolean'));
   }
 
diff --git a/modules/book.module b/modules/book.module
index 76bb98b6008a..576f8fd1a9c1 100644
--- a/modules/book.module
+++ b/modules/book.module
@@ -148,7 +148,7 @@ function book_block($op = 'list', $delta = 0) {
           $expand[] = $node->nid;
         }
 
-        $block['subject'] = $path[0]->title;
+        $block['subject'] = check_plain($path[0]->title);
         $block['content'] = book_tree($expand[0], 5, $expand);
       }
     }
@@ -287,7 +287,7 @@ function book_outline() {
           $output .= form_submit(t('Add to book outline'));
         }
 
-        drupal_set_title($node->title);
+        drupal_set_title(check_plain($node->title));
         print theme('page', form($output));
     }
   }
@@ -477,7 +477,7 @@ function theme_book_navigation($node) {
       $links .= '<div class="prev">';
       $links .= l(t('previous'), 'node/'. $prev->nid, array('title' => t('View the previous page.')));
       $links .= '</div>';
-      $titles .= '<div class="prev">'. $prev->title .'</div>';
+      $titles .= '<div class="prev">'. check_plain($prev->title) .'</div>';
     }
     else {
       $links .= '<div class="prev">&nbsp;</div>'; // Make an empty div to fill the space.
@@ -486,7 +486,7 @@ function theme_book_navigation($node) {
       $links .= '<div class="next">';
       $links .= l(t('next'), 'node/'. $next->nid, array('title' => t('View the next page.')));
       $links .= '</div>';
-      $titles .= '<div class="next">'. $next->title .'</div>';
+      $titles .= '<div class="next">'. check_plain($next->title) .'</div>';
     }
     else {
       $links .= '<div class="next">&nbsp;</div>'; // Make an empty div to fill the space.
@@ -633,7 +633,7 @@ function book_print($nid = 0, $depth = 1) {
       // Allow modules to change $node->body before viewing.
       node_invoke_nodeapi($node, 'view', $node->body, false);
 
-      $output .= '<h1 id="'. $node->nid .'" name="'. $node->nid .'" class="book-h'. $depth .'">'. $node->title .'</h1>';
+      $output .= '<h1 id="'. $node->nid .'" name="'. $node->nid .'" class="book-h'. $depth .'">'. check_plain($node->title) .'</h1>';
 
       if ($node->body) {
         $output .= $node->body;
@@ -643,7 +643,7 @@ function book_print($nid = 0, $depth = 1) {
 
   $output .= book_print_recurse($nid, $depth);
 
-  $html = '<html><head><title>'. $node->title .'</title>';
+  $html = '<html><head><title>'. check_plain($node->title) .'</title>';
   $html .= '<base href="'. $base_url .'/" />';
   $html .= "<style type=\"text/css\">\n@import url(misc/print.css);\n</style>";
   $html .= '</head><body>'. $output .'</body></html>';
@@ -671,7 +671,7 @@ function book_print_recurse($parent = '', $depth = 1) {
       // Allow modules to change $node->body before viewing.
       node_invoke_nodeapi($node, 'view', $node->body, false);
 
-      $output .= '<h1 id="'. $node->nid .'" name="'. $node->nid .'" class="book-h'. $depth .'">'. $node->title .'</h1>';
+      $output .= '<h1 id="'. $node->nid .'" name="'. $node->nid .'" class="book-h'. $depth .'">'. check_plain($node->title) .'</h1>';
 
       if ($node->body) {
         $output .= '<ul>'. $node->body .'</ul>';
@@ -707,7 +707,7 @@ function book_admin_view($nid, $depth = 0) {
   if ($nid) {
     $node = node_load(array('nid' => $nid));
 
-    $output .= '<h3>'. $node->title .'</h3>';
+    $output .= '<h3>'. check_plain($node->title) .'</h3>';
 
     $header = array(t('Title'), t('Weight'), array('data' => t('Operations'), 'colspan' => '3'));
     $rows[] = book_admin_view_line($node);
@@ -738,7 +738,7 @@ function book_admin_save($nid, $edit = array()) {
       }
     }
 
-    $message = t('Updated book %title.', array('%title' => "<em>$book->title</em>"));
+    $message = t('Updated book %title.', array('%title' => theme('placeholder', $book->title)));
     watchdog('content', $message);
 
     return $message;
diff --git a/modules/book/book.module b/modules/book/book.module
index 76bb98b6008a..576f8fd1a9c1 100644
--- a/modules/book/book.module
+++ b/modules/book/book.module
@@ -148,7 +148,7 @@ function book_block($op = 'list', $delta = 0) {
           $expand[] = $node->nid;
         }
 
-        $block['subject'] = $path[0]->title;
+        $block['subject'] = check_plain($path[0]->title);
         $block['content'] = book_tree($expand[0], 5, $expand);
       }
     }
@@ -287,7 +287,7 @@ function book_outline() {
           $output .= form_submit(t('Add to book outline'));
         }
 
-        drupal_set_title($node->title);
+        drupal_set_title(check_plain($node->title));
         print theme('page', form($output));
     }
   }
@@ -477,7 +477,7 @@ function theme_book_navigation($node) {
       $links .= '<div class="prev">';
       $links .= l(t('previous'), 'node/'. $prev->nid, array('title' => t('View the previous page.')));
       $links .= '</div>';
-      $titles .= '<div class="prev">'. $prev->title .'</div>';
+      $titles .= '<div class="prev">'. check_plain($prev->title) .'</div>';
     }
     else {
       $links .= '<div class="prev">&nbsp;</div>'; // Make an empty div to fill the space.
@@ -486,7 +486,7 @@ function theme_book_navigation($node) {
       $links .= '<div class="next">';
       $links .= l(t('next'), 'node/'. $next->nid, array('title' => t('View the next page.')));
       $links .= '</div>';
-      $titles .= '<div class="next">'. $next->title .'</div>';
+      $titles .= '<div class="next">'. check_plain($next->title) .'</div>';
     }
     else {
       $links .= '<div class="next">&nbsp;</div>'; // Make an empty div to fill the space.
@@ -633,7 +633,7 @@ function book_print($nid = 0, $depth = 1) {
       // Allow modules to change $node->body before viewing.
       node_invoke_nodeapi($node, 'view', $node->body, false);
 
-      $output .= '<h1 id="'. $node->nid .'" name="'. $node->nid .'" class="book-h'. $depth .'">'. $node->title .'</h1>';
+      $output .= '<h1 id="'. $node->nid .'" name="'. $node->nid .'" class="book-h'. $depth .'">'. check_plain($node->title) .'</h1>';
 
       if ($node->body) {
         $output .= $node->body;
@@ -643,7 +643,7 @@ function book_print($nid = 0, $depth = 1) {
 
   $output .= book_print_recurse($nid, $depth);
 
-  $html = '<html><head><title>'. $node->title .'</title>';
+  $html = '<html><head><title>'. check_plain($node->title) .'</title>';
   $html .= '<base href="'. $base_url .'/" />';
   $html .= "<style type=\"text/css\">\n@import url(misc/print.css);\n</style>";
   $html .= '</head><body>'. $output .'</body></html>';
@@ -671,7 +671,7 @@ function book_print_recurse($parent = '', $depth = 1) {
       // Allow modules to change $node->body before viewing.
       node_invoke_nodeapi($node, 'view', $node->body, false);
 
-      $output .= '<h1 id="'. $node->nid .'" name="'. $node->nid .'" class="book-h'. $depth .'">'. $node->title .'</h1>';
+      $output .= '<h1 id="'. $node->nid .'" name="'. $node->nid .'" class="book-h'. $depth .'">'. check_plain($node->title) .'</h1>';
 
       if ($node->body) {
         $output .= '<ul>'. $node->body .'</ul>';
@@ -707,7 +707,7 @@ function book_admin_view($nid, $depth = 0) {
   if ($nid) {
     $node = node_load(array('nid' => $nid));
 
-    $output .= '<h3>'. $node->title .'</h3>';
+    $output .= '<h3>'. check_plain($node->title) .'</h3>';
 
     $header = array(t('Title'), t('Weight'), array('data' => t('Operations'), 'colspan' => '3'));
     $rows[] = book_admin_view_line($node);
@@ -738,7 +738,7 @@ function book_admin_save($nid, $edit = array()) {
       }
     }
 
-    $message = t('Updated book %title.', array('%title' => "<em>$book->title</em>"));
+    $message = t('Updated book %title.', array('%title' => theme('placeholder', $book->title)));
     watchdog('content', $message);
 
     return $message;
diff --git a/modules/comment.module b/modules/comment.module
index a22da2242e41..876e89bff1f8 100644
--- a/modules/comment.module
+++ b/modules/comment.module
@@ -274,7 +274,7 @@ function comment_nodeapi(&$node, $op, $arg = 0) {
       $text = '';
       $comments = db_query('SELECT subject, comment, format FROM {comments} WHERE nid = %d AND status = 0', $node->nid);
       while ($comment = db_fetch_object($comments)) {
-        $text .= '<h2>'. $comment->subject .'</h2>'. check_output($comment->comment, $comment->format);
+        $text .= '<h2>'. check_plain($comment->subject) .'</h2>'. check_output($comment->comment, $comment->format);
       }
       return $text;
 
@@ -431,9 +431,12 @@ function comment_validate_form($edit) {
 
   // Validate the comment's subject.  If not specified, extract
   // one from the comment's body.
-  $edit['subject'] = strip_tags($edit['subject']);
-  if ($edit['subject'] == '') {
-    $edit['subject'] = truncate_utf8(strip_tags($edit['comment']), 29, TRUE);
+  if (trim($edit['subject']) == '') {
+    // The body may be in any format, so we:
+    // 1) Filter it into HTML
+    // 2) Strip out all HTML tags
+    // 3) Convert entities back to plain-text.
+    $edit['subject'] = truncate_utf8(decode_entities(strip_tags(check_output($edit['comment'], $edit['format']))), 29, TRUE);
   }
 
   // Validate the comment's body.
@@ -450,7 +453,7 @@ function comment_validate_form($edit) {
   if (!$user->uid) {
     if (variable_get('comment_anonymous', 0) > 0) {
       if ($edit['name']) {
-        $taken = db_result(db_query("SELECT COUNT(uid) FROM {users} WHERE LOWER(name) = '%s'", strip_tags($edit['name'])), 0);
+        $taken = db_result(db_query("SELECT COUNT(uid) FROM {users} WHERE LOWER(name) = '%s'", $edit['name']), 0);
 
         if ($taken != 0) {
           form_set_error('name', t('The name you used belongs to a registered user.'));
@@ -494,7 +497,7 @@ function comment_preview($edit) {
   // Attach the user and time information.
   $comment->uid = $user->uid;
   $comment->timestamp = time();
-  $comment->name = $user->name ? $user->name : $comment->name;
+  $comment->name = check_plain($user->name ? $user->name : $comment->name);
 
   // Preview the comment.
   $output .= theme('comment_view', $comment, theme('links', module_invoke_all('link', 'comment', $comment, 1)));
@@ -523,7 +526,7 @@ function comment_post($edit) {
       // validated/filtered data to perform such check.
       $duplicate = db_result(db_query("SELECT COUNT(cid) FROM {comments} WHERE pid = %d AND nid = %d AND subject = '%s' AND comment = '%s'", $edit['pid'], $edit['nid'], $edit['subject'], $edit['comment']), 0);
       if ($duplicate != 0) {
-        watchdog('content', t('Comment: duplicate %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')), WATCHDOG_WARNING);
+        watchdog('content', t('Comment: duplicate %subject.', array('%subject' => theme('placeholder', $edit['subject']))), WATCHDOG_WARNING);
       }
 
       if ($edit['cid']) {
@@ -538,7 +541,7 @@ function comment_post($edit) {
         module_invoke_all('comment', 'update', $edit);
 
         // Add an entry to the watchdog log.
-        watchdog('content', t('Comment: updated %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
+        watchdog('content', t('Comment: updated %subject.', array('%subject' => theme('placeholder', $edit['subject']))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
       }
       else {
         // Add the comment to database.
@@ -641,7 +644,7 @@ function comment_post($edit) {
         module_invoke_all('comment', 'insert', $edit);
 
         // Add an entry to the watchdog log.
-        watchdog('content', t('Comment: added %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
+        watchdog('content', t('Comment: added %subject.', array('%subject' => theme('placeholder', $edit['subject']))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
       }
 
       // Clear the cache so an anonymous user can see his comment being added.
@@ -662,7 +665,7 @@ function comment_post($edit) {
     }
   }
   else {
-    watchdog('content', t('Comment: unauthorized comment submitted or comment submitted to a closed node %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')), WATCHDOG_WARNING);
+    watchdog('content', t('Comment: unauthorized comment submitted or comment submitted to a closed node (%subject).', array('%subject' => theme('placeholder', $edit['subject']))), WATCHDOG_WARNING);
   }
 }
 
@@ -974,7 +977,7 @@ function comment_delete($cid) {
   }
   else if ($comment->cid) {
     $output = theme('confirm',
-                    t('Are you sure you want to delete the comment %title?', array('%title' => '<em>'. $comment->subject .'</em>')),
+                    t('Are you sure you want to delete the comment %title?', array('%title' => theme('placeholder', $comment->subject))),
                     'node/'. $comment->nid,
                     t('Any replies to this comment will be lost. This action cannot be undone.'),
                     t('Delete'));
@@ -992,7 +995,7 @@ function comment_delete($cid) {
 
 function comment_save($id, $edit) {
   db_query("UPDATE {comments} SET subject = '%s', comment = '%s', status = %d, format = '%s', name = '%s', mail = '%s', homepage = '%s' WHERE cid = %d", $edit['subject'], $edit['comment'], $edit['status'], $edit['format'], $edit['name'], $edit['mail'], $edit['homepage'], $id);
-  watchdog('content', t('Comment: modified %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')));
+  watchdog('content', t('Comment: modified %subject.', array('%subject' => theme('placeholder', $edit['subject']))));
   drupal_set_message(t('The comment has been saved.'));
 
   _comment_update_node_statistics($edit['nid']);
@@ -1023,7 +1026,7 @@ function comment_admin_overview($type = 'new') {
   while ($comment = db_fetch_object($result)) {
     $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
     $rows[] = array(
-        l($comment->subject, "node/$comment->nid", array('title' => htmlspecialchars(truncate_utf8($comment->comment, 128))), NULL, "comment-$comment->cid") ." ". theme('mark', node_mark($comment->nid, $comment->timestamp)),
+        l($comment->subject, "node/$comment->nid", array('title' => truncate_utf8($comment->comment, 128)), NULL, "comment-$comment->cid") ." ". theme('mark', node_mark($comment->nid, $comment->timestamp)),
         format_name($comment),
         ($comment->status == 0 ? t('Published') : t('Not published')),
         format_date($comment->timestamp, 'small'),
@@ -1624,7 +1627,7 @@ function theme_comment_post_forbidden() {
 function _comment_delete_thread($comment) {
   // Delete the comment:
   db_query('DELETE FROM {comments} WHERE cid = %d', $comment->cid);
-  watchdog('content', t('Comment: deleted %subject.', array('%subject' => "<em>$comment->subject</em>")));
+  watchdog('content', t('Comment: deleted %subject.', array('%subject' => theme('placeholder', $comment->subject))));
 
   module_invoke_all('comment', 'delete', $comment);
 
diff --git a/modules/comment/comment.module b/modules/comment/comment.module
index a22da2242e41..876e89bff1f8 100644
--- a/modules/comment/comment.module
+++ b/modules/comment/comment.module
@@ -274,7 +274,7 @@ function comment_nodeapi(&$node, $op, $arg = 0) {
       $text = '';
       $comments = db_query('SELECT subject, comment, format FROM {comments} WHERE nid = %d AND status = 0', $node->nid);
       while ($comment = db_fetch_object($comments)) {
-        $text .= '<h2>'. $comment->subject .'</h2>'. check_output($comment->comment, $comment->format);
+        $text .= '<h2>'. check_plain($comment->subject) .'</h2>'. check_output($comment->comment, $comment->format);
       }
       return $text;
 
@@ -431,9 +431,12 @@ function comment_validate_form($edit) {
 
   // Validate the comment's subject.  If not specified, extract
   // one from the comment's body.
-  $edit['subject'] = strip_tags($edit['subject']);
-  if ($edit['subject'] == '') {
-    $edit['subject'] = truncate_utf8(strip_tags($edit['comment']), 29, TRUE);
+  if (trim($edit['subject']) == '') {
+    // The body may be in any format, so we:
+    // 1) Filter it into HTML
+    // 2) Strip out all HTML tags
+    // 3) Convert entities back to plain-text.
+    $edit['subject'] = truncate_utf8(decode_entities(strip_tags(check_output($edit['comment'], $edit['format']))), 29, TRUE);
   }
 
   // Validate the comment's body.
@@ -450,7 +453,7 @@ function comment_validate_form($edit) {
   if (!$user->uid) {
     if (variable_get('comment_anonymous', 0) > 0) {
       if ($edit['name']) {
-        $taken = db_result(db_query("SELECT COUNT(uid) FROM {users} WHERE LOWER(name) = '%s'", strip_tags($edit['name'])), 0);
+        $taken = db_result(db_query("SELECT COUNT(uid) FROM {users} WHERE LOWER(name) = '%s'", $edit['name']), 0);
 
         if ($taken != 0) {
           form_set_error('name', t('The name you used belongs to a registered user.'));
@@ -494,7 +497,7 @@ function comment_preview($edit) {
   // Attach the user and time information.
   $comment->uid = $user->uid;
   $comment->timestamp = time();
-  $comment->name = $user->name ? $user->name : $comment->name;
+  $comment->name = check_plain($user->name ? $user->name : $comment->name);
 
   // Preview the comment.
   $output .= theme('comment_view', $comment, theme('links', module_invoke_all('link', 'comment', $comment, 1)));
@@ -523,7 +526,7 @@ function comment_post($edit) {
       // validated/filtered data to perform such check.
       $duplicate = db_result(db_query("SELECT COUNT(cid) FROM {comments} WHERE pid = %d AND nid = %d AND subject = '%s' AND comment = '%s'", $edit['pid'], $edit['nid'], $edit['subject'], $edit['comment']), 0);
       if ($duplicate != 0) {
-        watchdog('content', t('Comment: duplicate %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')), WATCHDOG_WARNING);
+        watchdog('content', t('Comment: duplicate %subject.', array('%subject' => theme('placeholder', $edit['subject']))), WATCHDOG_WARNING);
       }
 
       if ($edit['cid']) {
@@ -538,7 +541,7 @@ function comment_post($edit) {
         module_invoke_all('comment', 'update', $edit);
 
         // Add an entry to the watchdog log.
-        watchdog('content', t('Comment: updated %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
+        watchdog('content', t('Comment: updated %subject.', array('%subject' => theme('placeholder', $edit['subject']))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
       }
       else {
         // Add the comment to database.
@@ -641,7 +644,7 @@ function comment_post($edit) {
         module_invoke_all('comment', 'insert', $edit);
 
         // Add an entry to the watchdog log.
-        watchdog('content', t('Comment: added %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
+        watchdog('content', t('Comment: added %subject.', array('%subject' => theme('placeholder', $edit['subject']))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $edit['nid'], NULL, NULL, 'comment-'. $edit['cid']));
       }
 
       // Clear the cache so an anonymous user can see his comment being added.
@@ -662,7 +665,7 @@ function comment_post($edit) {
     }
   }
   else {
-    watchdog('content', t('Comment: unauthorized comment submitted or comment submitted to a closed node %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')), WATCHDOG_WARNING);
+    watchdog('content', t('Comment: unauthorized comment submitted or comment submitted to a closed node (%subject).', array('%subject' => theme('placeholder', $edit['subject']))), WATCHDOG_WARNING);
   }
 }
 
@@ -974,7 +977,7 @@ function comment_delete($cid) {
   }
   else if ($comment->cid) {
     $output = theme('confirm',
-                    t('Are you sure you want to delete the comment %title?', array('%title' => '<em>'. $comment->subject .'</em>')),
+                    t('Are you sure you want to delete the comment %title?', array('%title' => theme('placeholder', $comment->subject))),
                     'node/'. $comment->nid,
                     t('Any replies to this comment will be lost. This action cannot be undone.'),
                     t('Delete'));
@@ -992,7 +995,7 @@ function comment_delete($cid) {
 
 function comment_save($id, $edit) {
   db_query("UPDATE {comments} SET subject = '%s', comment = '%s', status = %d, format = '%s', name = '%s', mail = '%s', homepage = '%s' WHERE cid = %d", $edit['subject'], $edit['comment'], $edit['status'], $edit['format'], $edit['name'], $edit['mail'], $edit['homepage'], $id);
-  watchdog('content', t('Comment: modified %subject.', array('%subject' => '<em>'. $edit['subject'] .'</em>')));
+  watchdog('content', t('Comment: modified %subject.', array('%subject' => theme('placeholder', $edit['subject']))));
   drupal_set_message(t('The comment has been saved.'));
 
   _comment_update_node_statistics($edit['nid']);
@@ -1023,7 +1026,7 @@ function comment_admin_overview($type = 'new') {
   while ($comment = db_fetch_object($result)) {
     $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
     $rows[] = array(
-        l($comment->subject, "node/$comment->nid", array('title' => htmlspecialchars(truncate_utf8($comment->comment, 128))), NULL, "comment-$comment->cid") ." ". theme('mark', node_mark($comment->nid, $comment->timestamp)),
+        l($comment->subject, "node/$comment->nid", array('title' => truncate_utf8($comment->comment, 128)), NULL, "comment-$comment->cid") ." ". theme('mark', node_mark($comment->nid, $comment->timestamp)),
         format_name($comment),
         ($comment->status == 0 ? t('Published') : t('Not published')),
         format_date($comment->timestamp, 'small'),
@@ -1624,7 +1627,7 @@ function theme_comment_post_forbidden() {
 function _comment_delete_thread($comment) {
   // Delete the comment:
   db_query('DELETE FROM {comments} WHERE cid = %d', $comment->cid);
-  watchdog('content', t('Comment: deleted %subject.', array('%subject' => "<em>$comment->subject</em>")));
+  watchdog('content', t('Comment: deleted %subject.', array('%subject' => theme('placeholder', $comment->subject))));
 
   module_invoke_all('comment', 'delete', $comment);
 
diff --git a/modules/contact.module b/modules/contact.module
index 627f6ca3aa70..b86989963814 100644
--- a/modules/contact.module
+++ b/modules/contact.module
@@ -88,7 +88,7 @@ function contact_mail_user() {
 
           // Tidy up the body:
           foreach ($message as $key => $value) {
-            $message[$key] = wordwrap(strip_tags($value));
+            $message[$key] = wordwrap(check_plain($value));
           }
 
           // Prepare all fields:
diff --git a/modules/contact/contact.module b/modules/contact/contact.module
index 627f6ca3aa70..b86989963814 100644
--- a/modules/contact/contact.module
+++ b/modules/contact/contact.module
@@ -88,7 +88,7 @@ function contact_mail_user() {
 
           // Tidy up the body:
           foreach ($message as $key => $value) {
-            $message[$key] = wordwrap(strip_tags($value));
+            $message[$key] = wordwrap(check_plain($value));
           }
 
           // Prepare all fields:
diff --git a/modules/drupal.module b/modules/drupal.module
index 9158221bfdd3..08add863ca40 100644
--- a/modules/drupal.module
+++ b/modules/drupal.module
@@ -95,7 +95,7 @@ function drupal_directory_ping($arguments) {
     db_query("DELETE FROM {directory} WHERE link = '%s' OR mail = '%s'", $link, $mail);
     db_query("INSERT INTO {directory} (link, name, mail, slogan, mission, timestamp) VALUES ('%s', '%s', '%s', '%s', '%s', %d)", $link, $name, $mail, $slogan, $mission, time());
 
-    watchdog('directory ping', t('Ping from %name (%link).', array('%name' => "<em>$name</em>", '%link' => "<em>$link</em>")), WATCHDOG_NOTICE, "<a href=\"$link\">view</a>");
+    watchdog('directory ping', t('Ping from %name (%link).', array('%name' => theme('placeholder', $name), '%link' => theme('placeholder', $link))), WATCHDOG_NOTICE, '<a href="'. check_url($link) .'">view</a>');
 
     return new xmlrpcresp(new xmlrpcval(1, 'int'));
   }
@@ -143,7 +143,7 @@ function drupal_notify($server) {
   $result = $client->send($message, 5);
 
   if (!$result || $result->faultCode()) {
-    watchdog('directory ping', t('Failed to notify %url at %path: %error.', array('%url' => '<em>'. $url["host"] .'</em>', '%path' => '<em>'. $url["path"] .'</em>', '%error' => '<em>'. $result->faultString() .'</em>')), WATCHDOG_WARNING);
+    watchdog('directory ping', t('Failed to notify %url at %path: %error.', array('%url' => theme('placeholder', $url['host']), '%path' => theme('placeholder', $url['path']), '%error' => theme('placeholder', $result->faultString()))), WATCHDOG_WARNING);
   }
 
 }
diff --git a/modules/drupal/drupal.module b/modules/drupal/drupal.module
index 9158221bfdd3..08add863ca40 100644
--- a/modules/drupal/drupal.module
+++ b/modules/drupal/drupal.module
@@ -95,7 +95,7 @@ function drupal_directory_ping($arguments) {
     db_query("DELETE FROM {directory} WHERE link = '%s' OR mail = '%s'", $link, $mail);
     db_query("INSERT INTO {directory} (link, name, mail, slogan, mission, timestamp) VALUES ('%s', '%s', '%s', '%s', '%s', %d)", $link, $name, $mail, $slogan, $mission, time());
 
-    watchdog('directory ping', t('Ping from %name (%link).', array('%name' => "<em>$name</em>", '%link' => "<em>$link</em>")), WATCHDOG_NOTICE, "<a href=\"$link\">view</a>");
+    watchdog('directory ping', t('Ping from %name (%link).', array('%name' => theme('placeholder', $name), '%link' => theme('placeholder', $link))), WATCHDOG_NOTICE, '<a href="'. check_url($link) .'">view</a>');
 
     return new xmlrpcresp(new xmlrpcval(1, 'int'));
   }
@@ -143,7 +143,7 @@ function drupal_notify($server) {
   $result = $client->send($message, 5);
 
   if (!$result || $result->faultCode()) {
-    watchdog('directory ping', t('Failed to notify %url at %path: %error.', array('%url' => '<em>'. $url["host"] .'</em>', '%path' => '<em>'. $url["path"] .'</em>', '%error' => '<em>'. $result->faultString() .'</em>')), WATCHDOG_WARNING);
+    watchdog('directory ping', t('Failed to notify %url at %path: %error.', array('%url' => theme('placeholder', $url['host']), '%path' => theme('placeholder', $url['path']), '%error' => theme('placeholder', $result->faultString()))), WATCHDOG_WARNING);
   }
 
 }
diff --git a/modules/filter.module b/modules/filter.module
index 74e95e079c53..2fa406d75ed0 100644
--- a/modules/filter.module
+++ b/modules/filter.module
@@ -60,9 +60,9 @@ function filter_filter_tips($delta, $format, $long = false) {
           if ($allowed_html = variable_get("allowed_html_$format", '<a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>')) {
             switch ($long) {
               case 0:
-                return t('Allowed HTML tags') .': '. drupal_specialchars($allowed_html);
+                return t('Allowed HTML tags') .': '. check_plain($allowed_html);
               case 1:
-                $output = '<p>'. t('Allowed HTML tags') .': '. drupal_specialchars($allowed_html) .'</p>';
+                $output = '<p>'. t('Allowed HTML tags') .': '. check_plain($allowed_html) .'</p>';
                 if (!variable_get("filter_html_help_$format", 1)) {
                   return $output;
                 }
@@ -111,14 +111,14 @@ function filter_filter_tips($delta, $format, $long = false) {
                     if ($tips[$tag]) {
                       $rows[] = array(
                         array('data' => $tips[$tag][0], 'class' => 'description'),
-                        array('data' => '<code>'. drupal_specialchars($tips[$tag][1]) .'</code>', 'class' => 'type'),
+                        array('data' => '<code>'. check_plain($tips[$tag][1]) .'</code>', 'class' => 'type'),
                         array('data' => $tips[$tag][1], 'class' => 'get')
                       );
                     }
                   }
                   else {
                     $rows[] = array(
-                      array('data' => t('No help provided for tag %tag.', array('%tag' => drupal_specialchars($tag))), 'class' => 'description', 'colspan' => 3),
+                      array('data' => t('No help provided for tag %tag.', array('%tag' => check_plain($tag))), 'class' => 'description', 'colspan' => 3),
                     );
                   }
                 }
@@ -137,7 +137,7 @@ function filter_filter_tips($delta, $format, $long = false) {
                 foreach ($entities as $entity) {
                   $rows[] = array(
                     array('data' => $entity[0], 'class' => 'description'),
-                    array('data' => '<code>'. drupal_specialchars($entity[1]) .'</code>', 'class' => 'type'),
+                    array('data' => '<code>'. check_plain($entity[1]) .'</code>', 'class' => 'type'),
                     array('data' => $entity[1], 'class' => 'get')
                   );
                 }
@@ -365,7 +365,7 @@ function filter_admin_add() {
     db_query("INSERT INTO {filter_formats} (name) VALUES ('%s')", $name);
   }
 
-  drupal_set_message(t('Added input format %format.', array('%format' => '<em>'. $edit['name'] .'</em>')));
+  drupal_set_message(t('Added input format %format.', array('%format' => theme('placeholder', $edit['name']))));
   drupal_goto('admin/filters');
 }
 
@@ -386,7 +386,7 @@ function filter_admin_delete() {
 
       cache_clear_all('filter:'. $edit['format'], true);
 
-      drupal_set_message(t('Deleted input format %format.', array('%format' => '<em>'. $edit['name'] .'</em>')));
+      drupal_set_message(t('Deleted input format %format.', array('%format' => theme('placeholder', $edit['name']))));
     }
     drupal_goto('admin/filters');
   }
@@ -397,7 +397,7 @@ function filter_admin_delete() {
   $extra  = form_hidden('format', $format->format);
   $extra .= form_hidden('name', $format->name);
   $output = theme('confirm',
-                  t('Are you sure you want to delete the input format %format?', array('%format' => '<em>'. $format->name .'</em>')),
+                  t('Are you sure you want to delete the input format %format?', array('%format' => theme('placeholder', $format->name))),
                   'admin/filters',
                   t('If you have any content left in this input format, it will be switched to the default input format. This action cannot be undone.'),
                   t('Delete'),
@@ -927,7 +927,7 @@ function _filter_html($text, $format) {
 
   if (variable_get("filter_html_$format", FILTER_HTML_STRIP) == FILTER_HTML_ESCAPE) {
     // Escape HTML
-    $text = drupal_specialchars($text);
+    $text = check_plain($text);
   }
 
   if (variable_get("filter_html_nofollow_$format", FALSE)) {
diff --git a/modules/filter/filter.module b/modules/filter/filter.module
index 74e95e079c53..2fa406d75ed0 100644
--- a/modules/filter/filter.module
+++ b/modules/filter/filter.module
@@ -60,9 +60,9 @@ function filter_filter_tips($delta, $format, $long = false) {
           if ($allowed_html = variable_get("allowed_html_$format", '<a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>')) {
             switch ($long) {
               case 0:
-                return t('Allowed HTML tags') .': '. drupal_specialchars($allowed_html);
+                return t('Allowed HTML tags') .': '. check_plain($allowed_html);
               case 1:
-                $output = '<p>'. t('Allowed HTML tags') .': '. drupal_specialchars($allowed_html) .'</p>';
+                $output = '<p>'. t('Allowed HTML tags') .': '. check_plain($allowed_html) .'</p>';
                 if (!variable_get("filter_html_help_$format", 1)) {
                   return $output;
                 }
@@ -111,14 +111,14 @@ function filter_filter_tips($delta, $format, $long = false) {
                     if ($tips[$tag]) {
                       $rows[] = array(
                         array('data' => $tips[$tag][0], 'class' => 'description'),
-                        array('data' => '<code>'. drupal_specialchars($tips[$tag][1]) .'</code>', 'class' => 'type'),
+                        array('data' => '<code>'. check_plain($tips[$tag][1]) .'</code>', 'class' => 'type'),
                         array('data' => $tips[$tag][1], 'class' => 'get')
                       );
                     }
                   }
                   else {
                     $rows[] = array(
-                      array('data' => t('No help provided for tag %tag.', array('%tag' => drupal_specialchars($tag))), 'class' => 'description', 'colspan' => 3),
+                      array('data' => t('No help provided for tag %tag.', array('%tag' => check_plain($tag))), 'class' => 'description', 'colspan' => 3),
                     );
                   }
                 }
@@ -137,7 +137,7 @@ function filter_filter_tips($delta, $format, $long = false) {
                 foreach ($entities as $entity) {
                   $rows[] = array(
                     array('data' => $entity[0], 'class' => 'description'),
-                    array('data' => '<code>'. drupal_specialchars($entity[1]) .'</code>', 'class' => 'type'),
+                    array('data' => '<code>'. check_plain($entity[1]) .'</code>', 'class' => 'type'),
                     array('data' => $entity[1], 'class' => 'get')
                   );
                 }
@@ -365,7 +365,7 @@ function filter_admin_add() {
     db_query("INSERT INTO {filter_formats} (name) VALUES ('%s')", $name);
   }
 
-  drupal_set_message(t('Added input format %format.', array('%format' => '<em>'. $edit['name'] .'</em>')));
+  drupal_set_message(t('Added input format %format.', array('%format' => theme('placeholder', $edit['name']))));
   drupal_goto('admin/filters');
 }
 
@@ -386,7 +386,7 @@ function filter_admin_delete() {
 
       cache_clear_all('filter:'. $edit['format'], true);
 
-      drupal_set_message(t('Deleted input format %format.', array('%format' => '<em>'. $edit['name'] .'</em>')));
+      drupal_set_message(t('Deleted input format %format.', array('%format' => theme('placeholder', $edit['name']))));
     }
     drupal_goto('admin/filters');
   }
@@ -397,7 +397,7 @@ function filter_admin_delete() {
   $extra  = form_hidden('format', $format->format);
   $extra .= form_hidden('name', $format->name);
   $output = theme('confirm',
-                  t('Are you sure you want to delete the input format %format?', array('%format' => '<em>'. $format->name .'</em>')),
+                  t('Are you sure you want to delete the input format %format?', array('%format' => theme('placeholder', $format->name))),
                   'admin/filters',
                   t('If you have any content left in this input format, it will be switched to the default input format. This action cannot be undone.'),
                   t('Delete'),
@@ -927,7 +927,7 @@ function _filter_html($text, $format) {
 
   if (variable_get("filter_html_$format", FILTER_HTML_STRIP) == FILTER_HTML_ESCAPE) {
     // Escape HTML
-    $text = drupal_specialchars($text);
+    $text = check_plain($text);
   }
 
   if (variable_get("filter_html_nofollow_$format", FALSE)) {
diff --git a/modules/forum.module b/modules/forum.module
index e086cf991302..dae76244f019 100644
--- a/modules/forum.module
+++ b/modules/forum.module
@@ -228,10 +228,10 @@ function forum_overview() {
   if ($tree) {
     foreach ($tree as $term) {
       if (in_array($term->tid, variable_get('forum_containers', array()))) {
-        $rows[] = array(_forum_depth($term->depth) .' '. $term->name, l(t('edit container'), "admin/forum/edit/container/$term->tid"));
+        $rows[] = array(_forum_depth($term->depth) .' '. check_plain($term->name), l(t('edit container'), "admin/forum/edit/container/$term->tid"));
       }
       else {
-        $rows[] = array(_forum_depth($term->depth) .' '. $term->name, l(t('edit forum'), "admin/forum/edit/forum/$term->tid"));
+        $rows[] = array(_forum_depth($term->depth) .' '. check_plain($term->name), l(t('edit forum'), "admin/forum/edit/forum/$term->tid"));
        }
 
     }
@@ -381,11 +381,11 @@ function forum_link($type, $node = 0, $main = 0) {
     }
 
     if ($prev) {
-      $links[] = l(t('previous forum topic'), "node/$prev->nid", array('title' => $prev->title));
+      $links[] = l(t('previous forum topic'), "node/$prev->nid", array('title' => check_plain($prev->title)));
     }
 
     if ($next) {
-      $links[] = l(t('next forum topic'), "node/$next->nid", array('title' => $next->title));
+      $links[] = l(t('next forum topic'), "node/$next->nid", array('title' => check_plain($next->title)));
     }
   }
 
@@ -478,7 +478,7 @@ function forum_validate(&$node) {
       if (db_result(db_query('SELECT COUNT(*) FROM {term_data} WHERE tid = %d AND vid = %d', $term, $vocabulary))) {
         if (in_array($term, $containers)) {
           $term = taxonomy_get_term($term);
-          form_set_error('taxonomy', t('The item %forum is only a container for forums. Please select one of the forums below it.', array('%forum' => "<em>$term->name</em>")));
+          form_set_error('taxonomy', t('The item %forum is only a container for forums. Please select one of the forums below it.', array('%forum' => theme('placeholder', $term->name))));
         }
         else {
           $node->tid = $term;
@@ -878,7 +878,7 @@ function theme_forum_topic_list($tid, $topics, $sortby, $forum_per_page) {
       if ($topic->tid != $tid) {
         $rows[] = array(
           array('data' => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
-          array('data' => $topic->title, 'class' => 'title'),
+          array('data' => check_plain($topic->title), 'class' => 'title'),
           array('data' => l(t('This topic has been moved'), "forum/$topic->tid"), 'colspan' => '3')
         );
       }
diff --git a/modules/forum/forum.module b/modules/forum/forum.module
index e086cf991302..dae76244f019 100644
--- a/modules/forum/forum.module
+++ b/modules/forum/forum.module
@@ -228,10 +228,10 @@ function forum_overview() {
   if ($tree) {
     foreach ($tree as $term) {
       if (in_array($term->tid, variable_get('forum_containers', array()))) {
-        $rows[] = array(_forum_depth($term->depth) .' '. $term->name, l(t('edit container'), "admin/forum/edit/container/$term->tid"));
+        $rows[] = array(_forum_depth($term->depth) .' '. check_plain($term->name), l(t('edit container'), "admin/forum/edit/container/$term->tid"));
       }
       else {
-        $rows[] = array(_forum_depth($term->depth) .' '. $term->name, l(t('edit forum'), "admin/forum/edit/forum/$term->tid"));
+        $rows[] = array(_forum_depth($term->depth) .' '. check_plain($term->name), l(t('edit forum'), "admin/forum/edit/forum/$term->tid"));
        }
 
     }
@@ -381,11 +381,11 @@ function forum_link($type, $node = 0, $main = 0) {
     }
 
     if ($prev) {
-      $links[] = l(t('previous forum topic'), "node/$prev->nid", array('title' => $prev->title));
+      $links[] = l(t('previous forum topic'), "node/$prev->nid", array('title' => check_plain($prev->title)));
     }
 
     if ($next) {
-      $links[] = l(t('next forum topic'), "node/$next->nid", array('title' => $next->title));
+      $links[] = l(t('next forum topic'), "node/$next->nid", array('title' => check_plain($next->title)));
     }
   }
 
@@ -478,7 +478,7 @@ function forum_validate(&$node) {
       if (db_result(db_query('SELECT COUNT(*) FROM {term_data} WHERE tid = %d AND vid = %d', $term, $vocabulary))) {
         if (in_array($term, $containers)) {
           $term = taxonomy_get_term($term);
-          form_set_error('taxonomy', t('The item %forum is only a container for forums. Please select one of the forums below it.', array('%forum' => "<em>$term->name</em>")));
+          form_set_error('taxonomy', t('The item %forum is only a container for forums. Please select one of the forums below it.', array('%forum' => theme('placeholder', $term->name))));
         }
         else {
           $node->tid = $term;
@@ -878,7 +878,7 @@ function theme_forum_topic_list($tid, $topics, $sortby, $forum_per_page) {
       if ($topic->tid != $tid) {
         $rows[] = array(
           array('data' => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
-          array('data' => $topic->title, 'class' => 'title'),
+          array('data' => check_plain($topic->title), 'class' => 'title'),
           array('data' => l(t('This topic has been moved'), "forum/$topic->tid"), 'colspan' => '3')
         );
       }
diff --git a/modules/locale.module b/modules/locale.module
index 3f31ff75511c..493d34a99148 100644
--- a/modules/locale.module
+++ b/modules/locale.module
@@ -107,6 +107,7 @@ function locale_user($type, $edit, &$user, $category = NULL) {
     if ($user->language == '') {
       $user->language = key($languages['name']);
     }
+    $languages['name'] = array_map('check_plain', $languages['name']);
     return array(array('title' => t('Interface language settings'), 'data' => form_radios(t("Language"), 'language', $user->language, $languages['name'], t("Selecting a different locale will change the interface language of the site."))));
   }
 }
@@ -299,7 +300,7 @@ function locale_admin_manage_delete_screen() {
     if (isset($languages['name'][$edit['langcode']])) {
       db_query("DELETE FROM {locales_meta} WHERE locale = '%s'", $edit['langcode']);
       db_query("DELETE FROM {locales_target} WHERE locale = '%s'", $edit['langcode']);
-      $message = t('%locale language removed.', array('%locale' => '<em>'. t($languages['name'][$edit['langcode']]) .'</em>'));
+      $message = t('%locale language removed.', array('%locale' => theme('placeholder', t($languages['name'][$edit['langcode']]))));
       drupal_set_message($message);
       watchdog('locale', $message);
     }
@@ -320,7 +321,7 @@ function locale_admin_manage_delete_screen() {
 
   $extra = form_hidden('langcode', $langcode);
   $output = theme('confirm',
-                  t('Are you sure you want to delete the language %name?', array('%name' => '<em>'. t($languages['name'][$langcode]) .'</em>')),
+                  t('Are you sure you want to delete the language %name?', array('%name' => theme('placeholder', t($languages['name'][$langcode])))),
                   'admin/locale/language/overview',
                   t('Deleting a language will remove all data associated with it. This action cannot be undone.'),
                   t('Delete'),
@@ -359,7 +360,7 @@ function locale_admin_manage_add() {
         drupal_set_message(t('You need to specify both the language code and the English name of the new language.'), 'error');
       }
       else {
-        drupal_set_message(t('The language %language (%code) is already set up.', array('%language' => '<em>'. $edit['langname'] .'</em>', '%code' => '<em>'. $edit['langcode'] .'</em>')), 'error');
+        drupal_set_message(t('The language %language (%code) is already set up.', array('%language' => '<em>'. check_plain($edit['langname']) .'</em>', '%code' => theme('placeholder', $edit['langcode']))), 'error');
       }
       break;
   }
@@ -388,7 +389,7 @@ function locale_admin_import() {
       // Now import strings into the language
       $file = file_check_upload('file');
       if ($ret = _locale_import_po($file, $edit['langcode'], $edit['mode']) == FALSE) {
-        $message = t('Translation import of %filename failed.', array('%filename' => "<em>$file->filename</em>"));
+        $message = t('Translation import of %filename failed.', array('%filename' => theme('placeholder', $file->filename)));
         drupal_set_message($message, 'error');
         watchdog('locale', $message, WATCHDOG_ERROR);
       }
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
index 3f31ff75511c..493d34a99148 100644
--- a/modules/locale/locale.module
+++ b/modules/locale/locale.module
@@ -107,6 +107,7 @@ function locale_user($type, $edit, &$user, $category = NULL) {
     if ($user->language == '') {
       $user->language = key($languages['name']);
     }
+    $languages['name'] = array_map('check_plain', $languages['name']);
     return array(array('title' => t('Interface language settings'), 'data' => form_radios(t("Language"), 'language', $user->language, $languages['name'], t("Selecting a different locale will change the interface language of the site."))));
   }
 }
@@ -299,7 +300,7 @@ function locale_admin_manage_delete_screen() {
     if (isset($languages['name'][$edit['langcode']])) {
       db_query("DELETE FROM {locales_meta} WHERE locale = '%s'", $edit['langcode']);
       db_query("DELETE FROM {locales_target} WHERE locale = '%s'", $edit['langcode']);
-      $message = t('%locale language removed.', array('%locale' => '<em>'. t($languages['name'][$edit['langcode']]) .'</em>'));
+      $message = t('%locale language removed.', array('%locale' => theme('placeholder', t($languages['name'][$edit['langcode']]))));
       drupal_set_message($message);
       watchdog('locale', $message);
     }
@@ -320,7 +321,7 @@ function locale_admin_manage_delete_screen() {
 
   $extra = form_hidden('langcode', $langcode);
   $output = theme('confirm',
-                  t('Are you sure you want to delete the language %name?', array('%name' => '<em>'. t($languages['name'][$langcode]) .'</em>')),
+                  t('Are you sure you want to delete the language %name?', array('%name' => theme('placeholder', t($languages['name'][$langcode])))),
                   'admin/locale/language/overview',
                   t('Deleting a language will remove all data associated with it. This action cannot be undone.'),
                   t('Delete'),
@@ -359,7 +360,7 @@ function locale_admin_manage_add() {
         drupal_set_message(t('You need to specify both the language code and the English name of the new language.'), 'error');
       }
       else {
-        drupal_set_message(t('The language %language (%code) is already set up.', array('%language' => '<em>'. $edit['langname'] .'</em>', '%code' => '<em>'. $edit['langcode'] .'</em>')), 'error');
+        drupal_set_message(t('The language %language (%code) is already set up.', array('%language' => '<em>'. check_plain($edit['langname']) .'</em>', '%code' => theme('placeholder', $edit['langcode']))), 'error');
       }
       break;
   }
@@ -388,7 +389,7 @@ function locale_admin_import() {
       // Now import strings into the language
       $file = file_check_upload('file');
       if ($ret = _locale_import_po($file, $edit['langcode'], $edit['mode']) == FALSE) {
-        $message = t('Translation import of %filename failed.', array('%filename' => "<em>$file->filename</em>"));
+        $message = t('Translation import of %filename failed.', array('%filename' => theme('placeholder', $file->filename)));
         drupal_set_message($message, 'error');
         watchdog('locale', $message, WATCHDOG_ERROR);
       }
diff --git a/modules/menu.module b/modules/menu.module
index 0a972ec396c4..28e207f921ba 100644
--- a/modules/menu.module
+++ b/modules/menu.module
@@ -120,7 +120,7 @@ function menu_reset() {
       break;
     default:
       $output = theme('confirm',
-                      t('Are you sure you want to reset all menu items to their default settings?', array('%item' => '<em>'. $title .'</em>')),
+                      t('Are you sure you want to reset all menu items to their default settings?'),
                       'admin/menu',
                       t('Any custom additions or changes to the menu will be lost.'),
                       t('Reset all'));
@@ -167,7 +167,7 @@ function menu_reset_item($mid) {
     default:
       $title = db_result(db_query('SELECT title FROM {menu} WHERE mid = %d', $mid));
       $output = theme('confirm',
-                      t('Are you sure you want to reset the item %item to its default values?', array('%item' => '<em>'. $title .'</em>')),
+                      t('Are you sure you want to reset the item %item to its default values?', array('%item' => theme('placeholder', $title))),
                       'admin/menu',
                       t('Any customizations will be lost. This action cannot be undone.'),
                       t('Reset'));
@@ -198,10 +198,10 @@ function menu_delete_item($mid) {
       break;
     default:
       if ($menu->type & MENU_IS_ROOT) {
-        $message = t('Are you sure you want to delete the menu %item?', array('%item' => '<em>'. $menu->title .'</em>'));
+        $message = t('Are you sure you want to delete the menu %item?', array('%item' => theme('placeholder', $menu->title)));
       }
       else {
-        $message = t('Are you sure you want to delete the custom menu item %item?', array('%item' => '<em>'. $menu->title .'</em>'));
+        $message = t('Are you sure you want to delete the custom menu item %item?', array('%item' => theme('placeholder', $menu->title)));
       }     
       $output = theme('confirm', $message, 'admin/menu', t('This action cannot be undone.'), t('Delete'));
       print theme('page', $output);
@@ -348,16 +348,16 @@ function menu_edit_item_save($edit) {
 
   if ($edit['mid']) {
     db_query("UPDATE {menu} SET pid = %d, path = '%s', title = '%s', description = '%s', weight = %d, type = %d WHERE mid = %d", $edit['pid'], $edit['path'], $edit['title'], $edit['description'], $edit['weight'], $edit['type'] | MENU_MODIFIED_BY_ADMIN, $edit['mid']);
-    drupal_set_message(t('Updated menu item %title.', array('%title' => '<em>'. $edit['title'] .'</em>')));
+    drupal_set_message(t('Updated menu item %title.', array('%title' => theme('placeholder', $edit['title']))));
   }
   else {
     $mid = db_next_id('{menu}_mid');
     db_query("INSERT INTO {menu} (mid, pid, path, title, description, weight, type) VALUES (%d, %d, '%s', '%s', '%s', %d, %d)", $mid, $edit['pid'], $edit['path'], $edit['title'], $edit['description'], $edit['weight'], $edit['type'] | MENU_MODIFIED_BY_ADMIN);
-    drupal_set_message(t('Created new menu item %title.', array('%title' => '<em>'. $edit['title'] .'</em>')));
+    drupal_set_message(t('Created new menu item %title.', array('%title' => theme('placeholder', $edit['title']))));
     if (array_key_exists($edit['path'], $menu['path index'])) {
       $old_mid = $menu['path index'][$edit['path']];
       $old_item = $menu['items'][$old_mid];
-      drupal_set_message(t('Since a menu item %old already exists for %path, this new menu item was created as a shortcut to that location.', array('%old' => l('<em>'. $old_item['title'] .'</em>', 'admin/menu/item/edit/'. $old_mid), '%path' => '<em>'. $edit['path'] .'</em>')));
+      drupal_set_message(t('Since a menu item %old already exists for %path, this new menu item was created as a shortcut to that location.', array('%old' => l(theme('placeholder', $old_item['title']), 'admin/menu/item/edit/'. $old_mid, array(), NULL, NULL, FALSE, TRUE), '%path' => theme('placeholder', $edit['path']))));
     }
   }
 }
diff --git a/modules/menu/menu.module b/modules/menu/menu.module
index 0a972ec396c4..28e207f921ba 100644
--- a/modules/menu/menu.module
+++ b/modules/menu/menu.module
@@ -120,7 +120,7 @@ function menu_reset() {
       break;
     default:
       $output = theme('confirm',
-                      t('Are you sure you want to reset all menu items to their default settings?', array('%item' => '<em>'. $title .'</em>')),
+                      t('Are you sure you want to reset all menu items to their default settings?'),
                       'admin/menu',
                       t('Any custom additions or changes to the menu will be lost.'),
                       t('Reset all'));
@@ -167,7 +167,7 @@ function menu_reset_item($mid) {
     default:
       $title = db_result(db_query('SELECT title FROM {menu} WHERE mid = %d', $mid));
       $output = theme('confirm',
-                      t('Are you sure you want to reset the item %item to its default values?', array('%item' => '<em>'. $title .'</em>')),
+                      t('Are you sure you want to reset the item %item to its default values?', array('%item' => theme('placeholder', $title))),
                       'admin/menu',
                       t('Any customizations will be lost. This action cannot be undone.'),
                       t('Reset'));
@@ -198,10 +198,10 @@ function menu_delete_item($mid) {
       break;
     default:
       if ($menu->type & MENU_IS_ROOT) {
-        $message = t('Are you sure you want to delete the menu %item?', array('%item' => '<em>'. $menu->title .'</em>'));
+        $message = t('Are you sure you want to delete the menu %item?', array('%item' => theme('placeholder', $menu->title)));
       }
       else {
-        $message = t('Are you sure you want to delete the custom menu item %item?', array('%item' => '<em>'. $menu->title .'</em>'));
+        $message = t('Are you sure you want to delete the custom menu item %item?', array('%item' => theme('placeholder', $menu->title)));
       }     
       $output = theme('confirm', $message, 'admin/menu', t('This action cannot be undone.'), t('Delete'));
       print theme('page', $output);
@@ -348,16 +348,16 @@ function menu_edit_item_save($edit) {
 
   if ($edit['mid']) {
     db_query("UPDATE {menu} SET pid = %d, path = '%s', title = '%s', description = '%s', weight = %d, type = %d WHERE mid = %d", $edit['pid'], $edit['path'], $edit['title'], $edit['description'], $edit['weight'], $edit['type'] | MENU_MODIFIED_BY_ADMIN, $edit['mid']);
-    drupal_set_message(t('Updated menu item %title.', array('%title' => '<em>'. $edit['title'] .'</em>')));
+    drupal_set_message(t('Updated menu item %title.', array('%title' => theme('placeholder', $edit['title']))));
   }
   else {
     $mid = db_next_id('{menu}_mid');
     db_query("INSERT INTO {menu} (mid, pid, path, title, description, weight, type) VALUES (%d, %d, '%s', '%s', '%s', %d, %d)", $mid, $edit['pid'], $edit['path'], $edit['title'], $edit['description'], $edit['weight'], $edit['type'] | MENU_MODIFIED_BY_ADMIN);
-    drupal_set_message(t('Created new menu item %title.', array('%title' => '<em>'. $edit['title'] .'</em>')));
+    drupal_set_message(t('Created new menu item %title.', array('%title' => theme('placeholder', $edit['title']))));
     if (array_key_exists($edit['path'], $menu['path index'])) {
       $old_mid = $menu['path index'][$edit['path']];
       $old_item = $menu['items'][$old_mid];
-      drupal_set_message(t('Since a menu item %old already exists for %path, this new menu item was created as a shortcut to that location.', array('%old' => l('<em>'. $old_item['title'] .'</em>', 'admin/menu/item/edit/'. $old_mid), '%path' => '<em>'. $edit['path'] .'</em>')));
+      drupal_set_message(t('Since a menu item %old already exists for %path, this new menu item was created as a shortcut to that location.', array('%old' => l(theme('placeholder', $old_item['title']), 'admin/menu/item/edit/'. $old_mid, array(), NULL, NULL, FALSE, TRUE), '%path' => theme('placeholder', $edit['path']))));
     }
   }
 }
diff --git a/modules/node.module b/modules/node.module
index 29aae45cb700..adf40d94cf40 100644
--- a/modules/node.module
+++ b/modules/node.module
@@ -990,7 +990,7 @@ function node_revision_overview($nid) {
   if (user_access('administer nodes')) {
     $node = node_load(array('nid' => $nid));
 
-    drupal_set_title($node->title);
+    drupal_set_title(check_plain($node->title));
 
     if ($node->revisions) {
       $header = array(t('Older revisions'), array('colspan' => '3', 'data' => t('Operations')));
@@ -1059,7 +1059,7 @@ function node_revision_rollback($nid, $revision) {
 
     node_save($rev, $filter);
 
-    drupal_set_message(t('Rolled back to revision %revision of %title', array('%revision' => "<em>#$revision</em>", '%title' => "<em>$node->title</em>")));
+    drupal_set_message(t('Rolled back to revision %revision of %title', array('%revision' => "<em>#$revision</em>", '%title' => theme('placeholder', $node->title))));
     drupal_goto('node/'. $nid .'/revisions');
   }
 }
@@ -1075,7 +1075,7 @@ function node_revision_delete($nid, $revision) {
 
     node_save($node, array('nid', 'revisions'));
 
-    drupal_set_message(t('Deleted revision %revision of %title', array('%revision' => "<em>#$revision</em>", '%title' => "<em>$node->title</em>")));
+    drupal_set_message(t('Deleted revision %revision of %title', array('%revision' => "<em>#$revision</em>", '%title' => theme('placeholder', $node->title))));
     drupal_goto('node/'. $nid . (count($node->revisions) ? '/revisions' : ''));
   }
 }
@@ -1199,9 +1199,8 @@ function node_validate($node) {
 
   // Validate the title field.
   if (isset($node->title)) {
-    $node->title = strip_tags($node->title);
-    if (!$node->title) {
-      form_set_error('title', t('You have to specify a valid title.'));
+    if (trim($node->title) == '') {
+      form_set_error('title', t('You have to specify a title.'));
     }
   }
 
@@ -1242,7 +1241,7 @@ function node_validate($node) {
       $node->uid = $account->uid;
     }
     else {
-      form_set_error('name', t('The name %name does not exist.', array ('%name' => "<em>$node->name</em>")));
+      form_set_error('name', t('The username %name does not exist.', array ('%name' => theme('placeholder', $node->name))));
     }
 
     // Validate the "authored on" field.
@@ -1309,7 +1308,7 @@ function node_form($edit) {
   $output .= '<div class="node-form">';
 
   // Add hidden 'op' variable, which specifies the default operation (Preview).
-  $output .= '<input type="hidden" name="op" value="'. check_form(t('Preview')) ."\" />\n";
+  $output .= '<input type="hidden" name="op" value="'. check_plain(t('Preview')) ."\" />\n";
 
   // Add the admin-specific parts.
   if (user_access('administer nodes')) {
@@ -1455,7 +1454,7 @@ function node_edit($id) {
 
   $node = node_load(array('nid' => $id));
 
-  drupal_set_title($node->title);
+  drupal_set_title(check_plain($node->title));
 
   $output = node_form($node);
 
@@ -1560,7 +1559,7 @@ function node_submit(&$node) {
     // perform this operation:
     if (node_access('update', $node)) {
       $node->nid = node_save($node);
-      watchdog('content', t('%type: updated %title.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => "<em>$node->title</em>")), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
+      watchdog('content', t('%type: updated %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
       $msg = t('The %post was updated.', array ('%post' => node_invoke($node, 'node_name')));
     }
   }
@@ -1569,7 +1568,7 @@ function node_submit(&$node) {
     // perform this operation:
     if (node_access('create', $node)) {
       $node->nid = node_save($node);
-      watchdog('content', t('%type: added %title.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => "<em>$node->title</em>")), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
+      watchdog('content', t('%type: added %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
       $msg = t('Your %post was created.', array ('%post' => node_invoke($node, 'node_name')));
     }
   }
@@ -1603,12 +1602,12 @@ function node_delete($edit) {
         search_wipe($node->nid, 'node');
       }
 
-      watchdog('content', t('%type: deleted %title.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => "<em>$node->title</em>")));
+      watchdog('content', t('%type: deleted %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))));
     }
     else {
       $extra = form_hidden('nid', $node->nid);
       $output = theme('confirm',
-                      t('Are you sure you want to delete %title?', array('%title' => '<em>'. $node->title .'</em>')),
+                      t('Are you sure you want to delete %title?', array('%title' => theme('placeholder', $node->title))),
                       $_GET['destination'] ? $_GET['destination'] : 'node/'. $node->nid,
                       t('This action cannot be undone.'),
                       t('Delete'),
@@ -1681,7 +1680,7 @@ function node_page() {
       if (is_numeric(arg(1))) {
         $node = node_load(array('nid' => arg(1)), $_GET['revision']);
         if ($node->nid) {
-          drupal_set_title($node->title);
+          drupal_set_title(check_plain($node->title));
           print theme('page', node_show($node, arg(2)));
         }
         else {
@@ -1758,7 +1757,7 @@ function node_update_index() {
     // Allow modules to change $node->body before viewing.
     node_invoke_nodeapi($node, 'view', false, false);
 
-    $text = '<h1>'. drupal_specialchars($node->title) .'</h1>'. $node->body;
+    $text = '<h1>'. check_plain($node->title) .'</h1>'. $node->body;
 
     // Fetch extra data normally not visible
     $extra = node_invoke_nodeapi($node, 'update index');
diff --git a/modules/node/node.module b/modules/node/node.module
index 29aae45cb700..adf40d94cf40 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -990,7 +990,7 @@ function node_revision_overview($nid) {
   if (user_access('administer nodes')) {
     $node = node_load(array('nid' => $nid));
 
-    drupal_set_title($node->title);
+    drupal_set_title(check_plain($node->title));
 
     if ($node->revisions) {
       $header = array(t('Older revisions'), array('colspan' => '3', 'data' => t('Operations')));
@@ -1059,7 +1059,7 @@ function node_revision_rollback($nid, $revision) {
 
     node_save($rev, $filter);
 
-    drupal_set_message(t('Rolled back to revision %revision of %title', array('%revision' => "<em>#$revision</em>", '%title' => "<em>$node->title</em>")));
+    drupal_set_message(t('Rolled back to revision %revision of %title', array('%revision' => "<em>#$revision</em>", '%title' => theme('placeholder', $node->title))));
     drupal_goto('node/'. $nid .'/revisions');
   }
 }
@@ -1075,7 +1075,7 @@ function node_revision_delete($nid, $revision) {
 
     node_save($node, array('nid', 'revisions'));
 
-    drupal_set_message(t('Deleted revision %revision of %title', array('%revision' => "<em>#$revision</em>", '%title' => "<em>$node->title</em>")));
+    drupal_set_message(t('Deleted revision %revision of %title', array('%revision' => "<em>#$revision</em>", '%title' => theme('placeholder', $node->title))));
     drupal_goto('node/'. $nid . (count($node->revisions) ? '/revisions' : ''));
   }
 }
@@ -1199,9 +1199,8 @@ function node_validate($node) {
 
   // Validate the title field.
   if (isset($node->title)) {
-    $node->title = strip_tags($node->title);
-    if (!$node->title) {
-      form_set_error('title', t('You have to specify a valid title.'));
+    if (trim($node->title) == '') {
+      form_set_error('title', t('You have to specify a title.'));
     }
   }
 
@@ -1242,7 +1241,7 @@ function node_validate($node) {
       $node->uid = $account->uid;
     }
     else {
-      form_set_error('name', t('The name %name does not exist.', array ('%name' => "<em>$node->name</em>")));
+      form_set_error('name', t('The username %name does not exist.', array ('%name' => theme('placeholder', $node->name))));
     }
 
     // Validate the "authored on" field.
@@ -1309,7 +1308,7 @@ function node_form($edit) {
   $output .= '<div class="node-form">';
 
   // Add hidden 'op' variable, which specifies the default operation (Preview).
-  $output .= '<input type="hidden" name="op" value="'. check_form(t('Preview')) ."\" />\n";
+  $output .= '<input type="hidden" name="op" value="'. check_plain(t('Preview')) ."\" />\n";
 
   // Add the admin-specific parts.
   if (user_access('administer nodes')) {
@@ -1455,7 +1454,7 @@ function node_edit($id) {
 
   $node = node_load(array('nid' => $id));
 
-  drupal_set_title($node->title);
+  drupal_set_title(check_plain($node->title));
 
   $output = node_form($node);
 
@@ -1560,7 +1559,7 @@ function node_submit(&$node) {
     // perform this operation:
     if (node_access('update', $node)) {
       $node->nid = node_save($node);
-      watchdog('content', t('%type: updated %title.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => "<em>$node->title</em>")), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
+      watchdog('content', t('%type: updated %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
       $msg = t('The %post was updated.', array ('%post' => node_invoke($node, 'node_name')));
     }
   }
@@ -1569,7 +1568,7 @@ function node_submit(&$node) {
     // perform this operation:
     if (node_access('create', $node)) {
       $node->nid = node_save($node);
-      watchdog('content', t('%type: added %title.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => "<em>$node->title</em>")), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
+      watchdog('content', t('%type: added %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
       $msg = t('Your %post was created.', array ('%post' => node_invoke($node, 'node_name')));
     }
   }
@@ -1603,12 +1602,12 @@ function node_delete($edit) {
         search_wipe($node->nid, 'node');
       }
 
-      watchdog('content', t('%type: deleted %title.', array('%type' => '<em>'. t($node->type) .'</em>', '%title' => "<em>$node->title</em>")));
+      watchdog('content', t('%type: deleted %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))));
     }
     else {
       $extra = form_hidden('nid', $node->nid);
       $output = theme('confirm',
-                      t('Are you sure you want to delete %title?', array('%title' => '<em>'. $node->title .'</em>')),
+                      t('Are you sure you want to delete %title?', array('%title' => theme('placeholder', $node->title))),
                       $_GET['destination'] ? $_GET['destination'] : 'node/'. $node->nid,
                       t('This action cannot be undone.'),
                       t('Delete'),
@@ -1681,7 +1680,7 @@ function node_page() {
       if (is_numeric(arg(1))) {
         $node = node_load(array('nid' => arg(1)), $_GET['revision']);
         if ($node->nid) {
-          drupal_set_title($node->title);
+          drupal_set_title(check_plain($node->title));
           print theme('page', node_show($node, arg(2)));
         }
         else {
@@ -1758,7 +1757,7 @@ function node_update_index() {
     // Allow modules to change $node->body before viewing.
     node_invoke_nodeapi($node, 'view', false, false);
 
-    $text = '<h1>'. drupal_specialchars($node->title) .'</h1>'. $node->body;
+    $text = '<h1>'. check_plain($node->title) .'</h1>'. $node->body;
 
     // Fetch extra data normally not visible
     $extra = node_invoke_nodeapi($node, 'update index');
diff --git a/modules/path.module b/modules/path.module
index e48589c057e0..ba2251490dfa 100644
--- a/modules/path.module
+++ b/modules/path.module
@@ -296,15 +296,15 @@ function path_save($edit) {
   $pid = $edit['pid'];
 
   if (!valid_url($src)) {
-    form_set_error('src', t('The system path %path is invalid.', array('%path' => "<em>$src</em>")));
+    form_set_error('src', t('The system path %path is invalid.', array('%path' => theme('placeholder', $src))));
   }
 
   if (!valid_url($dst)) {
-    form_set_error('dst', t('The alias %alias is invalid.', array('%alias' => "<em>$dst</em>")));
+    form_set_error('dst', t('The alias %alias is invalid.', array('%alias' => theme('placeholder', $dst))));
   }
 
   if (db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE pid != %d AND dst = '%s'", $pid, $dst))) {
-    form_set_error('dst', t('The alias %alias is already in use.', array('%alias' => "<em>$dst</em>")));
+    form_set_error('dst', t('The alias %alias is already in use.', array('%alias' => theme('placeholder', $dst))));
   }
 
   if (form_get_errors()) {
diff --git a/modules/path/path.module b/modules/path/path.module
index e48589c057e0..ba2251490dfa 100644
--- a/modules/path/path.module
+++ b/modules/path/path.module
@@ -296,15 +296,15 @@ function path_save($edit) {
   $pid = $edit['pid'];
 
   if (!valid_url($src)) {
-    form_set_error('src', t('The system path %path is invalid.', array('%path' => "<em>$src</em>")));
+    form_set_error('src', t('The system path %path is invalid.', array('%path' => theme('placeholder', $src))));
   }
 
   if (!valid_url($dst)) {
-    form_set_error('dst', t('The alias %alias is invalid.', array('%alias' => "<em>$dst</em>")));
+    form_set_error('dst', t('The alias %alias is invalid.', array('%alias' => theme('placeholder', $dst))));
   }
 
   if (db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE pid != %d AND dst = '%s'", $pid, $dst))) {
-    form_set_error('dst', t('The alias %alias is already in use.', array('%alias' => "<em>$dst</em>")));
+    form_set_error('dst', t('The alias %alias is already in use.', array('%alias' => theme('placeholder', $dst))));
   }
 
   if (form_get_errors()) {
diff --git a/modules/poll.module b/modules/poll.module
index d5eae590a48c..933c1067ac24 100644
--- a/modules/poll.module
+++ b/modules/poll.module
@@ -307,9 +307,9 @@ function poll_view_voting(&$node, $teaser, $page, $block) {
   if ($node->choice) {
     $list = array();
     foreach ($node->choice as $i => $choice) {
-      $list[$i] = drupal_specialchars($choice['chtext']);
+      $list[$i] = check_plain($choice['chtext']);
     }
-    $form .= form_radios($page ? '' : $node->title, 'choice', -1, $list);
+    $form .= form_radios($page ? '' : check_plain($node->title), 'choice', -1, $list);
   }
   $form .= '</div>';
   $form .= form_hidden('nid', $node->nid);
@@ -336,12 +336,12 @@ function poll_view_results(&$node, $teaser, $page, $block) {
   // Output the divs for the text, bars and percentages
   $output .= '<div class="poll">';
   if ($block) {
-    $output .= '<div class="title">'. $node->title .'</div>';
+    $output .= '<div class="title">'. check_plain($node->title) .'</div>';
   }
   foreach ($node->choice as $i => $choice) {
     if ($choice['chtext'] != '') {
       $percentage = round($choice['chvotes'] * 100 / max($votestotal, 1));
-      $output .= '<div class="text">'. drupal_specialchars($choice['chtext']) .'</div>';
+      $output .= '<div class="text">'. check_plain($choice['chtext']) .'</div>';
       $output .= '<div class="bar">';
       $output .= '<div style="width: '. $percentage .'%;" class="foreground"></div>';
       $output .= '</div>';
@@ -360,7 +360,7 @@ function poll_view_results(&$node, $teaser, $page, $block) {
  */
 function poll_results() {
   if ($node = node_load(array('nid' => arg(1)))) {
-    drupal_set_title($node->title);
+    drupal_set_title(check_plain($node->title));
     print theme('page', node_show($node, 0));
   }
   else {
diff --git a/modules/poll/poll.module b/modules/poll/poll.module
index d5eae590a48c..933c1067ac24 100644
--- a/modules/poll/poll.module
+++ b/modules/poll/poll.module
@@ -307,9 +307,9 @@ function poll_view_voting(&$node, $teaser, $page, $block) {
   if ($node->choice) {
     $list = array();
     foreach ($node->choice as $i => $choice) {
-      $list[$i] = drupal_specialchars($choice['chtext']);
+      $list[$i] = check_plain($choice['chtext']);
     }
-    $form .= form_radios($page ? '' : $node->title, 'choice', -1, $list);
+    $form .= form_radios($page ? '' : check_plain($node->title), 'choice', -1, $list);
   }
   $form .= '</div>';
   $form .= form_hidden('nid', $node->nid);
@@ -336,12 +336,12 @@ function poll_view_results(&$node, $teaser, $page, $block) {
   // Output the divs for the text, bars and percentages
   $output .= '<div class="poll">';
   if ($block) {
-    $output .= '<div class="title">'. $node->title .'</div>';
+    $output .= '<div class="title">'. check_plain($node->title) .'</div>';
   }
   foreach ($node->choice as $i => $choice) {
     if ($choice['chtext'] != '') {
       $percentage = round($choice['chvotes'] * 100 / max($votestotal, 1));
-      $output .= '<div class="text">'. drupal_specialchars($choice['chtext']) .'</div>';
+      $output .= '<div class="text">'. check_plain($choice['chtext']) .'</div>';
       $output .= '<div class="bar">';
       $output .= '<div style="width: '. $percentage .'%;" class="foreground"></div>';
       $output .= '</div>';
@@ -360,7 +360,7 @@ function poll_view_results(&$node, $teaser, $page, $block) {
  */
 function poll_results() {
   if ($node = node_load(array('nid' => arg(1)))) {
-    drupal_set_title($node->title);
+    drupal_set_title(check_plain($node->title));
     print theme('page', node_show($node, 0));
   }
   else {
diff --git a/modules/profile.module b/modules/profile.module
index 8e9c2bdbc040..d47caa4003ef 100644
--- a/modules/profile.module
+++ b/modules/profile.module
@@ -107,7 +107,7 @@ function profile_browse() {
     $output .= theme('pager', NULL, 20);
 
     if ($field->type == 'selection' || $field->type == 'list') {
-      $title = strtr($field->page, array('%value' => $value));
+      $title = strtr($field->page, array('%value' => theme('placeholder', $value)));
     }
     else {
       $title = $field->page;
@@ -178,15 +178,15 @@ function profile_view_field($user, $field) {
   if ($value = $user->{$field->name}) {
     switch ($field->type) {
       case 'textfield':
-        return drupal_specialchars($value);
+        return check_plain($value);
       case 'textarea':
         return check_output($value);
       case 'selection':
-        return $browse ? l(drupal_specialchars($value), "profile/$field->name/". check_url($value)) : drupal_specialchars($value);
+        return $browse ? l($value, "profile/$field->name/$value") : check_plain($value);
       case 'checkbox':
-        return $browse ? l(strip_tags($field->title), "profile/$field->name") : drupal_specialchars($field->title);
+        return $browse ? l($field->title, "profile/$field->name") : check_plain($field->title);
       case 'url':
-        return '<a href="'. check_url($value) .'">'. drupal_specialchars($value) .'</a>';
+        return '<a href="'. check_url($value) .'">'. check_plain($value) .'</a>';
       case 'date':
         list($format) = explode(' - ', variable_get('date_format_short', 'm/d/Y - H:i'), 2);
         // Note: we avoid PHP's date() because it does not handle dates before
@@ -203,7 +203,7 @@ function profile_view_field($user, $field) {
         $fields = array();
         foreach ($values as $value) {
           if ($value = trim($value)) {
-            $fields[] = $browse ? l(drupal_specialchars($value), "profile/$field->name/". check_url($value)) : drupal_specialchars($value);
+            $fields[] = $browse ? l($value, "profile/$field->name/$value") : check_plain($value);
           }
         }
         return implode(', ', $fields);
@@ -226,7 +226,7 @@ function profile_view_profile($user) {
   while ($field = db_fetch_object($result)) {
     if ($value = profile_view_field($user, $field)) {
       $description = ($field->visibility == PROFILE_PRIVATE) ? t('The content of this field is private and only visible to yourself.') : '';
-      $title = ($field->type != 'checkbox') ? $field->title : '';
+      $title = ($field->type != 'checkbox') ? check_plain($field->title) : '';
       $fields[$field->category] .= form_item($title, $value, $description);
     }
   }
@@ -264,16 +264,16 @@ function profile_form_profile($edit, $user, $category) {
     switch ($field->type) {
       case 'textfield':
       case 'url':
-        $fields[$category] .= form_textfield($field->title, $field->name, $edit[$field->name], 70, 255, _profile_form_explanation($field), NULL, $field->required);
+        $fields[$category] .= form_textfield(check_plain($field->title), $field->name, $edit[$field->name], 70, 255, _profile_form_explanation($field), NULL, $field->required);
         break;
       case 'textarea':
-        $fields[$category] .= form_textarea($field->title, $field->name, $edit[$field->name], 70, 5, _profile_form_explanation($field), NULL, $field->required);
+        $fields[$category] .= form_textarea(check_plain($field->title), $field->name, $edit[$field->name], 70, 5, _profile_form_explanation($field), NULL, $field->required);
         break;
       case 'list':
-        $fields[$category] .= form_textarea($field->title, $field->name, $edit[$field->name], 70, 5, _profile_form_explanation($field), NULL, $field->required);
+        $fields[$category] .= form_textarea(check_plain($field->title), $field->name, $edit[$field->name], 70, 5, _profile_form_explanation($field), NULL, $field->required);
         break;
       case 'checkbox':
-        $fields[$category] .= form_checkbox($field->title, $field->name, 1, $edit[$field->name], _profile_form_explanation($field), NULL, $field->required);
+        $fields[$category] .= form_checkbox(check_plain($field->title), $field->name, 1, $edit[$field->name], _profile_form_explanation($field), NULL, $field->required);
         break;
       case 'selection':
         $options = array('--');
@@ -284,7 +284,7 @@ function profile_form_profile($edit, $user, $category) {
           }
         }
 
-        $fields[$category] .= form_select($field->title, $field->name, $edit[$field->name], $options, _profile_form_explanation($field), 0, 0, $field->required);
+        $fields[$category] .= form_select(check_plain($field->title), $field->name, $edit[$field->name], $options, _profile_form_explanation($field), 0, 0, $field->required);
         break;
       case 'date':
         $fields[$category] .= _profile_date_field($field, $edit);
@@ -338,7 +338,7 @@ function _profile_date_field($field, $edit) {
   }
   $output .= '</div>';
 
-  return form_item($field->title, $output, _profile_form_explanation($field), NULL, $field->required);
+  return form_item(check_plain($field->title), $output, _profile_form_explanation($field), NULL, $field->required);
 }
 
 /**
@@ -362,12 +362,12 @@ function profile_validate_profile($edit, $category) {
     if ($edit[$field->name]) {
       if ($field->type == 'url') {
         if (!valid_url($edit[$field->name], true)) {
-          form_set_error($field->name, t('The value provided for %field is not a valid URL.', array('%field' => "<em>$field->title</em>")));
-         }
+          form_set_error($field->name, t('The value provided for %field is not a valid URL.', array('%field' => theme('placeholder', $field->title))));
+        }
       }
     }
     else if ($field->required && !user_access('administer users')) {
-      form_set_error($field->name, t('The field %field is required.', array('%field' => "<em>$field->title</em>")));
+      form_set_error($field->name, t('The field %field is required.', array('%field' => theme('placeholder', $field->title))));
     }
   }
 
@@ -377,7 +377,7 @@ function profile_validate_profile($edit, $category) {
 function profile_categories() {
   $result = db_query("SELECT DISTINCT(category) FROM {profile_fields}");
   while ($category = db_fetch_object($result)) {
-    $data[] = array('name' => drupal_specialchars($category->category), 'title' => $category->category, 'weight' => 3);
+    $data[] = array('name' => check_plain($category->category), 'title' => $category->category, 'weight' => 3);
   }
   return $data;
 }
@@ -539,7 +539,7 @@ function profile_admin_overview() {
   $result = db_query('SELECT * FROM {profile_fields} ORDER BY category, weight');
   $rows = array();
   while ($field = db_fetch_object($result)) {
-    $rows[] = array($field->title, $field->name, _profile_field_types($field->type), $field->category, l(t('edit'), "admin/settings/profile/edit/$field->fid"), l(t('delete'), "admin/settings/profile/delete/$field->fid"));
+    $rows[] = array(check_plain($field->title), $field->name, _profile_field_types($field->type), $field->category, l(t('edit'), "admin/settings/profile/edit/$field->fid"), l(t('delete'), "admin/settings/profile/delete/$field->fid"));
   }
   if (count($rows) == 0) {
     $rows[] = array(array('data' => t('No fields defined.'), 'colspan' => '6'));
diff --git a/modules/profile/profile.module b/modules/profile/profile.module
index 8e9c2bdbc040..d47caa4003ef 100644
--- a/modules/profile/profile.module
+++ b/modules/profile/profile.module
@@ -107,7 +107,7 @@ function profile_browse() {
     $output .= theme('pager', NULL, 20);
 
     if ($field->type == 'selection' || $field->type == 'list') {
-      $title = strtr($field->page, array('%value' => $value));
+      $title = strtr($field->page, array('%value' => theme('placeholder', $value)));
     }
     else {
       $title = $field->page;
@@ -178,15 +178,15 @@ function profile_view_field($user, $field) {
   if ($value = $user->{$field->name}) {
     switch ($field->type) {
       case 'textfield':
-        return drupal_specialchars($value);
+        return check_plain($value);
       case 'textarea':
         return check_output($value);
       case 'selection':
-        return $browse ? l(drupal_specialchars($value), "profile/$field->name/". check_url($value)) : drupal_specialchars($value);
+        return $browse ? l($value, "profile/$field->name/$value") : check_plain($value);
       case 'checkbox':
-        return $browse ? l(strip_tags($field->title), "profile/$field->name") : drupal_specialchars($field->title);
+        return $browse ? l($field->title, "profile/$field->name") : check_plain($field->title);
       case 'url':
-        return '<a href="'. check_url($value) .'">'. drupal_specialchars($value) .'</a>';
+        return '<a href="'. check_url($value) .'">'. check_plain($value) .'</a>';
       case 'date':
         list($format) = explode(' - ', variable_get('date_format_short', 'm/d/Y - H:i'), 2);
         // Note: we avoid PHP's date() because it does not handle dates before
@@ -203,7 +203,7 @@ function profile_view_field($user, $field) {
         $fields = array();
         foreach ($values as $value) {
           if ($value = trim($value)) {
-            $fields[] = $browse ? l(drupal_specialchars($value), "profile/$field->name/". check_url($value)) : drupal_specialchars($value);
+            $fields[] = $browse ? l($value, "profile/$field->name/$value") : check_plain($value);
           }
         }
         return implode(', ', $fields);
@@ -226,7 +226,7 @@ function profile_view_profile($user) {
   while ($field = db_fetch_object($result)) {
     if ($value = profile_view_field($user, $field)) {
       $description = ($field->visibility == PROFILE_PRIVATE) ? t('The content of this field is private and only visible to yourself.') : '';
-      $title = ($field->type != 'checkbox') ? $field->title : '';
+      $title = ($field->type != 'checkbox') ? check_plain($field->title) : '';
       $fields[$field->category] .= form_item($title, $value, $description);
     }
   }
@@ -264,16 +264,16 @@ function profile_form_profile($edit, $user, $category) {
     switch ($field->type) {
       case 'textfield':
       case 'url':
-        $fields[$category] .= form_textfield($field->title, $field->name, $edit[$field->name], 70, 255, _profile_form_explanation($field), NULL, $field->required);
+        $fields[$category] .= form_textfield(check_plain($field->title), $field->name, $edit[$field->name], 70, 255, _profile_form_explanation($field), NULL, $field->required);
         break;
       case 'textarea':
-        $fields[$category] .= form_textarea($field->title, $field->name, $edit[$field->name], 70, 5, _profile_form_explanation($field), NULL, $field->required);
+        $fields[$category] .= form_textarea(check_plain($field->title), $field->name, $edit[$field->name], 70, 5, _profile_form_explanation($field), NULL, $field->required);
         break;
       case 'list':
-        $fields[$category] .= form_textarea($field->title, $field->name, $edit[$field->name], 70, 5, _profile_form_explanation($field), NULL, $field->required);
+        $fields[$category] .= form_textarea(check_plain($field->title), $field->name, $edit[$field->name], 70, 5, _profile_form_explanation($field), NULL, $field->required);
         break;
       case 'checkbox':
-        $fields[$category] .= form_checkbox($field->title, $field->name, 1, $edit[$field->name], _profile_form_explanation($field), NULL, $field->required);
+        $fields[$category] .= form_checkbox(check_plain($field->title), $field->name, 1, $edit[$field->name], _profile_form_explanation($field), NULL, $field->required);
         break;
       case 'selection':
         $options = array('--');
@@ -284,7 +284,7 @@ function profile_form_profile($edit, $user, $category) {
           }
         }
 
-        $fields[$category] .= form_select($field->title, $field->name, $edit[$field->name], $options, _profile_form_explanation($field), 0, 0, $field->required);
+        $fields[$category] .= form_select(check_plain($field->title), $field->name, $edit[$field->name], $options, _profile_form_explanation($field), 0, 0, $field->required);
         break;
       case 'date':
         $fields[$category] .= _profile_date_field($field, $edit);
@@ -338,7 +338,7 @@ function _profile_date_field($field, $edit) {
   }
   $output .= '</div>';
 
-  return form_item($field->title, $output, _profile_form_explanation($field), NULL, $field->required);
+  return form_item(check_plain($field->title), $output, _profile_form_explanation($field), NULL, $field->required);
 }
 
 /**
@@ -362,12 +362,12 @@ function profile_validate_profile($edit, $category) {
     if ($edit[$field->name]) {
       if ($field->type == 'url') {
         if (!valid_url($edit[$field->name], true)) {
-          form_set_error($field->name, t('The value provided for %field is not a valid URL.', array('%field' => "<em>$field->title</em>")));
-         }
+          form_set_error($field->name, t('The value provided for %field is not a valid URL.', array('%field' => theme('placeholder', $field->title))));
+        }
       }
     }
     else if ($field->required && !user_access('administer users')) {
-      form_set_error($field->name, t('The field %field is required.', array('%field' => "<em>$field->title</em>")));
+      form_set_error($field->name, t('The field %field is required.', array('%field' => theme('placeholder', $field->title))));
     }
   }
 
@@ -377,7 +377,7 @@ function profile_validate_profile($edit, $category) {
 function profile_categories() {
   $result = db_query("SELECT DISTINCT(category) FROM {profile_fields}");
   while ($category = db_fetch_object($result)) {
-    $data[] = array('name' => drupal_specialchars($category->category), 'title' => $category->category, 'weight' => 3);
+    $data[] = array('name' => check_plain($category->category), 'title' => $category->category, 'weight' => 3);
   }
   return $data;
 }
@@ -539,7 +539,7 @@ function profile_admin_overview() {
   $result = db_query('SELECT * FROM {profile_fields} ORDER BY category, weight');
   $rows = array();
   while ($field = db_fetch_object($result)) {
-    $rows[] = array($field->title, $field->name, _profile_field_types($field->type), $field->category, l(t('edit'), "admin/settings/profile/edit/$field->fid"), l(t('delete'), "admin/settings/profile/delete/$field->fid"));
+    $rows[] = array(check_plain($field->title), $field->name, _profile_field_types($field->type), $field->category, l(t('edit'), "admin/settings/profile/edit/$field->fid"), l(t('delete'), "admin/settings/profile/delete/$field->fid"));
   }
   if (count($rows) == 0) {
     $rows[] = array(array('data' => t('No fields defined.'), 'colspan' => '6'));
diff --git a/modules/queue.module b/modules/queue.module
index b37d4b5fd16d..0aef36ebb1ed 100644
--- a/modules/queue.module
+++ b/modules/queue.module
@@ -78,34 +78,34 @@ function queue_vote($node, $vote) {
       $node->moderate = 0;
       $node->promote = 1;
       node_save($node);
-      watchdog('content', t('Moderation: approved %title.', array('%title' => "<em>$node->title</em>")));
+      watchdog('content', t('Moderation: approved %title.', array('%title' => theme('placeholder', $node->title))));
       drupal_set_message(t('The post is promoted.'));
     }
     else if (variable_get('queue_threshold_dump', -2) >= $node->score) {
       if ($node->revisions) {
         node_revision_rollback($node, end(node_revision_list($node)));
-        watchdog('content', t('Moderation: declined %title (rollback).', array('%title' => "<em>$node->title</em>")));
+        watchdog('content', t('Moderation: declined %title (rollback).', array('%title' => theme('placeholder', $node->title))));
         drupal_set_message(t('The post has been declined and the previous version has been restored.'));
       }
       else {
         $node->moderate = 0;
         $node->status = 0;
         node_save($node);
-        watchdog('content', t('Moderation: declined %title.', array('%title' => "<em>$node->title</em>")));
+        watchdog('content', t('Moderation: declined %title.', array('%title' => theme('placeholder', $node->title))));
         drupal_set_message(t('The post has been declined.'));
       }
     }
     else if (variable_get('queue_threshold_expire', 8) <= $node->votes) {
       if ($node->revisions) {
         node_revision_rollback($node, end(node_revision_list($node)));
-        watchdog('content', t('Moderation: expired %title (rollback).', array('%title' => "<em>$node->title</em>")));
+        watchdog('content', t('Moderation: expired %title (rollback).', array('%title' => theme('placeholder', $node->title))));
         drupal_set_message(t('The post has expired and the previous version has been restored.'));
       }
       else {
         $node->moderate = 0;
         $node->status = 0;
         node_save($node);
-        watchdog('content', t('Moderation: expired %title.', array('%title' => "<em>$node->title</em>")));
+        watchdog('content', t('Moderation: expired %title.', array('%title' => theme('placeholder', $node->title))));
         drupal_set_message(t('The post has expired.'));
       }
     }
diff --git a/modules/search.module b/modules/search.module
index 7b8862239cd2..8fa3f1e5da4b 100644
--- a/modules/search.module
+++ b/modules/search.module
@@ -503,7 +503,7 @@ function do_search($keywords, $type, $join = '', $where = '1', $variation = true
     $message = format_plural(count($refused),
                              'The word %words was not included because it is too short.',
                              'The words %words were not included because they were too short.');
-    drupal_set_message(strtr($message, array('%words' => '<em>'. drupal_specialchars(implode(', ', $refused)) .'</em>')));
+    drupal_set_message(strtr($message, array('%words' => theme('placeholder', implode(', ', $refused)))));
   }
 
   if (count($words) == 0) {
@@ -559,7 +559,7 @@ function search_view() {
     if ($type == '') {
       $type = 'node';
     }
-    drupal_goto('search/'. $type .'/'. urlencode($_POST['edit']['keys']));
+    drupal_goto('search/'. urlencode($type) .'/'. urlencode($_POST['edit']['keys']));
   }
   else if ($type == '') {
     // Note: search/node can not be a default tab because it would take on the
@@ -574,9 +574,9 @@ function search_view() {
     if (trim($keys)) {
       // Log the search keys:
       watchdog('search',
-        t('Search: %keys (%type).', array('%keys' => "<em>$keys</em>", '%type' => module_invoke($type, 'search', 'name'))),
+        t('Search: %keys (%type).', array('%keys' => theme('placeholder', $keys), '%type' => module_invoke($type, 'search', 'name'))),
         WATCHDOG_NOTICE,
-        l(t('results'), 'search', NULL, 'keys='. urlencode($keys) . '&type='. urlencode($type))
+        l(t('results'), 'search/'. urlencode($type) .'/'. urlencode($keys))
         );
 
       // Collect the search results:
@@ -833,7 +833,7 @@ function theme_search_item($item, $type) {
     $output = module_invoke($type, 'search_item', $item);
   }
   else {
-    $output = ' <dt class="title"><a href="'. $item['link'] .'">'. $item['title'] .'</a></dt>';
+    $output = ' <dt class="title"><a href="'. check_url($item['link']) .'">'. check_plain($item['title']) .'</a></dt>';
     $info = array();
     if ($item['type']) {
       $info[] = $item['type'];
diff --git a/modules/search/search.module b/modules/search/search.module
index 7b8862239cd2..8fa3f1e5da4b 100644
--- a/modules/search/search.module
+++ b/modules/search/search.module
@@ -503,7 +503,7 @@ function do_search($keywords, $type, $join = '', $where = '1', $variation = true
     $message = format_plural(count($refused),
                              'The word %words was not included because it is too short.',
                              'The words %words were not included because they were too short.');
-    drupal_set_message(strtr($message, array('%words' => '<em>'. drupal_specialchars(implode(', ', $refused)) .'</em>')));
+    drupal_set_message(strtr($message, array('%words' => theme('placeholder', implode(', ', $refused)))));
   }
 
   if (count($words) == 0) {
@@ -559,7 +559,7 @@ function search_view() {
     if ($type == '') {
       $type = 'node';
     }
-    drupal_goto('search/'. $type .'/'. urlencode($_POST['edit']['keys']));
+    drupal_goto('search/'. urlencode($type) .'/'. urlencode($_POST['edit']['keys']));
   }
   else if ($type == '') {
     // Note: search/node can not be a default tab because it would take on the
@@ -574,9 +574,9 @@ function search_view() {
     if (trim($keys)) {
       // Log the search keys:
       watchdog('search',
-        t('Search: %keys (%type).', array('%keys' => "<em>$keys</em>", '%type' => module_invoke($type, 'search', 'name'))),
+        t('Search: %keys (%type).', array('%keys' => theme('placeholder', $keys), '%type' => module_invoke($type, 'search', 'name'))),
         WATCHDOG_NOTICE,
-        l(t('results'), 'search', NULL, 'keys='. urlencode($keys) . '&type='. urlencode($type))
+        l(t('results'), 'search/'. urlencode($type) .'/'. urlencode($keys))
         );
 
       // Collect the search results:
@@ -833,7 +833,7 @@ function theme_search_item($item, $type) {
     $output = module_invoke($type, 'search_item', $item);
   }
   else {
-    $output = ' <dt class="title"><a href="'. $item['link'] .'">'. $item['title'] .'</a></dt>';
+    $output = ' <dt class="title"><a href="'. check_url($item['link']) .'">'. check_plain($item['title']) .'</a></dt>';
     $info = array();
     if ($item['type']) {
       $info[] = $item['type'];
diff --git a/modules/statistics.module b/modules/statistics.module
index bc57b0ab274d..8261758bcea3 100644
--- a/modules/statistics.module
+++ b/modules/statistics.module
@@ -183,7 +183,7 @@ function statistics_node_tracker() {
       $rows[] = array(array('data' => $pager, 'colspan' => '4'));
     }
 
-    drupal_set_title($node->title);
+    drupal_set_title(check_plain($node->title));
     print theme('page', theme('table', $header, $rows));
   }
   else {
diff --git a/modules/statistics/statistics.module b/modules/statistics/statistics.module
index bc57b0ab274d..8261758bcea3 100644
--- a/modules/statistics/statistics.module
+++ b/modules/statistics/statistics.module
@@ -183,7 +183,7 @@ function statistics_node_tracker() {
       $rows[] = array(array('data' => $pager, 'colspan' => '4'));
     }
 
-    drupal_set_title($node->title);
+    drupal_set_title(check_plain($node->title));
     print theme('page', theme('table', $header, $rows));
   }
   else {
diff --git a/modules/taxonomy.module b/modules/taxonomy.module
index 17de7a520b03..9ebc1aebf841 100644
--- a/modules/taxonomy.module
+++ b/modules/taxonomy.module
@@ -130,7 +130,7 @@ function taxonomy_save_vocabulary($edit) {
       db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $edit['vid'], $type);
     }
     module_invoke_all('taxonomy', 'update', 'vocabulary', $edit);
-    $message = t('Updated vocabulary %name.', array('%name' => '<em>'. $edit['name'] .'</em>'));
+    $message = t('Updated vocabulary %name.', array('%name' => theme('placeholder', $edit['name'])));
   }
   else if ($edit['vid']) {
     $message = taxonomy_del_vocabulary($edit['vid']);
@@ -142,7 +142,7 @@ function taxonomy_save_vocabulary($edit) {
       db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $edit['vid'], $type);
     }
     module_invoke_all('taxonomy', 'insert', 'vocabulary', $edit);
-    $message = t('Created new vocabulary %name.', array('%name' => '<em>'. $edit['name'] .'</em>'));
+    $message = t('Created new vocabulary %name.', array('%name' => theme('placeholder', $edit['name'])));
   }
 
   cache_clear_all();
@@ -236,7 +236,7 @@ function taxonomy_save_term($edit) {
 
     db_query('UPDATE {term_data} SET '. _taxonomy_prepare_update($data) .' WHERE tid = %d', $edit['tid']);
     module_invoke_all('taxonomy', 'update', 'term', $edit);
-    $message = t('The term %term has been updated.', array('%term' => '<em>'. $edit['name'] .'</em>'));
+    $message = t('The term %term has been updated.', array('%term' => theme('placeholder', $edit['name'])));
   }
   else if ($edit['tid']) {
     return taxonomy_del_term($edit['tid']);
@@ -246,7 +246,7 @@ function taxonomy_save_term($edit) {
     $data = array('tid' => $edit['tid'], 'name' => $edit['name'], 'description' => $edit['description'], 'vid' => $edit['vid'], 'weight' => $edit['weight']);
     db_query('INSERT INTO {term_data} '. _taxonomy_prepare_insert($data, 1) .' VALUES '. _taxonomy_prepare_insert($data, 2));
     module_invoke_all('taxonomy', 'insert', 'term', $edit);
-    $message = t('Created new term %term.', array('%term' => '<em>'. $edit['name'] .'</em>'));
+    $message = t('Created new term %term.', array('%term' => theme('placeholder', $edit['name'])));
   }
 
   db_query('DELETE FROM {term_relation} WHERE tid1 = %d OR tid2 = %d', $edit['tid'], $edit['tid']);
@@ -315,7 +315,7 @@ function taxonomy_del_term($tid) {
       db_query('DELETE FROM {term_node} WHERE tid = %d', $tid);
 
       module_invoke_all('taxonomy', 'delete', 'term', $term);
-      drupal_set_message(t('Deleted term %name.', array('%name' => '<em>'. $term->name .'</em>')));
+      drupal_set_message(t('Deleted term %name.', array('%name' => theme('placeholder', $term->name))));
     }
 
     $tids = $orphans;
@@ -331,7 +331,7 @@ function _taxonomy_confirm_del_term($tid) {
   $extra .= form_hidden('tid', $tid);
 
   $output = theme('confirm',
-                  t('Are you sure you want to delete the term %title?', array('%title' => '<em>'. $term->name .'</em>')),
+                  t('Are you sure you want to delete the term %title?', array('%title' => theme('placeholder', $term->name))),
                   'admin/taxonomy',
                   t('Deleting a term will delete all its children if there are any. This action cannot be undone.'),
                   t('Delete'),
@@ -357,13 +357,13 @@ function taxonomy_overview() {
         $types[] = $node_type ? $node_type : $type;
       }
 
-      $rows[] = array($vocabulary->name, implode(', ', $types), l(t('edit vocabulary'), "admin/taxonomy/edit/vocabulary/$vocabulary->vid"), l(t('add term'), "admin/taxonomy/add/term/$vocabulary->vid"), l(t('preview form'), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
+      $rows[] = array(check_plain($vocabulary->name), implode(', ', $types), l(t('edit vocabulary'), "admin/taxonomy/edit/vocabulary/$vocabulary->vid"), l(t('add term'), "admin/taxonomy/add/term/$vocabulary->vid"), l(t('preview form'), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
 
       $tree = taxonomy_get_tree($vocabulary->vid);
       if ($tree) {
         unset($data);
       foreach ($tree as $term) {
-        $data .= _taxonomy_depth($term->depth) .' '. $term->name .' ('. l(t('edit term'), "admin/taxonomy/edit/term/$term->tid") .')<br />';
+        $data .= _taxonomy_depth($term->depth) .' '. check_plain($term->name) .' ('. l(t('edit term'), "admin/taxonomy/edit/term/$term->tid") .')<br />';
       }
       $rows[] = array(array('data' => $data, 'colspan' => '5'));
       }
@@ -390,7 +390,7 @@ function taxonomy_form($vid, $value = 0, $help = NULL, $name = 'taxonomy') {
     $blank = '<'. t('none') .'>';
   }
 
-  return _taxonomy_term_select($vocabulary->name, $name, $value, $vid, $help, intval($vocabulary->multiple), $blank);
+  return _taxonomy_term_select(check_plain($vocabulary->name), $name, $value, $vid, $help, intval($vocabulary->multiple), $blank);
 }
 
 /**
diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module
index 17de7a520b03..9ebc1aebf841 100644
--- a/modules/taxonomy/taxonomy.module
+++ b/modules/taxonomy/taxonomy.module
@@ -130,7 +130,7 @@ function taxonomy_save_vocabulary($edit) {
       db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $edit['vid'], $type);
     }
     module_invoke_all('taxonomy', 'update', 'vocabulary', $edit);
-    $message = t('Updated vocabulary %name.', array('%name' => '<em>'. $edit['name'] .'</em>'));
+    $message = t('Updated vocabulary %name.', array('%name' => theme('placeholder', $edit['name'])));
   }
   else if ($edit['vid']) {
     $message = taxonomy_del_vocabulary($edit['vid']);
@@ -142,7 +142,7 @@ function taxonomy_save_vocabulary($edit) {
       db_query("INSERT INTO {vocabulary_node_types} (vid, type) VALUES (%d, '%s')", $edit['vid'], $type);
     }
     module_invoke_all('taxonomy', 'insert', 'vocabulary', $edit);
-    $message = t('Created new vocabulary %name.', array('%name' => '<em>'. $edit['name'] .'</em>'));
+    $message = t('Created new vocabulary %name.', array('%name' => theme('placeholder', $edit['name'])));
   }
 
   cache_clear_all();
@@ -236,7 +236,7 @@ function taxonomy_save_term($edit) {
 
     db_query('UPDATE {term_data} SET '. _taxonomy_prepare_update($data) .' WHERE tid = %d', $edit['tid']);
     module_invoke_all('taxonomy', 'update', 'term', $edit);
-    $message = t('The term %term has been updated.', array('%term' => '<em>'. $edit['name'] .'</em>'));
+    $message = t('The term %term has been updated.', array('%term' => theme('placeholder', $edit['name'])));
   }
   else if ($edit['tid']) {
     return taxonomy_del_term($edit['tid']);
@@ -246,7 +246,7 @@ function taxonomy_save_term($edit) {
     $data = array('tid' => $edit['tid'], 'name' => $edit['name'], 'description' => $edit['description'], 'vid' => $edit['vid'], 'weight' => $edit['weight']);
     db_query('INSERT INTO {term_data} '. _taxonomy_prepare_insert($data, 1) .' VALUES '. _taxonomy_prepare_insert($data, 2));
     module_invoke_all('taxonomy', 'insert', 'term', $edit);
-    $message = t('Created new term %term.', array('%term' => '<em>'. $edit['name'] .'</em>'));
+    $message = t('Created new term %term.', array('%term' => theme('placeholder', $edit['name'])));
   }
 
   db_query('DELETE FROM {term_relation} WHERE tid1 = %d OR tid2 = %d', $edit['tid'], $edit['tid']);
@@ -315,7 +315,7 @@ function taxonomy_del_term($tid) {
       db_query('DELETE FROM {term_node} WHERE tid = %d', $tid);
 
       module_invoke_all('taxonomy', 'delete', 'term', $term);
-      drupal_set_message(t('Deleted term %name.', array('%name' => '<em>'. $term->name .'</em>')));
+      drupal_set_message(t('Deleted term %name.', array('%name' => theme('placeholder', $term->name))));
     }
 
     $tids = $orphans;
@@ -331,7 +331,7 @@ function _taxonomy_confirm_del_term($tid) {
   $extra .= form_hidden('tid', $tid);
 
   $output = theme('confirm',
-                  t('Are you sure you want to delete the term %title?', array('%title' => '<em>'. $term->name .'</em>')),
+                  t('Are you sure you want to delete the term %title?', array('%title' => theme('placeholder', $term->name))),
                   'admin/taxonomy',
                   t('Deleting a term will delete all its children if there are any. This action cannot be undone.'),
                   t('Delete'),
@@ -357,13 +357,13 @@ function taxonomy_overview() {
         $types[] = $node_type ? $node_type : $type;
       }
 
-      $rows[] = array($vocabulary->name, implode(', ', $types), l(t('edit vocabulary'), "admin/taxonomy/edit/vocabulary/$vocabulary->vid"), l(t('add term'), "admin/taxonomy/add/term/$vocabulary->vid"), l(t('preview form'), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
+      $rows[] = array(check_plain($vocabulary->name), implode(', ', $types), l(t('edit vocabulary'), "admin/taxonomy/edit/vocabulary/$vocabulary->vid"), l(t('add term'), "admin/taxonomy/add/term/$vocabulary->vid"), l(t('preview form'), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
 
       $tree = taxonomy_get_tree($vocabulary->vid);
       if ($tree) {
         unset($data);
       foreach ($tree as $term) {
-        $data .= _taxonomy_depth($term->depth) .' '. $term->name .' ('. l(t('edit term'), "admin/taxonomy/edit/term/$term->tid") .')<br />';
+        $data .= _taxonomy_depth($term->depth) .' '. check_plain($term->name) .' ('. l(t('edit term'), "admin/taxonomy/edit/term/$term->tid") .')<br />';
       }
       $rows[] = array(array('data' => $data, 'colspan' => '5'));
       }
@@ -390,7 +390,7 @@ function taxonomy_form($vid, $value = 0, $help = NULL, $name = 'taxonomy') {
     $blank = '<'. t('none') .'>';
   }
 
-  return _taxonomy_term_select($vocabulary->name, $name, $value, $vid, $help, intval($vocabulary->multiple), $blank);
+  return _taxonomy_term_select(check_plain($vocabulary->name), $name, $value, $vid, $help, intval($vocabulary->multiple), $blank);
 }
 
 /**
diff --git a/modules/upload.module b/modules/upload.module
index e6cbae3fc254..768092136a3c 100644
--- a/modules/upload.module
+++ b/modules/upload.module
@@ -169,7 +169,7 @@ function upload_nodeapi(&$node, $op, $arg) {
         $total_usersize = upload_count_size($user->uid) + $filesize;
 
         if ($maxsize && $total_size > $maxsize) {
-          form_set_error('upload', t('Error attaching file %name: total file size exceeded', array('%name' => "<em>$file->filename</em>")));
+          form_set_error('upload', t('Error attaching file %name: total file size exceeded', array('%name' => theme('placeholder', $file->filename))));
           break;
         }
 
@@ -207,13 +207,13 @@ function upload_nodeapi(&$node, $op, $arg) {
         }
 
         if ($error['extension'] == count($user->roles) && $user->uid != 1) {
-          form_set_error('upload', t('Error attaching file %name: invalid extension', array('%name' => "<em>$file->filename</em>")));
+          form_set_error('upload', t('Error attaching file %name: invalid extension', array('%name' => theme('placeholder', $file->filename))));
         }
         elseif ($error['uploadsize'] == count($user->roles) && $user->uid != 1) {
-          form_set_error('upload', t('Error attaching file %name: exceeds maximum file size', array('%name' => "<em>$file->filename</em>")));
+          form_set_error('upload', t('Error attaching file %name: exceeds maximum file size', array('%name' => theme('placeholder', $file->filename))));
         }
         elseif ($error['usersize'] == count($user->roles) && $user->uid != 1) {
-          form_set_error('upload', t('Error attaching file %name: exceeds maximum file size', array('%name' => "<em>$file->filename</em>")));
+          form_set_error('upload', t('Error attaching file %name: exceeds maximum file size', array('%name' => theme('placeholder', $file->filename))));
         }
         else {
           $key = 'upload_'. count($_SESSION['file_uploads']);
diff --git a/modules/upload/upload.module b/modules/upload/upload.module
index e6cbae3fc254..768092136a3c 100644
--- a/modules/upload/upload.module
+++ b/modules/upload/upload.module
@@ -169,7 +169,7 @@ function upload_nodeapi(&$node, $op, $arg) {
         $total_usersize = upload_count_size($user->uid) + $filesize;
 
         if ($maxsize && $total_size > $maxsize) {
-          form_set_error('upload', t('Error attaching file %name: total file size exceeded', array('%name' => "<em>$file->filename</em>")));
+          form_set_error('upload', t('Error attaching file %name: total file size exceeded', array('%name' => theme('placeholder', $file->filename))));
           break;
         }
 
@@ -207,13 +207,13 @@ function upload_nodeapi(&$node, $op, $arg) {
         }
 
         if ($error['extension'] == count($user->roles) && $user->uid != 1) {
-          form_set_error('upload', t('Error attaching file %name: invalid extension', array('%name' => "<em>$file->filename</em>")));
+          form_set_error('upload', t('Error attaching file %name: invalid extension', array('%name' => theme('placeholder', $file->filename))));
         }
         elseif ($error['uploadsize'] == count($user->roles) && $user->uid != 1) {
-          form_set_error('upload', t('Error attaching file %name: exceeds maximum file size', array('%name' => "<em>$file->filename</em>")));
+          form_set_error('upload', t('Error attaching file %name: exceeds maximum file size', array('%name' => theme('placeholder', $file->filename))));
         }
         elseif ($error['usersize'] == count($user->roles) && $user->uid != 1) {
-          form_set_error('upload', t('Error attaching file %name: exceeds maximum file size', array('%name' => "<em>$file->filename</em>")));
+          form_set_error('upload', t('Error attaching file %name: exceeds maximum file size', array('%name' => theme('placeholder', $file->filename))));
         }
         else {
           $key = 'upload_'. count($_SESSION['file_uploads']);
diff --git a/modules/user.module b/modules/user.module
index 34caea9a0fc9..4e873303f898 100644
--- a/modules/user.module
+++ b/modules/user.module
@@ -216,13 +216,13 @@ function user_validate_name($name) {
   if (ereg('  ', $name)) return t('The username cannot contain multiple spaces in a row.');
   if (ereg("[^\x80-\xF7 [:alnum:]@_.-]", $name)) return t('The username contains an illegal character.');
   if (ereg('@', $name) && !eregi('@([0-9a-z](-?[0-9a-z])*.)+[a-z]{2}([zmuvtg]|fo|me)?$', $name)) return t('The username is not a valid authentication ID.');
-  if (strlen($name) > 56) return t('The username %name is too long: it must be less than 56 characters.', array('%name' => "<em>$name</em>"));
+  if (strlen($name) > 56) return t('The username %name is too long: it must be less than 56 characters.', array('%name' => theme('placeholder', $name)));
 }
 
 function user_validate_mail($mail) {
   if (!$mail) return t('You must enter an e-mail address.');
   if (!valid_email_address($mail)) {
-    return t('The e-mail address %mail is not valid.', array('%mail' => "<em>$mail</em>"));
+    return t('The e-mail address %mail is not valid.', array('%mail' => theme('placeholder', $mail)));
   }
 }
 
@@ -262,7 +262,7 @@ function user_validate_authmap($account, $authname, $module) {
   $result = db_query("SELECT COUNT(*) from {authmap} WHERE uid != %d AND authname = '%s'", $account->uid, $authname);
   if (db_result($result) > 0) {
     $name = module_invoke($module, 'info', 'name');
-    return t('The %u ID %s is already taken.', array('%u' => $name, '%s' => "<em>$authname</em>"));
+    return t('The %u ID %s is already taken.', array('%u' => $name, '%s' => theme('placeholder', $authname)));
   }
 }
 
@@ -594,7 +594,7 @@ function theme_user_picture($account) {
       $alt = t('%user\'s picture', array('%user' => $account->name ? $account->name : variable_get('anonymous', 'Anonymous')));
       $picture = theme('image', $picture, $alt, $alt, '', false);
       if ($account->uid) {
-        $picture = l($picture, "user/$account->uid", array('title' => t('View user profile.')));
+        $picture = l($picture, "user/$account->uid", array('title' => t('View user profile.')), NULL, NULL, FALSE, TRUE);
       }
 
       return "<div class=\"picture\">$picture</div>";
@@ -786,7 +786,7 @@ function user_login($edit = array(), $msg = '') {
   }
 
   if (user_deny('user', $edit['name'])) {
-    $error = t('The name %s has been denied access.', array('%s' => '<em>'. $edit['name'] .'</em>'));
+    $error = t('The name %s has been denied access.', array('%s' => theme('placeholder', $edit['name'])));
   }
   else if ($edit['name'] && $edit['pass']) {
 
@@ -795,7 +795,7 @@ function user_login($edit = array(), $msg = '') {
     }
 
     if ($user->uid) {
-      watchdog('user', t('Session opened for %name.', array('%name' => "<em>$user->name</em>")));
+      watchdog('user', t('Session opened for %name.', array('%name' => theme('placeholder', $user->name))));
 
       // Update the user table timestamp noting user has logged in.
       db_query("UPDATE {users} SET changed = '%d' WHERE uid = '%s'", time(), $user->uid);
@@ -807,9 +807,9 @@ function user_login($edit = array(), $msg = '') {
     }
     else {
       if (!$error) {
-        $error = t('Sorry.  Unrecognized username or password.') .' '. l(t('Have you forgotten your password?'), 'user/password');
+        $error = t('Sorry. Unrecognized username or password.') .' '. l(t('Have you forgotten your password?'), 'user/password');
       }
-      watchdog('user', t('Login attempt failed for %user: %error.', array('%user' => '<em>'. $edit['name'] .'</em>', '%error' => '<em>'. $error .'</em>')));
+      watchdog('user', t('Login attempt failed for %user: %error.', array('%user' => theme('placeholder', $edit['name']), '%error' => theme('placeholder', $error))));
     }
   }
 
@@ -851,10 +851,10 @@ function user_authenticate($name, $pass) {
   if (!$user->uid && $server && $result = user_get_authmaps("$name@$server")) {
     if (module_invoke(key($result), 'auth', $name, $pass, $server)) {
       $user = user_external_load("$name@$server");
-      watchdog('user', t('External load by %user using module %module.', array('%user' => "<em>$name@$server</em>", '%module' => '<em>'. key($result) .'</em>')));
+      watchdog('user', t('External load by %user using module %module.', array('%user' => theme('placeholder', $name .'@'. $server), '%module' => theme('placeholder', key($result)))));
     }
     else {
-      $error = t('Invalid password for %s.', array('%s' => "<em>$name@$server</em>"));
+      $error = t('Invalid password for %s.', array('%s' => theme('placeholder', $name .'@'. $server)));
     }
   }
 
@@ -868,7 +868,7 @@ function user_authenticate($name, $pass) {
             $account = user_load(array('name' => "$name@$server"));
             if (!$account->uid) { // Register this new user.
               $user = user_save('', array('name' => "$name@$server", 'pass' => user_password(), 'init' => "$name@$server", 'status' => 1, "authname_$module" => "$name@$server", 'roles' => array(_user_authenticated_id())));
-              watchdog('user', t('New external user: %user using module %module.', array('%user' => "<em>$name@$server</em>", '%module' => "<em>$module</em>")), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
+              watchdog('user', t('New external user: %user using module %module.', array('%user' => theme('placeholder', $name .'@'. $server), '%module' => theme('placeholder', $module))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
               break;
             }
           }
@@ -889,7 +889,7 @@ function _user_authenticated_id() {
 function user_logout() {
   global $user;
 
-  watchdog('user', t('Session closed for %name.', array('%name' => '<em>'. $user->name .'</em>')));
+  watchdog('user', t('Session closed for %name.', array('%name' => theme('placeholder', $user->name))));
 
   // Destroy the current session:
   session_destroy();
@@ -904,10 +904,10 @@ function user_pass() {
   $edit = $_POST['edit'];
 
   if ($edit['name'] && !($account = user_load(array('name' => $edit['name'], 'status' => 1)))) {
-    form_set_error('name', t('Sorry. The username %name is not recognized.', array('%name' => '<em>'. $edit['name'] .'</em>')));
+    form_set_error('name', t('Sorry. The username %name is not recognized.', array('%name' => theme('placeholder', $edit['name']))));
   }
   else if ($edit['mail'] && !($account = user_load(array('mail' => $edit['mail'], 'status' => 1)))) {
-    form_set_error('mail', t('Sorry. The e-mail address %email is not recognized.', array('%email' => '<em>'. $edit['mail'] .'</em>')));
+    form_set_error('mail', t('Sorry. The e-mail address %email is not recognized.', array('%email' => theme('placeholder', $edit['mail']))));
   }
   if ($account) {
     $from = variable_get('site_mail', ini_get('sendmail_from'));
@@ -924,11 +924,11 @@ function user_pass() {
     $mail_success = user_mail($account->mail, $subject, $body, $headers);
 
     if ($mail_success) {
-      watchdog('user', t('Password mailed to %name at %email.', array('%name' => '<em>'. $account->name .'</em>', '%email' => '<em>'. $account->mail .'</em>')));
+      watchdog('user', t('Password mailed to %name at %email.', array('%name' => theme('placeholder', $account->mail))));
       drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.'));
     }
     else {
-      watchdog('user', t('Error mailing password to %name at %email.', array('%name' => '<em>'. $account->name .'</em>', '%email' => '<em>'. $account->mail .'</em>')), WATCHDOG_ERROR);
+      watchdog('user', t('Error mailing password to %name at %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', $account->mail))), WATCHDOG_ERROR);
       drupal_set_message(t('Unable to send mail. Please contact the site admin.'));
     }
     drupal_goto('user');
@@ -964,7 +964,7 @@ function user_register($edit = array()) {
       // TODO: Is this necessary? Won't session_write() replicate this?
       unset($edit['session']);
       $account = user_save('', array_merge(array('name' => $edit['name'], 'pass' => $pass, 'init' => $edit['mail'], 'mail' => $edit['mail'], 'roles' => array(_user_authenticated_id()), 'status' => (variable_get('user_register', 1) == 1 ? 1 : 0)), $edit));
-      watchdog('user', t('New user: %name %email.', array('%name' => '<em>'. $edit['name'] .'</em>', '%email' => '<em>&lt;'. $edit['mail'] .'&gt;</em>')), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
+      watchdog('user', t('New user: %name %email.', array('%name' => theme('placeholder', $edit['name']), '%email' => theme('placeholder', '<'. $edit['mail'] .'>'))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
 
       $variables = array('%username' => $edit['name'], '%site' => variable_get('site_name', 'drupal'), '%password' => $pass, '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $edit['mail'], '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE));
 
@@ -1057,10 +1057,10 @@ function user_edit_validate($uid, &$edit) {
     form_set_error('name', $error);
   }
   else if (db_num_rows(db_query("SELECT uid FROM {users} WHERE uid != %d AND LOWER(name) = LOWER('%s')", $uid, $edit['name'])) > 0) {
-    form_set_error('name', t('The name %name is already taken.', array('%name' => '<em>'. $edit['name'] .'</em>')));
+    form_set_error('name', t('The name %name is already taken.', array('%name' => theme('placeholder', $edit['name']))));
   }
   else if (user_deny('user', $edit['name'])) {
-    form_set_error('name', t('The name %name has been denied access.', array('%name' => '<em>'. $edit['name'] .'</em>')));
+    form_set_error('name', t('The name %name has been denied access.', array('%name' => theme('placeholder', $edit['name']))));
   }
 
   // Validate the e-mail address:
@@ -1068,10 +1068,10 @@ function user_edit_validate($uid, &$edit) {
     form_set_error('mail', $error);
   }
   else if (db_num_rows(db_query("SELECT uid FROM {users} WHERE uid != %d AND LOWER(mail) = LOWER('%s')", $uid, $edit['mail'])) > 0) {
-    form_set_error('mail', t('The e-mail address %email is already taken.', array('%email' => '<em>'. $edit['mail'] .'</em>')));
+    form_set_error('mail', t('The e-mail address %email is already taken.', array('%email' => theme('placeholder', $edit['mail']))));
   }
   else if (user_deny('mail', $edit['mail'])) {
-    form_set_error('mail', t('The e-mail address %email has been denied access.', array('%email' => '<em>'. $edit['mail'] .'</em>')));
+    form_set_error('mail', t('The e-mail address %email has been denied access.', array('%email' => theme('placeholder', $edit['mail']))));
   }
 
   // Validate the user roles:
@@ -1150,7 +1150,7 @@ function user_edit($category = 'account') {
     }
     else {
       $output = theme('confirm',
-                      t('Are you sure you want to delete the account %name?', array('%name' => '<em>'. $account->name .'</em>')),
+                      t('Are you sure you want to delete the account %name?', array('%name' => theme('placeholder', $account->name))),
                       'user/'. $account->uid,
                       t('Deleting a user will remove all their submissions as well. This action cannot be undone.'),
                       t('Delete'));
@@ -1296,11 +1296,11 @@ function user_admin_create($edit = array()) {
     user_module_invoke('validate', $edit, $edit, 'account');
 
     if (!form_get_errors()) {
-      watchdog('user', t('New user: %name %email.', array('%name' => '<em>'. $edit['name'] .'</em>', '%email' => '<em>&lt;'. $edit['mail'] .'&gt;</em>')));
+      watchdog('user', t('New user: %name %email.', array('%name' => theme('placeholder', $edit['name']), '%email' => theme('placeholder', '<'. $edit['mail'] .'>'))));
 
       user_save('', array('name' => $edit['name'], 'pass' => $edit['pass'], 'init' => $edit['mail'], 'mail' => $edit['mail'], 'roles' => $edit['roles'], 'status' => 1));
 
-      drupal_set_message(t('Created a new user account.  No e-mail has been sent.'));
+      drupal_set_message(t('Created a new user account. No e-mail has been sent.'));
 
       return;
     }
@@ -1327,10 +1327,10 @@ function user_admin_access_check() {
 
   if ($op) {
     if (user_deny($edit['type'], $edit['test'])) {
-      drupal_set_message(t('%test is not allowed.', array('%test' => '<em>'. $edit['test'] .'</em>')));
+      drupal_set_message(t('%test is not allowed.', array('%test' => theme('placeholder', $edit['test']))));
     }
     else {
-      drupal_set_message(t('%test is allowed.', array('%test' => '<em>'. $edit['test'] .'</em>')));
+      drupal_set_message(t('%test is allowed.', array('%test' => theme('placeholder', $edit['test']))));
     }
   }
 
@@ -1383,7 +1383,7 @@ function user_admin_access_delete($aid = 0) {
     $edit = db_fetch_object(db_query('SELECT aid, type, status, mask FROM {access} WHERE aid = %d', $aid));
 
     $output = theme('confirm',
-                    t('Are you sure you want to delete the %type rule for %rule?', array('%type' => $access_types[$edit->type], '%rule' => '<em>'. $edit->mask .'</em>')),
+                    t('Are you sure you want to delete the %type rule for %rule?', array('%type' => $access_types[$edit->type], '%rule' => theme('placeholder', $edit->mask))),
                     'admin/access/rules',
                     t('This action cannot be undone.'),
                     t('Delete'),
@@ -1580,7 +1580,7 @@ function user_admin_role() {
     // Display the role form.
     $role = db_fetch_object(db_query('SELECT * FROM {role} WHERE rid = %d', $id));
 
-    $output .= form_textfield(t('Role name'), 'name', $role->name, 32, 64, t('The name for this role.  Example: "moderator", "editorial board", "site architect".'));
+    $output .= form_textfield(t('Role name'), 'name', $role->name, 32, 64, t('The name for this role. Example: "moderator", "editorial board", "site architect".'));
     $output .= form_submit(t('Save role'));
     $output .= form_submit(t('Delete role'));
 
@@ -1615,7 +1615,7 @@ function user_admin_account() {
     array('data' => t('Username'), 'field' => 'u.name'),
     array('data' => t('Status'), 'field' => 'u.status'),
     array('data' => t('Roles')),
-    array('data' => t('Last access'), 'field'  => 'u.changed', 'sort' => 'desc'),
+    array('data' => t('Last access'), 'field' => 'u.changed', 'sort' => 'desc'),
     t('Operations')
   );
   $sql = 'SELECT u.uid, u.name, u.status, u.changed FROM {users} u WHERE uid != 0';
diff --git a/modules/user/user.module b/modules/user/user.module
index 34caea9a0fc9..4e873303f898 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -216,13 +216,13 @@ function user_validate_name($name) {
   if (ereg('  ', $name)) return t('The username cannot contain multiple spaces in a row.');
   if (ereg("[^\x80-\xF7 [:alnum:]@_.-]", $name)) return t('The username contains an illegal character.');
   if (ereg('@', $name) && !eregi('@([0-9a-z](-?[0-9a-z])*.)+[a-z]{2}([zmuvtg]|fo|me)?$', $name)) return t('The username is not a valid authentication ID.');
-  if (strlen($name) > 56) return t('The username %name is too long: it must be less than 56 characters.', array('%name' => "<em>$name</em>"));
+  if (strlen($name) > 56) return t('The username %name is too long: it must be less than 56 characters.', array('%name' => theme('placeholder', $name)));
 }
 
 function user_validate_mail($mail) {
   if (!$mail) return t('You must enter an e-mail address.');
   if (!valid_email_address($mail)) {
-    return t('The e-mail address %mail is not valid.', array('%mail' => "<em>$mail</em>"));
+    return t('The e-mail address %mail is not valid.', array('%mail' => theme('placeholder', $mail)));
   }
 }
 
@@ -262,7 +262,7 @@ function user_validate_authmap($account, $authname, $module) {
   $result = db_query("SELECT COUNT(*) from {authmap} WHERE uid != %d AND authname = '%s'", $account->uid, $authname);
   if (db_result($result) > 0) {
     $name = module_invoke($module, 'info', 'name');
-    return t('The %u ID %s is already taken.', array('%u' => $name, '%s' => "<em>$authname</em>"));
+    return t('The %u ID %s is already taken.', array('%u' => $name, '%s' => theme('placeholder', $authname)));
   }
 }
 
@@ -594,7 +594,7 @@ function theme_user_picture($account) {
       $alt = t('%user\'s picture', array('%user' => $account->name ? $account->name : variable_get('anonymous', 'Anonymous')));
       $picture = theme('image', $picture, $alt, $alt, '', false);
       if ($account->uid) {
-        $picture = l($picture, "user/$account->uid", array('title' => t('View user profile.')));
+        $picture = l($picture, "user/$account->uid", array('title' => t('View user profile.')), NULL, NULL, FALSE, TRUE);
       }
 
       return "<div class=\"picture\">$picture</div>";
@@ -786,7 +786,7 @@ function user_login($edit = array(), $msg = '') {
   }
 
   if (user_deny('user', $edit['name'])) {
-    $error = t('The name %s has been denied access.', array('%s' => '<em>'. $edit['name'] .'</em>'));
+    $error = t('The name %s has been denied access.', array('%s' => theme('placeholder', $edit['name'])));
   }
   else if ($edit['name'] && $edit['pass']) {
 
@@ -795,7 +795,7 @@ function user_login($edit = array(), $msg = '') {
     }
 
     if ($user->uid) {
-      watchdog('user', t('Session opened for %name.', array('%name' => "<em>$user->name</em>")));
+      watchdog('user', t('Session opened for %name.', array('%name' => theme('placeholder', $user->name))));
 
       // Update the user table timestamp noting user has logged in.
       db_query("UPDATE {users} SET changed = '%d' WHERE uid = '%s'", time(), $user->uid);
@@ -807,9 +807,9 @@ function user_login($edit = array(), $msg = '') {
     }
     else {
       if (!$error) {
-        $error = t('Sorry.  Unrecognized username or password.') .' '. l(t('Have you forgotten your password?'), 'user/password');
+        $error = t('Sorry. Unrecognized username or password.') .' '. l(t('Have you forgotten your password?'), 'user/password');
       }
-      watchdog('user', t('Login attempt failed for %user: %error.', array('%user' => '<em>'. $edit['name'] .'</em>', '%error' => '<em>'. $error .'</em>')));
+      watchdog('user', t('Login attempt failed for %user: %error.', array('%user' => theme('placeholder', $edit['name']), '%error' => theme('placeholder', $error))));
     }
   }
 
@@ -851,10 +851,10 @@ function user_authenticate($name, $pass) {
   if (!$user->uid && $server && $result = user_get_authmaps("$name@$server")) {
     if (module_invoke(key($result), 'auth', $name, $pass, $server)) {
       $user = user_external_load("$name@$server");
-      watchdog('user', t('External load by %user using module %module.', array('%user' => "<em>$name@$server</em>", '%module' => '<em>'. key($result) .'</em>')));
+      watchdog('user', t('External load by %user using module %module.', array('%user' => theme('placeholder', $name .'@'. $server), '%module' => theme('placeholder', key($result)))));
     }
     else {
-      $error = t('Invalid password for %s.', array('%s' => "<em>$name@$server</em>"));
+      $error = t('Invalid password for %s.', array('%s' => theme('placeholder', $name .'@'. $server)));
     }
   }
 
@@ -868,7 +868,7 @@ function user_authenticate($name, $pass) {
             $account = user_load(array('name' => "$name@$server"));
             if (!$account->uid) { // Register this new user.
               $user = user_save('', array('name' => "$name@$server", 'pass' => user_password(), 'init' => "$name@$server", 'status' => 1, "authname_$module" => "$name@$server", 'roles' => array(_user_authenticated_id())));
-              watchdog('user', t('New external user: %user using module %module.', array('%user' => "<em>$name@$server</em>", '%module' => "<em>$module</em>")), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
+              watchdog('user', t('New external user: %user using module %module.', array('%user' => theme('placeholder', $name .'@'. $server), '%module' => theme('placeholder', $module))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
               break;
             }
           }
@@ -889,7 +889,7 @@ function _user_authenticated_id() {
 function user_logout() {
   global $user;
 
-  watchdog('user', t('Session closed for %name.', array('%name' => '<em>'. $user->name .'</em>')));
+  watchdog('user', t('Session closed for %name.', array('%name' => theme('placeholder', $user->name))));
 
   // Destroy the current session:
   session_destroy();
@@ -904,10 +904,10 @@ function user_pass() {
   $edit = $_POST['edit'];
 
   if ($edit['name'] && !($account = user_load(array('name' => $edit['name'], 'status' => 1)))) {
-    form_set_error('name', t('Sorry. The username %name is not recognized.', array('%name' => '<em>'. $edit['name'] .'</em>')));
+    form_set_error('name', t('Sorry. The username %name is not recognized.', array('%name' => theme('placeholder', $edit['name']))));
   }
   else if ($edit['mail'] && !($account = user_load(array('mail' => $edit['mail'], 'status' => 1)))) {
-    form_set_error('mail', t('Sorry. The e-mail address %email is not recognized.', array('%email' => '<em>'. $edit['mail'] .'</em>')));
+    form_set_error('mail', t('Sorry. The e-mail address %email is not recognized.', array('%email' => theme('placeholder', $edit['mail']))));
   }
   if ($account) {
     $from = variable_get('site_mail', ini_get('sendmail_from'));
@@ -924,11 +924,11 @@ function user_pass() {
     $mail_success = user_mail($account->mail, $subject, $body, $headers);
 
     if ($mail_success) {
-      watchdog('user', t('Password mailed to %name at %email.', array('%name' => '<em>'. $account->name .'</em>', '%email' => '<em>'. $account->mail .'</em>')));
+      watchdog('user', t('Password mailed to %name at %email.', array('%name' => theme('placeholder', $account->mail))));
       drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.'));
     }
     else {
-      watchdog('user', t('Error mailing password to %name at %email.', array('%name' => '<em>'. $account->name .'</em>', '%email' => '<em>'. $account->mail .'</em>')), WATCHDOG_ERROR);
+      watchdog('user', t('Error mailing password to %name at %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', $account->mail))), WATCHDOG_ERROR);
       drupal_set_message(t('Unable to send mail. Please contact the site admin.'));
     }
     drupal_goto('user');
@@ -964,7 +964,7 @@ function user_register($edit = array()) {
       // TODO: Is this necessary? Won't session_write() replicate this?
       unset($edit['session']);
       $account = user_save('', array_merge(array('name' => $edit['name'], 'pass' => $pass, 'init' => $edit['mail'], 'mail' => $edit['mail'], 'roles' => array(_user_authenticated_id()), 'status' => (variable_get('user_register', 1) == 1 ? 1 : 0)), $edit));
-      watchdog('user', t('New user: %name %email.', array('%name' => '<em>'. $edit['name'] .'</em>', '%email' => '<em>&lt;'. $edit['mail'] .'&gt;</em>')), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
+      watchdog('user', t('New user: %name %email.', array('%name' => theme('placeholder', $edit['name']), '%email' => theme('placeholder', '<'. $edit['mail'] .'>'))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
 
       $variables = array('%username' => $edit['name'], '%site' => variable_get('site_name', 'drupal'), '%password' => $pass, '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $edit['mail'], '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE));
 
@@ -1057,10 +1057,10 @@ function user_edit_validate($uid, &$edit) {
     form_set_error('name', $error);
   }
   else if (db_num_rows(db_query("SELECT uid FROM {users} WHERE uid != %d AND LOWER(name) = LOWER('%s')", $uid, $edit['name'])) > 0) {
-    form_set_error('name', t('The name %name is already taken.', array('%name' => '<em>'. $edit['name'] .'</em>')));
+    form_set_error('name', t('The name %name is already taken.', array('%name' => theme('placeholder', $edit['name']))));
   }
   else if (user_deny('user', $edit['name'])) {
-    form_set_error('name', t('The name %name has been denied access.', array('%name' => '<em>'. $edit['name'] .'</em>')));
+    form_set_error('name', t('The name %name has been denied access.', array('%name' => theme('placeholder', $edit['name']))));
   }
 
   // Validate the e-mail address:
@@ -1068,10 +1068,10 @@ function user_edit_validate($uid, &$edit) {
     form_set_error('mail', $error);
   }
   else if (db_num_rows(db_query("SELECT uid FROM {users} WHERE uid != %d AND LOWER(mail) = LOWER('%s')", $uid, $edit['mail'])) > 0) {
-    form_set_error('mail', t('The e-mail address %email is already taken.', array('%email' => '<em>'. $edit['mail'] .'</em>')));
+    form_set_error('mail', t('The e-mail address %email is already taken.', array('%email' => theme('placeholder', $edit['mail']))));
   }
   else if (user_deny('mail', $edit['mail'])) {
-    form_set_error('mail', t('The e-mail address %email has been denied access.', array('%email' => '<em>'. $edit['mail'] .'</em>')));
+    form_set_error('mail', t('The e-mail address %email has been denied access.', array('%email' => theme('placeholder', $edit['mail']))));
   }
 
   // Validate the user roles:
@@ -1150,7 +1150,7 @@ function user_edit($category = 'account') {
     }
     else {
       $output = theme('confirm',
-                      t('Are you sure you want to delete the account %name?', array('%name' => '<em>'. $account->name .'</em>')),
+                      t('Are you sure you want to delete the account %name?', array('%name' => theme('placeholder', $account->name))),
                       'user/'. $account->uid,
                       t('Deleting a user will remove all their submissions as well. This action cannot be undone.'),
                       t('Delete'));
@@ -1296,11 +1296,11 @@ function user_admin_create($edit = array()) {
     user_module_invoke('validate', $edit, $edit, 'account');
 
     if (!form_get_errors()) {
-      watchdog('user', t('New user: %name %email.', array('%name' => '<em>'. $edit['name'] .'</em>', '%email' => '<em>&lt;'. $edit['mail'] .'&gt;</em>')));
+      watchdog('user', t('New user: %name %email.', array('%name' => theme('placeholder', $edit['name']), '%email' => theme('placeholder', '<'. $edit['mail'] .'>'))));
 
       user_save('', array('name' => $edit['name'], 'pass' => $edit['pass'], 'init' => $edit['mail'], 'mail' => $edit['mail'], 'roles' => $edit['roles'], 'status' => 1));
 
-      drupal_set_message(t('Created a new user account.  No e-mail has been sent.'));
+      drupal_set_message(t('Created a new user account. No e-mail has been sent.'));
 
       return;
     }
@@ -1327,10 +1327,10 @@ function user_admin_access_check() {
 
   if ($op) {
     if (user_deny($edit['type'], $edit['test'])) {
-      drupal_set_message(t('%test is not allowed.', array('%test' => '<em>'. $edit['test'] .'</em>')));
+      drupal_set_message(t('%test is not allowed.', array('%test' => theme('placeholder', $edit['test']))));
     }
     else {
-      drupal_set_message(t('%test is allowed.', array('%test' => '<em>'. $edit['test'] .'</em>')));
+      drupal_set_message(t('%test is allowed.', array('%test' => theme('placeholder', $edit['test']))));
     }
   }
 
@@ -1383,7 +1383,7 @@ function user_admin_access_delete($aid = 0) {
     $edit = db_fetch_object(db_query('SELECT aid, type, status, mask FROM {access} WHERE aid = %d', $aid));
 
     $output = theme('confirm',
-                    t('Are you sure you want to delete the %type rule for %rule?', array('%type' => $access_types[$edit->type], '%rule' => '<em>'. $edit->mask .'</em>')),
+                    t('Are you sure you want to delete the %type rule for %rule?', array('%type' => $access_types[$edit->type], '%rule' => theme('placeholder', $edit->mask))),
                     'admin/access/rules',
                     t('This action cannot be undone.'),
                     t('Delete'),
@@ -1580,7 +1580,7 @@ function user_admin_role() {
     // Display the role form.
     $role = db_fetch_object(db_query('SELECT * FROM {role} WHERE rid = %d', $id));
 
-    $output .= form_textfield(t('Role name'), 'name', $role->name, 32, 64, t('The name for this role.  Example: "moderator", "editorial board", "site architect".'));
+    $output .= form_textfield(t('Role name'), 'name', $role->name, 32, 64, t('The name for this role. Example: "moderator", "editorial board", "site architect".'));
     $output .= form_submit(t('Save role'));
     $output .= form_submit(t('Delete role'));
 
@@ -1615,7 +1615,7 @@ function user_admin_account() {
     array('data' => t('Username'), 'field' => 'u.name'),
     array('data' => t('Status'), 'field' => 'u.status'),
     array('data' => t('Roles')),
-    array('data' => t('Last access'), 'field'  => 'u.changed', 'sort' => 'desc'),
+    array('data' => t('Last access'), 'field' => 'u.changed', 'sort' => 'desc'),
     t('Operations')
   );
   $sql = 'SELECT u.uid, u.name, u.status, u.changed FROM {users} u WHERE uid != 0';
diff --git a/themes/chameleon/chameleon.theme b/themes/chameleon/chameleon.theme
index 78d0cc5e3df2..86c774c10c94 100644
--- a/themes/chameleon/chameleon.theme
+++ b/themes/chameleon/chameleon.theme
@@ -18,10 +18,12 @@ function chameleon_features() {
 function chameleon_page($content) {
   $language = $GLOBALS['locale'];
 
+  $title = drupal_get_title();
+
   $output  = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
   $output .= "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"$language\" xml:lang=\"$language\">\n";
   $output .= "<head>\n";
-  $output .= " <title>". ($title ? $title ." | ". variable_get("site_name", "drupal") : variable_get("site_name", "drupal") ." | ". variable_get("site_slogan", "")) ."</title>\n";
+  $output .= " <title>". ($title ? strip_tags($title) ." | ". variable_get("site_name", "drupal") : variable_get("site_name", "drupal") ." | ". variable_get("site_slogan", "")) ."</title>\n";
   $output .= drupal_get_html_head();
   $output .= " <link rel=\"stylesheet\" type=\"text/css\" href=\"themes/chameleon/common.css\" />\n";
   $output .= theme_get_styles();
@@ -63,7 +65,7 @@ function chameleon_page($content) {
 
   $output .= "   <td id=\"main\">\n";
 
-  if ($title = drupal_get_title()) {
+  if ($title) {
     $output .= theme("breadcrumb", drupal_get_breadcrumb());
     $output .= "<h2>$title</h2>";
   }
@@ -107,7 +109,7 @@ function chameleon_node($node, $main = 0, $page = 0) {
   $output  = "<div class=\"node\">\n";
 
   if (!$page) {
-    $output .= " <h2 class=\"title\">". ($main ? l($node->title, "node/$node->nid") : $node->title) ."</h2>\n";
+    $output .= " <h2 class=\"title\">". ($main ? l($node->title, "node/$node->nid") : check_plain($node->title)) ."</h2>\n";
   }
 
   $output .= " <div class=\"content\">\n";
diff --git a/themes/engines/xtemplate/xtemplate.engine b/themes/engines/xtemplate/xtemplate.engine
index 0a5a16a43e93..c7bb12d18328 100644
--- a/themes/engines/xtemplate/xtemplate.engine
+++ b/themes/engines/xtemplate/xtemplate.engine
@@ -45,7 +45,7 @@ function xtemplate_node($node, $main = 0, $page = 0) {
                            array("%a" => format_name($node),
                             "%b" => format_date($node->created))) : '',
         "link"      => url("node/$node->nid"),
-        "title"     => $node->title,
+        "title"     => check_plain($node->title),
         "author"    => format_name($node),
         "date"      => format_date($node->created),
         "sticky"    => ($main && $node->sticky) ? 'sticky' : '',
@@ -116,7 +116,7 @@ function xtemplate_page($content) {
 
   $xtemplate->template->assign(array(
     "language" => $GLOBALS['locale'],
-    "head_title" => (drupal_get_title() ? drupal_get_title() ." | ". variable_get("site_name", "drupal") : variable_get("site_name", "drupal") ." | ". variable_get("site_slogan", "")),
+    "head_title" => (drupal_get_title() ? strip_tags(drupal_get_title()) ." | ". variable_get("site_name", "drupal") : variable_get("site_name", "drupal") ." | ". variable_get("site_slogan", "")),
     "head" => drupal_get_html_head(),
     "styles" => theme_get_styles(),
     "onload_attributes" => theme_onload_attribute(),
-- 
GitLab