Index: includes/locale.inc
===================================================================
RCS file: /Users/Shared/code/drupal/includes/locale.inc,v
retrieving revision 1.176
diff -u -p -r1.176 locale.inc
--- includes/locale.inc	26 May 2008 17:12:54 -0000	1.176
+++ includes/locale.inc	29 Jun 2008 03:07:30 -0000
@@ -667,7 +667,7 @@ function locale_translate_import_form_su
   }
   else {
     drupal_set_message(t('File to import not found.'), 'error');
-    return 'admin/build/translate/import';
+    $form_state['redirect'] = 'admin/build/translate/import';
   }
 
   $form_state['redirect'] = 'admin/build/translate';
@@ -828,7 +828,19 @@ function locale_translate_edit_form(&$fo
 }
 
 /**
+ * Validate string editing form submissions.
+ */
+function locale_translate_edit_form_validate($form, &$form_state) {
+  foreach ($form_state['values']['translations'] as $key => $value) {
+    if (decode_entities($value) != decode_entities(filter_xss($value, array('a', 'b', 'big', 'del', 'em', 'i', 'ins', 'pre', 'q', 'small', 'span', 'strong', 'sub', 'sup', 'tt', 'ol', 'ul', 'li', 'p', 'br')))) {
+      form_set_error('translations', t('The string you submitted is invalid - it may contain unsafe HTML.'));
+    }
+  }
+}
+
+/**
  * Process string editing form submissions.
+ *
  * Saves all translations of one string submitted from a form.
  */
 function locale_translate_edit_form_submit($form, &$form_state) {
@@ -1241,7 +1253,10 @@ function _locale_import_one_string($op, 
             if ($key == 0) {
               $plid = 0;
             }
-            $plid = _locale_import_one_string_db($report, $lang, $english[$key], $trans, $group, $comments, $mode, $plid, $key);
+            // Skip this string unless it passes a check for dangerous code.
+            if (decode_entities($trans) == decode_entities(filter_xss($trans, array('a', 'b', 'big', 'del', 'em', 'i', 'ins', 'pre', 'q', 'small', 'span', 'strong', 'sub', 'sup', 'tt', 'ol', 'ul', 'li', 'p', 'br')))) {
+              $plid = _locale_import_one_string_db($report, $lang, $english[$key], $trans, $group, $comments, $mode, $plid, $key);
+            }
           }
         }
 
@@ -1249,7 +1264,10 @@ function _locale_import_one_string($op, 
           // A simple string to import.
           $english = $value['msgid'];
           $translation = $value['msgstr'];
-          _locale_import_one_string_db($report, $lang, $english, $translation, $group, $comments, $mode);
+          // Skip this string unless it passes a check for dangerous code.
+          if (decode_entities($translation) == decode_entities(filter_xss($translation, array('a', 'b', 'big', 'del', 'em', 'i', 'ins', 'pre', 'q', 'small', 'span', 'strong', 'sub', 'sup', 'tt', 'ol', 'ul', 'li', 'p', 'br')))) {
+            _locale_import_one_string_db($report, $lang, $english, $translation, $group, $comments, $mode);
+          }
         }
       }
   } // end of db-store operation
Index: modules/locale/locale.test
===================================================================
RCS file: /Users/Shared/code/drupal/modules/locale/locale.test,v
retrieving revision 1.3
diff -u -p -r1.3 locale.test
--- modules/locale/locale.test	30 May 2008 07:30:51 -0000	1.3
+++ modules/locale/locale.test	29 Jun 2008 03:08:37 -0000
@@ -7,8 +7,8 @@ class LocaleTestCase extends DrupalWebTe
    */
   function getInfo() {
     return array(
-      'name' => t('String translate'),
-      'description' => 'Adds a new locale and translates its name',
+      'name' => t('String translate and validate'),
+      'description' => 'Adds a new locale and translates its name.  Checks the validation of translation strings.',
       'group' => 'Locale',
     );
   }
@@ -113,4 +113,62 @@ class LocaleTestCase extends DrupalWebTe
     $this->drupalPost('admin/build/translate/search', $search, t('Search'));
     $this->assertNoText($name, 'Search now can not find the name');
   }
+
+  function testLocaleStringTest() {
+    global $base_url;
+
+    // User to add  language and strings
+    $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages', 'translate interface'));
+    $this->drupalLogin($admin_user);
+    $langcode = str_replace('simpletest_', 'si-', $this->randomName(6));
+    // The English name for the language. This will be translated.
+    $name = $this->randomName(16);
+    // The native name for the language.
+    $native = $this->randomName(16);
+    // The domain prefix. Not tested yet.
+    $prefix = strtolower(str_replace('si-', '', $langcode));
+    // This is the language indicator on the translation search screen for
+    // untranslated strings. Copied straight from locale.inc.
+    $language_indicator = "<em class=\"locale-untranslated\">$langcode</em> ";
+    // These will be the invalid translations of $name.
+    $key = $this->randomName(16);
+    $bad_translations[$key] = "<script>alert('xss');</script>" . $key;
+    $key = $this->randomName(16);
+    $bad_translations[$key] = '<img SRC="javascript:alert(\'xss\');">' . $key;
+    $key = $this->randomName(16);
+    $bad_translations[$key] = '<<SCRIPT>alert("xss");//<</SCRIPT>' . $key;
+    $key = $this->randomName(16);
+    $bad_translations[$key] ="<BODY ONLOAD=alert('xss')>" . $key;
+
+    // Add language.
+    $edit = array (
+      'langcode' => $langcode,
+      'name' => $name,
+      'native' => $native,
+      'prefix' => $prefix,
+      'direction' => '0',
+    );
+    $this->drupalPost('admin/settings/language/add', $edit, t('Add custom language'));
+    // Add string.
+    t($name, array(), $langcode);
+    // Reset locale cache.
+    $search = array (
+      'string' => $name,
+      'language' => 'all',
+      'translation' => 'all',
+      'group' => 'all',
+    );
+    $this->drupalPost('admin/build/translate/search', $search, t('Search'));
+    // Find the edit path
+    $content = $this->drupalGetContent();
+    $this->assertTrue(preg_match('@(admin/build/translate/edit/[0-9]+)@', $content, $matches), 'Found the edit path');
+    $path = $matches[0];
+    foreach ($bad_translations as $key => $translation) {
+      $edit = array (
+        "translations[$langcode]" => $translation,
+      );
+      $this->drupalPost($path, $edit, t('Save translations'));
+      $this->assertText(t('The string you submitted is invalid'), 'The string was rejected as unsafe.');
+    }
+  }
 }
