diff --git a/includes/common.inc b/includes/common.inc
index 8575844..1218d22 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -4802,8 +4802,8 @@ function drupal_clear_js_cache() {
  * @ingroup php_wrappers
  */
 function drupal_json_encode($var) {
-  // json_encode() does not escape <, > and &, so we do it with str_replace().
-  return str_replace(array('<', '>', '&'), array('\u003c', '\u003e', '\u0026'), json_encode($var));
+  // json_encode() escapes <, >, ', " and & using its options parameter.
+  return json_encode($var, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
 }
 
 /**
diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test
index e50ba5e..d09ae1e 100644
--- a/modules/simpletest/tests/common.test
+++ b/modules/simpletest/tests/common.test
@@ -2316,9 +2316,10 @@ class DrupalJSONTest extends DrupalUnitTestCase {
     for ($i=0; $i < 128; $i++) {
       $str .= chr($i);
     }
+
     // Characters that must be escaped.
-    $html_unsafe = array('<', '>', '&');
-    $html_unsafe_escaped = array('\u003c', '\u003e', '\u0026');
+    $html_unsafe = array('<', '>', '\'', '&');
+    $html_unsafe_escaped = array('\u003C', '\u003E', '\u0027', '\u0026');
 
     // Verify there aren't character encoding problems with the source string.
     $this->assertIdentical(strlen($str), 128, t('A string with the full ASCII table has the correct length.'));
