Title: [275039] releases/WebKitGTK/webkit-2.32
Revision
275039
Author
[email protected]
Date
2021-03-25 10:06:08 -0700 (Thu, 25 Mar 2021)

Log Message

Merge r275031 - [GTK][WPE] JSC crashes if a function expects a parameter but doesn't receive any
https://bugs.webkit.org/show_bug.cgi?id=223646

Reviewed by Adrian Perez de Castro.

Source/_javascript_Core:

Handle the case of receiving fewer argumens than expected in function calls and constructors. We pass undefined
for the expected arguments that are missing. We were not correctly handling the case of converting undefined and
null values to JSCValue, so this patch fixes that case too.

* API/glib/JSCCallbackFunction.cpp:
(JSC::JSCCallbackFunction::call):
(JSC::JSCCallbackFunction::construct):
* API/glib/JSCContext.cpp:
(jscContextJSValueToWrappedObject):
(jscContextJSValueToGValue):

Tools:

Add test cases.

* TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp:
(valueToString):
(testJSCFunction):
(testJSCClass):

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.32/Source/_javascript_Core/API/glib/JSCCallbackFunction.cpp (275038 => 275039)


--- releases/WebKitGTK/webkit-2.32/Source/_javascript_Core/API/glib/JSCCallbackFunction.cpp	2021-03-25 16:49:46 UTC (rev 275038)
+++ releases/WebKitGTK/webkit-2.32/Source/_javascript_Core/API/glib/JSCCallbackFunction.cpp	2021-03-25 17:06:08 UTC (rev 275039)
@@ -113,7 +113,7 @@
     // GClosure always expect to have at least the instance parameter.
     bool addInstance = instance || (m_parameters && m_parameters->isEmpty());
 
-    auto parameterCount = m_parameters ? std::min(m_parameters->size(), argumentCount) : 1;
+    auto parameterCount = m_parameters ? m_parameters->size() : 1;
     if (addInstance)
         parameterCount++;
     auto* values = static_cast<GValue*>(g_alloca(sizeof(GValue) * parameterCount));
