diff --git a/mollom.module b/mollom.module
index 33cfc2e..e2b9724 100644
--- a/mollom.module
+++ b/mollom.module
@@ -1129,15 +1129,25 @@ function mollom_form_get_values($form_values, $fields, $mapping) {
   // sanitized into an empty string, so the Mollom backend would not receive
   // any value.
   $valid_utf8 = TRUE;
+  $valid_xml = TRUE;
   foreach ($data as $key => $value) {
+    // Check for invalid UTF-8 byte sequences first.
     if (!drupal_validate_utf8($value)) {
       $valid_utf8 = FALSE;
+      $data[$key] = '- Invalid UTF-8 -';
+    }
+    // Since values are transmitted over XML-RPC and not merely output as
+    // (X)HTML, they have to be valid XML characters.
+    // @see http://www.w3.org/TR/2000/REC-xml-20001006#charsets
+    // @see http://drupal.org/node/882298
+    elseif (preg_match('@[^\x9\xA\xD\x20-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]@u', $value)) {
+      $valid_xml = FALSE;
     }
   }
-  if (!$valid_utf8) {
+  if (!$valid_utf8 || !$valid_xml) {
     form_set_error('mollom', t('Invalid form values. Your submission will not be accepted.'));
     _mollom_watchdog(array(
-      'Invalid UTF-8 in form values' => array(),
+      'Invalid !type in form values' => array('!type' => !$valid_utf8 ? 'UTF-8' : 'XML characters'),
       'Data:<pre>@data</pre>' => array('@data' => $data),
     ));
     $data = FALSE;
@@ -1901,18 +1911,20 @@ function _mollom_watchdog(array $parts, $severity = WATCHDOG_NOTICE) {
 
   // Prettify replacement token values, if possible.
   foreach ($arguments as $token => $array) {
-    $flat_value = FALSE;
-    if (is_array($array)) {
-      $flat_value = '';
-      foreach ($array as $key => $value) {
-        if (is_array($value)) {
-          $flat_value = FALSE;
-          break;
-        }
-        $value = var_export($value, TRUE);
-        // Indent the new value, so there is a visual separation from the last.
-        $flat_value .= "  {$key} = {$value}\n";
+    // Only try to prettify arrays and objects. All other values can be replaced
+    // as is.
+    if (is_scalar($array)) {
+      continue;
+    }
+    $flat_value = '';
+    foreach ($array as $key => $value) {
+      if (is_array($value)) {
+        $flat_value = FALSE;
+        break;
       }
+      $value = var_export($value, TRUE);
+      // Indent the new value, so there is a visual separation from the last.
+      $flat_value .= "  {$key} = {$value}\n";
     }
     // Only convert one-dimensional arrays, or we would lose debugging data.
     if ($flat_value !== FALSE) {
diff --git a/tests/mollom.test b/tests/mollom.test
index e04b5bf..92347cd 100644
--- a/tests/mollom.test
+++ b/tests/mollom.test
@@ -2691,6 +2691,20 @@ class MollomDataTestCase extends MollomWebTestCase {
     $this->assertFalse(isset($data['author_openid']), t('author_openid: Undefined.'));
     $this->assertSame('author_id', $data['author_id'], $this->admin_user->uid);
     $this->assertSame('author_ip', $data['author_ip'], ip_address());
+
+    // Verify that invalid UTF-8 is detected.
+    $values = array(
+      'subject' => "Foo \xC0 bar",
+    );
+    $data = mollom_form_get_values($values, $fields, $form_info['mapping']);
+    $this->assertFalse($data, 'Invalid UTF-8 detected.');
+
+    // Verify that invalid XML characters are detected.
+    $values = array(
+      'subject' => "Foo \x11 bar",
+    );
+    $data = mollom_form_get_values($values, $fields, $form_info['mapping']);
+    $this->assertFalse($data, 'Invalid XML characters detected.');
   }
 
   /**
