diff --git a/core/includes/mail.inc b/core/includes/mail.inc
index f58a76e..369ee04 100644
--- a/core/includes/mail.inc
+++ b/core/includes/mail.inc
@@ -516,9 +516,9 @@ function drupal_html_to_text($string, $allowed_tags = NULL) {
  */
 function _drupal_wrap_mail_line(&$line, $key, $values) {
   // Use soft-breaks only for purely quoted or unindented text.
-  $line = wordwrap($line, 77 - $values['length'], $values['soft'] ? "  \n" : "\n");
+  $line = drupal_wordwrap($line, 77 - $values['length'], $values['soft'] ? "  \n" : "\n");
   // Break really long words at the maximum width allowed.
-  $line = wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n");
+  $line = drupal_wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n");
 }
 
 /**
diff --git a/core/includes/unicode.inc b/core/includes/unicode.inc
index 1450b43..f040385 100644
--- a/core/includes/unicode.inc
+++ b/core/includes/unicode.inc
@@ -602,3 +602,42 @@ function drupal_substr($text, $start, $length = NULL) {
     return substr($text, $istart, max(0, $iend - $istart + 1));
   }
 }
+
+/**
+ * Wraps a UTF-8 string to a given number of characters using a string break character.
+ */
+function drupal_wordwrap($str, $width = 75, $break = "\n", $cut = FALSE) {
+  $return = '';
+  if ($cut) {
+    while ($len = drupal_strlen($str)) {
+      $chunk = drupal_substr($str, 0, $width);
+      $return .= $chunk;
+      $str = ltrim(drupal_substr($str, $width, $len - $width));
+      if (drupal_strlen($str) > 0) {
+        $return .= $break;
+      }
+    }
+  }
+  else {
+    $str = preg_split('#\h+#u', $str);
+    $len = 0;
+    foreach ($str as $val) {
+      $val .= ' ';
+      $tmp = drupal_strlen($val);
+      $len += $tmp;
+      if ($len >= $width) {
+        // To avoid to have a white space at the end, trim the value before
+        // adding the break.
+        $return = trim($return);
+        $return .= $break . $val;
+        $len = $tmp;
+      }
+      else {
+        $return .= $val;
+      }
+    }
+  }
+  // A last trim to avoid the final white space that have been added during the
+  // process.
+  return trim($return);
+}
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index b21c64c..4af6c0f 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -400,7 +400,7 @@ function simpletest_generate_file($filename, $width, $lines, $type = 'binary-tex
         break;
     }
   }
-  $text = wordwrap($text, $width - 1, "\n", TRUE) . "\n"; // Add \n for symmetrical file.
+  $text = drupal_wordwrap($text, $width - 1, "\n", TRUE) . "\n"; // Add \n for symmetrical file.
 
   // Create filename.
   file_put_contents('public://' . $filename . '.txt', $text);