@@ -126,8 +126,11 @@
         firstParameter = 1;
     }
     if (m_parameters) {
-        for (size_t i = firstParameter; i < parameterCount && !*exception; ++i)
-            jscContextJSValueToGValue(context.get(), arguments[i - firstParameter], m_parameters.value()[i - firstParameter], &values[i], exception);
+        for (size_t i = firstParameter; i < parameterCount && !*exception; ++i) {
+            auto argumentIndex = i - firstParameter;
+            jscContextJSValueToGValue(context.get(), argumentIndex < argumentCount ? arguments[argumentIndex] : JSValueMakeUndefined(jsContext),
+                m_parameters.value()[argumentIndex], &values[i], exception);
+        }
     } else {
         auto* parameters = g_ptr_array_new_full(argumentCount, g_object_unref);
         for (size_t i = 0; i < argumentCount; ++i)
@@ -182,13 +185,13 @@
         g_closure_invoke(m_closure.get(), &returnValue, 1, &dummyValue, nullptr);
         g_value_unset(&dummyValue);
     } else {
-        auto parameterCount = m_parameters ? std::min(m_parameters->size(), argumentCount) : 1;
+        auto parameterCount = m_parameters ? m_parameters->size() : 1;
         auto* values = static_cast<GValue*>(g_alloca(sizeof(GValue) * parameterCount));
         memset(values, 0, sizeof(GValue) * parameterCount);
 
         if (m_parameters) {
             for (size_t i = 0; i < parameterCount && !*exception; ++i)
-                jscContextJSValueToGValue(context.get(), arguments[i], m_parameters.value()[i], &values[i], exception);
+                jscContextJSValueToGValue(context.get(), i < argumentCount ? arguments[i] : JSValueMakeUndefined(jsContext), m_parameters.value()[i], &values[i], exception);
         } else {
             auto* parameters = g_ptr_array_new_full(argumentCount, g_object_unref);
             for (size_t i = 0; i < argumentCount; ++i)

Modified: releases/WebKitGTK/webkit-2.32/Source/_javascript_Core/API/glib/JSCContext.cpp (275038 => 275039)


--- releases/WebKitGTK/webkit-2.32/Source/_javascript_Core/API/glib/JSCContext.cpp	2021-03-25 16:49:46 UTC (rev 275038)
+++ releases/WebKitGTK/webkit-2.32/Source/_javascript_Core/API/glib/JSCContext.cpp	2021-03-25 17:06:08 UTC (rev 275039)
@@ -461,6 +461,12 @@
     return JSValueMakeUndefined(priv->jsContext.get());
 }
 
+static inline gpointer jscContextJSValueToWrappedObject(JSCContext* context, JSValueRef jsValue)
+{
+    auto jsObject = JSValueToObject(context->priv->jsContext.get(), jsValue, nullptr);
+    return jsObject ? jscContextWrappedObject(context, jsObject) : nullptr;
+}
+
 void jscContextJSValueToGValue(JSCContext* context, JSValueRef jsValue, GType type, GValue* value, JSValueRef* exception)
 {
     JSCContextPrivate* priv = context->priv;
@@ -471,7 +477,7 @@
     auto fundamentalType = g_type_fundamental(G_VALUE_TYPE(value));
     switch (fundamentalType) {
     case G_TYPE_INT:
-        g_value_set_int(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
+        g_value_set_int(value, JSC::toInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
         break;
     case G_TYPE_FLOAT:
         g_value_set_float(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
@@ -495,56 +501,50 @@
             g_value_set_string(value, nullptr);
         break;
     case G_TYPE_CHAR:
-        g_value_set_schar(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
+        g_value_set_schar(value, JSC::toInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
         break;
     case G_TYPE_UCHAR:
-        g_value_set_uchar(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
+        g_value_set_uchar(value, JSC::toUInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
         break;
     case G_TYPE_UINT:
-        g_value_set_uint(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
+        g_value_set_uint(value, JSC::toUInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
         break;
     case G_TYPE_POINTER:
     case G_TYPE_OBJECT:
     case G_TYPE_BOXED: {
-        gpointer wrappedObject = nullptr;
+        gpointer wrappedObject = jscContextJSValueToWrappedObject(context, jsValue);
 
-        if (!JSValueIsNull(priv->jsContext.get(), jsValue)) {
-            auto jsObject = JSValueToObject(priv->jsContext.get(), jsValue, exception);
-            if (*exception)
+        if (!wrappedObject) {
+            if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_VALUE)) {
+                auto jscValue = jscContextGetOrCreateValue(context, jsValue);
+                g_value_set_object(value, jscValue.get());
                 return;
+            }
 
-            wrappedObject = jscContextWrappedObject(context, jsObject);
-            if (!wrappedObject) {
-                if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_VALUE)) {
-                    auto jscValue = jscContextGetOrCreateValue(context, jsValue);
-                    g_value_set_object(value, jscValue.get());
-                    return;
-                }
+            if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_EXCEPTION)) {
+                auto exception = jscExceptionCreate(context, jsValue);
+                g_value_set_object(value, exception.get());
+                return;
+            }
 
-                if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_EXCEPTION)) {
-                    auto exception = jscExceptionCreate(context, jsValue);
-                    g_value_set_object(value, exception.get());
-                    return;
-                }
+            if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_PTR_ARRAY)) {
+                auto gArray = jscContextJSArrayToGArray(context, jsValue, exception);
+                if (!*exception)
+                    g_value_take_boxed(value, gArray.leakRef());
+                return;
+            }
 
-                if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_PTR_ARRAY)) {
-                    auto gArray = jscContextJSArrayToGArray(context, jsValue, exception);
-                    if (!*exception)
-                        g_value_take_boxed(value, gArray.leakRef());
-                    return;
-                }
-
-                if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_STRV)) {
-                    auto strv = jscContextJSArrayToGStrv(context, jsValue, exception);
-                    if (!*exception)
-                        g_value_take_boxed(value, strv.release());
-                    return;
-                }
-
-                *exception = toRef(JSC::createTypeError(globalObject, "invalid pointer type"_s));
+            if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_STRV)) {
+                auto strv = jscContextJSArrayToGStrv(context, jsValue, exception);
+                if (!*exception)
+                    g_value_take_boxed(value, strv.release());
                 return;
             }
