[gjs/wip/ptomato/mozjs38: 5/26] jsapi-util: Use JS_PutEscapedString()



commit 2f1fb6a47c8a059ae2c91fae26cbd785ce92effe
Author: Philip Chimento <philip endlessm com>
Date:   Thu Jan 19 16:17:57 2017 -0800

    jsapi-util: Use JS_PutEscapedString()
    
    In gjs_string_readable(), instead of doing our own escaping of strings,
    we can use JS_PutEscapedString(). Since JS_GetStringCharsAndLength() is
    going away in SpiderMonkey 38, we have to change this code anyway.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=776966

 gjs/jsapi-util.cpp |   25 +++++++++++++------------
 test/gjs-tests.cpp |   44 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 54 insertions(+), 15 deletions(-)
---
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index cacf7dc..493bab4 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -377,18 +377,19 @@ gjs_string_readable (JSContext   *context,
     g_string_append_c(buf, '"');
 
     if (!gjs_string_to_utf8(context, JS::StringValue(string), &chars)) {
-        size_t i, len;
-        const char16_t *uchars;
-
-        uchars = JS_GetStringCharsAndLength(context, string, &len);
-
-        for (i = 0; i < len; i++) {
-            char16_t c = uchars[i];
-            if (c >> 8 == 0 && g_ascii_isprint(c & 0xFF))
-                g_string_append_c(buf, c & 0xFF);
-            else
-                g_string_append_printf(buf, "\\u%04X", c);
-        }
+        /* I'm not sure this code will actually ever be reached, since
+         * JS_EncodeStringToUTF8(), called internally by
+         * gjs_string_to_utf8(), seems to happily output non-valid UTF-8
+         * bytes. However, let's leave this in, since SpiderMonkey may
+         * decide to do this in the future. */
+
+        /* Find out size of buffer to allocate, not counting 0-terminator */
+        size_t len = JS_PutEscapedString(context, NULL, 0, string, '"');
+        char *escaped = g_new(char, len + 1);
+
+        JS_PutEscapedString(context, escaped, len, string, '"');
+        g_string_append(buf, escaped);
+        g_free(escaped);
     } else {
         g_string_append(buf, chars);
         g_free(chars);
diff --git a/test/gjs-tests.cpp b/test/gjs-tests.cpp
index 5111a76..ca5af1a 100644
--- a/test/gjs-tests.cpp
+++ b/test/gjs-tests.cpp
@@ -32,6 +32,8 @@
 #include "gjs-test-utils.h"
 #include "util/error.h"
 
+#define VALID_UTF8_STRING "\303\211\303\226 foobar \343\203\237"
+
 static void
 gjstest_test_func_gjs_context_construct_destroy(void)
 {
@@ -119,14 +121,13 @@ static void
 gjstest_test_func_gjs_jsapi_util_string_js_string_utf8(GjsUnitTestFixture *fx,
                                                        gconstpointer       unused)
 {
-    const char *utf8_string = "\303\211\303\226 foobar \343\203\237";
     char *utf8_result;
     JS::RootedValue js_string(fx->cx);
 
-    g_assert(gjs_string_from_utf8(fx->cx, utf8_string, -1, &js_string));
+    g_assert_true(gjs_string_from_utf8(fx->cx, VALID_UTF8_STRING, -1, &js_string));
     g_assert(js_string.isString());
     g_assert(gjs_string_to_utf8(fx->cx, js_string, &utf8_result));
-    g_assert(g_str_equal(utf8_string, utf8_result));
+    g_assert_cmpstr(VALID_UTF8_STRING, ==, utf8_result);
     g_free(utf8_result);
 }
 
@@ -179,6 +180,39 @@ gjstest_test_func_gjs_jsapi_util_error_throw(GjsUnitTestFixture *fx,
 }
 
 static void
+gjstest_test_func_gjs_jsapi_util_debug_string_valid_utf8(GjsUnitTestFixture *fx,
+                                                         gconstpointer       unused)
+{
+    JS::RootedValue v_string(fx->cx);
+    g_assert_true(gjs_string_from_utf8(fx->cx, VALID_UTF8_STRING, -1, &v_string));
+
+    char *debug_output = gjs_value_debug_string(fx->cx, v_string);
+
+    g_assert_nonnull(debug_output);
+    g_assert_cmpstr("\"" VALID_UTF8_STRING "\"", ==, debug_output);
+
+    g_free(debug_output);
+}
+
+static void
+gjstest_test_func_gjs_jsapi_util_debug_string_invalid_utf8(GjsUnitTestFixture *fx,
+                                                           gconstpointer       unused)
+{
+    g_test_skip("SpiderMonkey doesn't validate UTF-8 after encoding it");
+
+    JS::RootedValue v_string(fx->cx);
+    const char16_t invalid_unicode[] = { 0xffff, 0xffff };
+    v_string.setString(JS_NewUCStringCopyN(fx->cx, invalid_unicode, 2));
+
+    char *debug_output = gjs_value_debug_string(fx->cx, v_string);
+
+    g_assert_nonnull(debug_output);
+    /* g_assert_cmpstr("\"\\xf5\\xf6\"", ==, debug_output); */
+
+    g_free(debug_output);
+}
+
+static void
 gjstest_test_func_util_glib_strv_concat_null(void)
 {
     char **ret;
@@ -297,6 +331,10 @@ main(int    argc,
                         gjstest_test_func_gjs_jsapi_util_error_throw);
     ADD_JSAPI_UTIL_TEST("string/js/string/utf8",
                         gjstest_test_func_gjs_jsapi_util_string_js_string_utf8);
+    ADD_JSAPI_UTIL_TEST("debug_string/valid-utf8",
+                        gjstest_test_func_gjs_jsapi_util_debug_string_valid_utf8);
+    ADD_JSAPI_UTIL_TEST("debug_string/invalid-utf8",
+                        gjstest_test_func_gjs_jsapi_util_debug_string_invalid_utf8);
 
 #undef ADD_JSAPI_UTIL_TEST
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]