[gjs: 1/2] gi: Avoid infinite recursion when converting GValues



commit 2ab3be50449e850c40da0ee1d2ed44faf7ffa4d4
Author: Florian Müllner <fmuellner gnome org>
Date:   Tue Aug 13 00:23:21 2019 +0200

    gi: Avoid infinite recursion when converting GValues
    
    gjs_value_to_g_value() special-cases GValues of type G_TYPE_VALUE
    by calling itself with an untyped "nested" GValue. As that nested
    GValue is untyped, the function will guess the type from the
    javascript value and set the GValue accordingly.
    
    This works with one notable exception: If the javascript value
    itself holds a GValue, the guessed GType will be G_TYPE_VALUE
    again, and the same code path that calls gjs_value_to_g_value()
    will be called again ... and again ... and again ...
    
    Avoid that infinite recursion by setting the original GValue directly
    if the javascript value already holds a GValue.
    
    https://gitlab.gnome.org/GNOME/gjs/merge_requests/329

 gi/value.cpp | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
---
diff --git a/gi/value.cpp b/gi/value.cpp
index 8d567a7f..a68f6059 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -523,6 +523,22 @@ gjs_value_to_g_value_internal(JSContext      *context,
         if (g_type_is_a(gtype, G_TYPE_VALUE)) {
             GValue nested_gvalue = G_VALUE_INIT;
 
+            /* explicitly handle values that are already GValues
+               to avoid infinite recursion */
+            if (value.isObject()) {
+                JS::RootedObject obj(context, &value.toObject());
+                GType guessed_gtype;
+
+                if (!gjs_value_guess_g_type(context, value, &guessed_gtype))
+                    return false;
+
+                if (guessed_gtype == G_TYPE_VALUE) {
+                    gboxed = BoxedBase::to_c_ptr<GValue>(context, obj);
+                    g_value_set_boxed(gvalue, gboxed);
+                    return true;
+                }
+            }
+
             if (!gjs_value_to_g_value(context, value, &nested_gvalue))
                 return false;
 


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