+
+            *exception = toRef(JSC::createTypeError(globalObject, "invalid pointer type"_s));
+            return;
         }
+
         if (fundamentalType == G_TYPE_POINTER)
             g_value_set_pointer(value, wrappedObject);
         else if (fundamentalType == G_TYPE_BOXED)
@@ -568,10 +568,10 @@
         g_value_set_uint64(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
         break;
     case G_TYPE_ENUM:
-        g_value_set_enum(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
+        g_value_set_enum(value, JSC::toInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
         break;
     case G_TYPE_FLAGS:
-        g_value_set_flags(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
+        g_value_set_flags(value, JSC::toInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
         break;
     case G_TYPE_PARAM:
     case G_TYPE_INTERFACE:

Modified: releases/WebKitGTK/webkit-2.32/Source/_javascript_Core/ChangeLog (275038 => 275039)


--- releases/WebKitGTK/webkit-2.32/Source/_javascript_Core/ChangeLog	2021-03-25 16:49:46 UTC (rev 275038)
+++ releases/WebKitGTK/webkit-2.32/Source/_javascript_Core/ChangeLog	2021-03-25 17:06:08 UTC (rev 275039)
@@ -1,3 +1,21 @@
+2021-03-25  Carlos Garcia Campos  <[email protected]>
+
+        [GTK][WPE] JSC crashes if a function expects a parameter but doesn't receive any
+        https://bugs.webkit.org/show_bug.cgi?id=223646
+
+        Reviewed by Adrian Perez de Castro.
+
+        Handle the case of receiving fewer argumens than expected in function calls and constructors. We pass undefined
+        for the expected arguments that are missing. We were not correctly handling the case of converting undefined and
+        null values to JSCValue, so this patch fixes that case too.
+
+        * API/glib/JSCCallbackFunction.cpp:
+        (JSC::JSCCallbackFunction::call):
+        (JSC::JSCCallbackFunction::construct):
+        * API/glib/JSCContext.cpp:
+        (jscContextJSValueToWrappedObject):
+        (jscContextJSValueToGValue):
+
 2021-03-16  Khem Raj  <[email protected]>
 
         [CMake] Build fails on RISC-V with GCC 11

Modified: releases/WebKitGTK/webkit-2.32/Tools/ChangeLog (275038 => 275039)


--- releases/WebKitGTK/webkit-2.32/Tools/ChangeLog	2021-03-25 16:49:46 UTC (rev 275038)
+++ releases/WebKitGTK/webkit-2.32/Tools/ChangeLog	2021-03-25 17:06:08 UTC (rev 275039)
@@ -1,3 +1,17 @@
+2021-03-25  Carlos Garcia Campos  <[email protected]>
+
+        [GTK][WPE] JSC crashes if a function expects a parameter but doesn't receive any
+        https://bugs.webkit.org/show_bug.cgi?id=223646
+
+        Reviewed by Adrian Perez de Castro.
+
+        Add test cases.
+
+        * TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp:
+        (valueToString):
+        (testJSCFunction):
+        (testJSCClass):
+
 2021-03-12  Michael Catanzaro  <[email protected]>
 
         REGRESSION(r274270): [WPE][GTK] Broke Epiphany test /embed/ephy-web-view/error-pages-not-stored-in-history

Modified: releases/WebKitGTK/webkit-2.32/Tools/TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp (275038 => 275039)


--- releases/WebKitGTK/webkit-2.32/Tools/TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp	2021-03-25 16:49:46 UTC (rev 275038)
+++ releases/WebKitGTK/webkit-2.32/Tools/TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp	2021-03-25 17:06:08 UTC (rev 275039)
@@ -852,6 +852,11 @@
     return G_IS_FILE(file);
 }
 
+static char* valueToString(JSCValue* value)
+{
+    return jsc_value_to_string(value);
+}
+
 static void testJSCFunction()
 {
     {
@@ -1121,6 +1126,47 @@
         g_assert_true(jsc_value_is_boolean(value.get()));
         g_assert_true(jsc_value_to_boolean(value.get()));
     }
+
+    {
+        LeakChecker checker;
+        GRefPtr<JSCContext> context = adoptGRef(jsc_context_new());
+        checker.watch(context.get());
+        ExceptionHandler exceptionHandler(context.get());
+
+        GRefPtr<JSCValue> function = adoptGRef(jsc_value_new_function(context.get(), "valueToString", G_CALLBACK(valueToString), nullptr, nullptr, G_TYPE_STRING, 1, JSC_TYPE_VALUE));
+        checker.watch(function.get());
+        jsc_context_set_value(context.get(), "valueToString", function.get());
+
+        GRefPtr<JSCValue> value = adoptGRef(jsc_context_evaluate(context.get(), "valueToString(4)", -1));
+        checker.watch(value.get());
+        GUniquePtr<char> valueString(jsc_value_to_string(value.get()));
+        g_assert_cmpstr(valueString.get(), ==, "4");
+
+        value = adoptGRef(jsc_context_evaluate(context.get(), "valueToString('Hello World')", -1));
+        checker.watch(value.get());
+        valueString.reset(jsc_value_to_string(value.get()));
+        g_assert_cmpstr(valueString.get(), ==, "Hello World");
+
+        value = adoptGRef(jsc_context_evaluate(context.get(), "valueToString(undefined)", -1));
+        checker.watch(value.get());
+        valueString.reset(jsc_value_to_string(value.get()));
+        g_assert_cmpstr(valueString.get(), ==, "undefined");
+
+        value = adoptGRef(jsc_context_evaluate(context.get(), "valueToString(null)", -1));
+        checker.watch(value.get());
+        valueString.reset(jsc_value_to_string(value.get()));
+        g_assert_cmpstr(valueString.get(), ==, "null");
+
+        value = adoptGRef(jsc_context_evaluate(context.get(), "valueToString()", -1));
+        checker.watch(value.get());
+        valueString.reset(jsc_value_to_string(value.get()));
+        g_assert_cmpstr(valueString.get(), ==, "undefined");
+
+        value = adoptGRef(jsc_context_evaluate(context.get(), "valueToString(1,2,3)", -1));
+        checker.watch(value.get());
+        valueString.reset(jsc_value_to_string(value.get()));
+        g_assert_cmpstr(valueString.get(), ==, "1");
+    }
 }
 
 static void testJSCObject()
@@ -1811,6 +1857,14 @@
         g_assert_true(jsc_value_is_number(value.get()));
         g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 52);
 
+        foo2 = adoptGRef(jsc_context_evaluate(context.get(), "f2 = new Foo.CreateWithFoo();", -1));
+        checker.watch(foo2.get());
+        g_assert_true(jsc_value_is_object(foo2.get()));
+        value = adoptGRef(jsc_context_evaluate(context.get(), "f2.foo", -1));
+        checker.watch(value.get());
+        g_assert_true(jsc_value_is_number(value.get()));
+        g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 0);
+
         GRefPtr<JSCValue> constructorV = adoptGRef(jsc_class_add_constructor_variadic(jscClass, "CreateWithFoo", G_CALLBACK(fooCreateWithFooV), nullptr, nullptr, G_TYPE_POINTER));
         checker.watch(constructorV.get());
         g_assert_true(jsc_value_is_constructor(constructorV.get()));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to