Ejemplo n.º 1
0
bool
document_resolve(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned flags,
                 JS::MutableHandleObject objp)
{
    // If id is "all", resolve document.all=true.
    JS::RootedValue v(cx);
    if (!JS_IdToValue(cx, id, &v))
        return false;
    if (JSVAL_IS_STRING(v)) {
        JSString *str = JSVAL_TO_STRING(v);
        JSFlatString *flatStr = JS_FlattenString(cx, str);
        if (!flatStr)
            return false;
        if (JS_FlatStringEqualsAscii(flatStr, "all")) {
            JS::Rooted<JSObject*> docAll(cx,
                                         JS_NewObject(cx, &DocumentAllClass, JS::NullPtr(), JS::NullPtr()));
            if (!docAll)
                return false;
            JS::Rooted<JS::Value> allValue(cx, ObjectValue(*docAll));
            bool ok = JS_DefinePropertyById(cx, obj, id, allValue, nullptr, nullptr, 0);
            objp.set(ok ? obj.get() : nullptr);
            return ok;
        }
    }
    objp.set(nullptr);
    return true;
}
Ejemplo n.º 2
0
bool
JavaScriptShared::Unwrap(JSContext* cx, const InfallibleTArray<CpowEntry>& aCpows,
                         JS::MutableHandleObject objp)
{
    objp.set(nullptr);

    if (!aCpows.Length())
        return true;

    RootedObject obj(cx, JS_NewPlainObject(cx));
    if (!obj)
        return false;

    RootedValue v(cx);
    RootedString str(cx);
    for (size_t i = 0; i < aCpows.Length(); i++) {
        const nsString& name = aCpows[i].name();

        if (!fromVariant(cx, aCpows[i].value(), &v))
            return false;

        if (!JS_DefineUCProperty(cx,
                                 obj,
                                 name.BeginReading(),
                                 name.Length(),
                                 v,
                                 JSPROP_ENUMERATE))
        {
            return false;
        }
    }

    objp.set(obj);
    return true;
}
Ejemplo n.º 3
0
void CStdDeserializer::GetSerializablePrototype(const std::wstring& name, JS::MutableHandleObject ret)
{
	std::map<std::wstring, JS::Heap<JSObject*> >::iterator it = m_SerializablePrototypes.find(name);
	if (it != m_SerializablePrototypes.end())
		ret.set(it->second);
	else
		ret.set(NULL);
}
bool
doResolve(JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp)
{
    CHECK_EQUAL(resolveExitCount, 0);
    AutoIncrCounters incr(this);
    CHECK_EQUAL(obj, obj1 || obj == obj2);

    CHECK(JSID_IS_STRING(id));

    JSFlatString *str = JS_FlattenString(cx, JSID_TO_STRING(id));
    CHECK(str);
    JS::RootedValue v(cx);
    if (JS_FlatStringEqualsAscii(str, "x")) {
        if (obj == obj1) {
            /* First resolve hook invocation. */
            CHECK_EQUAL(resolveEntryCount, 1);
            EVAL("obj2.y = true", v.address());
            CHECK_SAME(v, JSVAL_TRUE);
            CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_FALSE, NULL, NULL, 0));
            objp.set(obj);
            return true;
        }
        if (obj == obj2) {
            CHECK_EQUAL(resolveEntryCount, 4);
            objp.set(NULL);
            return true;
        }
    } else if (JS_FlatStringEqualsAscii(str, "y")) {
        if (obj == obj2) {
            CHECK_EQUAL(resolveEntryCount, 2);
            CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_NULL, NULL, NULL, 0));
            EVAL("obj1.x", v.address());
            CHECK(JSVAL_IS_VOID(v));
            EVAL("obj1.y", v.address());
            CHECK_SAME(v, JSVAL_ZERO);
            objp.set(obj);
            return true;
        }
        if (obj == obj1) {
            CHECK_EQUAL(resolveEntryCount, 3);
            EVAL("obj1.x", v.address());
            CHECK(JSVAL_IS_VOID(v));
            EVAL("obj1.y", v.address());
            CHECK(JSVAL_IS_VOID(v));
            EVAL("obj2.y", v.address());
            CHECK(JSVAL_IS_NULL(v));
            EVAL("obj2.x", v.address());
            CHECK(JSVAL_IS_VOID(v));
            EVAL("obj1.y = 0", v.address());
            CHECK_SAME(v, JSVAL_ZERO);
            objp.set(obj);
            return true;
        }
    }
    CHECK(false);
    return false;
}
 void get_or_create_js_obj(JSContext* cx, JS::HandleObject obj, const std::string &name, JS::MutableHandleObject jsObj)
 {
     JS::RootedValue nsval(cx);
     JS_GetProperty(cx, obj, name.c_str(), &nsval);
     if (nsval == JSVAL_VOID) {
         jsObj.set(JS_NewObject(cx, NULL, NULL, NULL));
         nsval = OBJECT_TO_JSVAL(jsObj);
         JS_SetProperty(cx, obj, name.c_str(), nsval);
     } else {
         jsObj.set(nsval.toObjectOrNull());
     }
 }
Ejemplo n.º 6
0
bool
XPCWrappedNativeScope::GetComponentsJSObject(JS::MutableHandleObject obj)
{
    AutoJSContext cx;
    if (!mComponents) {
        nsIPrincipal* p = GetPrincipal();
        bool system = nsXPConnect::SecurityManager()->IsSystemPrincipal(p);
        mComponents = system ? new nsXPCComponents(this)
                             : new nsXPCComponentsBase(this);
    }

    RootedValue val(cx);
    xpcObjectHelper helper(mComponents);
    bool ok = XPCConvert::NativeInterface2JSObject(&val, nullptr, helper,
                                                   nullptr, nullptr, false,
                                                   nullptr);
    if (NS_WARN_IF(!ok))
        return false;

    if (NS_WARN_IF(!val.isObject()))
        return false;

    // The call to wrap() here is necessary even though the object is same-
    // compartment, because it applies our security wrapper.
    obj.set(&val.toObject());
    if (NS_WARN_IF(!JS_WrapObject(cx, obj)))
        return false;
    return true;
}
Ejemplo n.º 7
0
static bool
env_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
            JS::MutableHandleObject objp)
{
    JSString *idstr, *valstr;

    RootedValue idval(cx);
    if (!JS_IdToValue(cx, id, &idval))
        return false;

    idstr = ToString(cx, idval);
    if (!idstr)
        return false;
    JSAutoByteString name(cx, idstr);
    if (!name)
        return false;
    const char *value = getenv(name.ptr());
    if (value) {
        valstr = JS_NewStringCopyZ(cx, value);
        if (!valstr)
            return false;
        if (!JS_DefinePropertyById(cx, obj, id, STRING_TO_JSVAL(valstr),
                                   nullptr, nullptr, JSPROP_ENUMERATE)) {
            return false;
        }
        objp.set(obj);
    }
    return true;
}
Ejemplo n.º 8
0
bool
FilteringWrapper<Base, Policy>::getPrototypeOf(JSContext* cx, JS::HandleObject wrapper,
                                               JS::MutableHandleObject protop) const
{
    // Filtering wrappers do not allow access to the prototype.
    protop.set(nullptr);
    return true;
}
Ejemplo n.º 9
0
static void
PreWrap(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj,
        JS::HandleObject objectPassedToWrap,
        JS::MutableHandleObject retObj)
{
    JS_GC(cx);
    retObj.set(obj);
}
Ejemplo n.º 10
0
bool
CrossOriginXrayWrapper::getPrototypeOf(JSContext *cx, JS::HandleObject wrapper,
                                       JS::MutableHandleObject protop) const
{
    // Cross-origin objects have null prototypes.
    protop.set(nullptr);
    return true;
}
Ejemplo n.º 11
0
static JSBool
fundamental_instance_new_resolve_interface(JSContext    *context,
                                           JS::HandleObject obj,
                                           JS::MutableHandleObject objp,
                                           Fundamental  *proto_priv,
                                           char         *name)
{
    GIFunctionInfo *method_info;
    JSBool ret;
    GType *interfaces;
    guint n_interfaces;
    guint i;

    ret = JS_TRUE;
    interfaces = g_type_interfaces(proto_priv->gtype, &n_interfaces);
    for (i = 0; i < n_interfaces; i++) {
        GIBaseInfo *base_info;
        GIInterfaceInfo *iface_info;

        base_info = g_irepository_find_by_gtype(g_irepository_get_default(),
                                                interfaces[i]);

        if (base_info == NULL)
            continue;

        /* An interface GType ought to have interface introspection info */
        g_assert(g_base_info_get_type(base_info) == GI_INFO_TYPE_INTERFACE);

        iface_info = (GIInterfaceInfo *) base_info;

        method_info = g_interface_info_find_method(iface_info, name);

        g_base_info_unref(base_info);


        if (method_info != NULL) {
            if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
                if (gjs_define_function(context, obj,
                                        proto_priv->gtype,
                                        (GICallableInfo *) method_info)) {
                    objp.set(obj);
                } else {
                    ret = JS_FALSE;
                }
            }

            g_base_info_unref((GIBaseInfo *) method_info);
        }
    }

    g_free(interfaces);
    return ret;
}
Ejemplo n.º 12
0
static bool
interface_new_resolve(JSContext *context,
                      JS::HandleObject obj,
                      JS::HandleId id,
                      JS::MutableHandleObject objp)
{
    Interface *priv;
    char *name;
    bool ret = false;
    GIFunctionInfo *method_info;

    if (!gjs_get_string_id(context, id, &name))
        return true;

    priv = priv_from_js(context, obj);

    if (priv == NULL)
        goto out;

    /* If we have no GIRepository information then this interface was defined
     * from within GJS. In that case, it has no properties that need to be
     * resolved from within C code, as interfaces cannot inherit. */
    if (priv->info == NULL) {
        ret = true;
        goto out;
    }

    method_info = g_interface_info_find_method((GIInterfaceInfo*) priv->info, name);

    if (method_info != NULL) {
        if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
            if (gjs_define_function(context, obj,
                                    priv->gtype,
                                    (GICallableInfo*)method_info) == NULL) {
                g_base_info_unref((GIBaseInfo*)method_info);
                goto out;
            }

            objp.set(obj);
        }

        g_base_info_unref((GIBaseInfo*)method_info);
    }

    ret = true;

 out:
    g_free (name);
    return ret;
}
Ejemplo n.º 13
0
bool ScriptInterface::GetProperty(JS::HandleValue obj, const char* name, JS::MutableHandleObject out)
{
	JSContext* cx = GetContext();
	JSAutoRequest rq(cx);
	JS::RootedValue val(cx);
	if (!GetProperty_(obj, name, &val))
		return false;
	if (!val.isObject())
	{
		LOGERROR("GetProperty failed: trying to get an object, but the property is not an object!");
		return false;
	}

	out.set(&val.toObject());
	return true;
}
Ejemplo n.º 14
0
/*
 * Like JSResolveOp, but flags provide contextual information as follows:
 *
 *  JSRESOLVE_QUALIFIED   a qualified property id: obj.id or obj[id], not id
 *  JSRESOLVE_ASSIGNING   obj[id] is on the left-hand side of an assignment
 *  JSRESOLVE_DETECTING   'if (o.p)...' or similar detection opcode sequence
 *  JSRESOLVE_DECLARING   var, const, or function prolog declaration opcode
 *  JSRESOLVE_CLASSNAME   class name used when constructing
 *
 * The *objp out parameter, on success, should be null to indicate that id
 * was not resolved; and non-null, referring to obj or one of its prototypes,
 * if id was resolved.
 */
static JSBool
importer_new_resolve(JSContext *context,
                     JS::HandleObject obj,
                     JS::HandleId id,
                     unsigned flags,
                     JS::MutableHandleObject objp)
{
    Importer *priv;
    std::string name;
    JSBool ret = JS_TRUE;
    jsid module_init_name;

    module_init_name = gjs_context_get_const_string(context, GJS_STRING_MODULE_INIT);
    if (id == module_init_name)
        return JS_TRUE;

    if (!gjs_get_string_id(context, id, name))
        return JS_FALSE;

    /* let Object.prototype resolve these */
    if (name == "valueOf" ||
        name == "toString" ||
        name == "__iterator__")
        goto out;
    priv = priv_from_js(context, obj);

//    std::cout << "Resolve prop '" << name << "' hook obj " << (uint32_t)*obj << " priv " << (uint32_t)priv << "\n";
    if (priv == NULL) /* we are the prototype, or have the wrong class */
        goto out;
    JS_BeginRequest(context);
    if (do_import(context, obj, priv, name)) {
        objp.set(obj);
    } else {
        ret = JS_FALSE;
    }
    JS_EndRequest(context);

 out:
    return ret;
}
bool
StructuredCloneHelper::ReadTransferCallback(JSContext* aCx,
                                            JSStructuredCloneReader* aReader,
                                            uint32_t aTag,
                                            void* aContent,
                                            uint64_t aExtraData,
                                            JS::MutableHandleObject aReturnObject)
{
  MOZ_ASSERT(mSupportsTransferring);

  if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) {
    // This can be null.
    nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mParent);

    MOZ_ASSERT(aExtraData < mPortIdentifiers.Length());
    const MessagePortIdentifier& portIdentifier = mPortIdentifiers[aExtraData];

    // aExtraData is the index of this port identifier.
    ErrorResult rv;
    nsRefPtr<MessagePort> port =
      MessagePort::Create(window, portIdentifier, rv);
    if (NS_WARN_IF(rv.Failed())) {
      return false;
    }

    mTransferredPorts.AppendElement(port);

    JS::Rooted<JS::Value> value(aCx);
    if (!GetOrCreateDOMReflector(aCx, port, &value)) {
      JS_ClearPendingException(aCx);
      return false;
    }

    aReturnObject.set(&value.toObject());
    return true;
  }

  return false;
}
Ejemplo n.º 16
0
    void getJsObjOrCreat(JSContext* cx, JS::HandleObject jsObj, const char* name, JS::MutableHandleObject retObj) {
        JS::RootedObject parent(cx);
        JS::RootedObject tempObj(cx);
        bool first = true;

        std::stringstream ss(name);
        std::string sub;
        const char* subChar;
        while(getline(ss, sub, '.')) {
            if(sub.empty())continue;

            subChar = sub.c_str();
            if (first) {
                get_or_create_js_obj(cx, jsObj, subChar, &tempObj);
                first = false;
            } else {
                parent = tempObj;
                get_or_create_js_obj(cx, parent, subChar, &tempObj);
            }
        }

        retObj.set(tempObj.get());
    }
Ejemplo n.º 17
0
Archivo: ns.cpp Proyecto: dreamsxin/gjs
/*
 * Like JSResolveOp, but flags provide contextual information as follows:
 *
 *  JSRESOLVE_QUALIFIED   a qualified property id: obj.id or obj[id], not id
 *  JSRESOLVE_ASSIGNING   obj[id] is on the left-hand side of an assignment
 *  JSRESOLVE_DETECTING   'if (o.p)...' or similar detection opcode sequence
 *  JSRESOLVE_DECLARING   var, const, or function prolog declaration opcode
 *  JSRESOLVE_CLASSNAME   class name used when constructing
 *
 * The *objp out parameter, on success, should be null to indicate that id
 * was not resolved; and non-null, referring to obj or one of its prototypes,
 * if id was resolved.
 */
static JSBool
ns_new_resolve(JSContext *context,
               JS::HandleObject obj,
               JS::HandleId id,
               unsigned flags,
               JS::MutableHandleObject objp)
{
    Ns *priv;
    char *name;
    GIRepository *repo;
    GIBaseInfo *info;
    JSBool ret = JS_FALSE;
    gboolean defined;

    if (!gjs_get_string_id(context, id, &name))
        return JS_TRUE; /* not resolved, but no error */

    /* let Object.prototype resolve these */
    if (strcmp(name, "valueOf") == 0 ||
        strcmp(name, "toString") == 0) {
        ret = JS_TRUE;
        goto out;
    }

    priv = priv_from_js(context, obj);
    gjs_debug_jsprop(GJS_DEBUG_GNAMESPACE, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv);

    if (priv == NULL) {
        ret = JS_TRUE; /* we are the prototype, or have the wrong class */
        goto out;
    }

    JS_BeginRequest(context);

    repo = g_irepository_get_default();

    info = g_irepository_find_by_name(repo, priv->gi_namespace, name);
    if (info == NULL) {
        /* No property defined, but no error either, so return TRUE */
        JS_EndRequest(context);
        ret = JS_TRUE;
        goto out;
    }

    gjs_debug(GJS_DEBUG_GNAMESPACE,
              "Found info type %s for '%s' in namespace '%s'",
              gjs_info_type_name(g_base_info_get_type(info)),
              g_base_info_get_name(info),
              g_base_info_get_namespace(info));

    if (gjs_define_info(context, obj, info, &defined)) {
        g_base_info_unref(info);
        if (defined)
            objp.set(obj); /* we defined the property in this object */
        ret = JS_TRUE;
    } else {
        gjs_debug(GJS_DEBUG_GNAMESPACE,
                  "Failed to define info '%s'",
                  g_base_info_get_name(info));

        g_base_info_unref(info);
    }
    JS_EndRequest(context);

 out:
    g_free(name);
    return ret;
}
Ejemplo n.º 18
0
void CStdDeserializer::GetScriptBackref(u32 tag, JS::MutableHandleObject ret)
{
	ENSURE(m_ScriptBackrefs.size() > tag);
	ret.set(m_ScriptBackrefs[tag]);
}
Ejemplo n.º 19
0
/*
 * Like JSResolveOp, but flags provide contextual information as follows:
 *
 *  JSRESOLVE_QUALIFIED   a qualified property id: obj.id or obj[id], not id
 *  JSRESOLVE_ASSIGNING   obj[id] is on the left-hand side of an assignment
 *  JSRESOLVE_DETECTING   'if (o.p)...' or similar detection opcode sequence
 *  JSRESOLVE_DECLARING   var, const, or fundamental prolog declaration opcode
 *  JSRESOLVE_CLASSNAME   class name used when constructing
 *
 * The *objp out parameter, on success, should be null to indicate that id
 * was not resolved; and non-null, referring to obj or one of its prototypes,
 * if id was resolved.
 */
static JSBool
fundamental_instance_new_resolve(JSContext  *context,
                                 JS::HandleObject obj,
                                 JS::HandleId id,
                                 unsigned flags,
                                 JS::MutableHandleObject objp)
{
    FundamentalInstance *priv;
    char *name;
    JSBool ret = JS_FALSE;

    if (!gjs_get_string_id(context, id, &name))
        return JS_TRUE; /* not resolved, but no error */

    priv = priv_from_js(context, obj);
    gjs_debug_jsprop(GJS_DEBUG_GFUNDAMENTAL, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv);

    if (priv == NULL)
        goto out; /* wrong class */

    if (priv->prototype == NULL) {
        /* We are the prototype, so look for methods and other class properties */
        Fundamental *proto_priv = (Fundamental *) priv;
        GIFunctionInfo *method_info;

        method_info = g_object_info_find_method((GIStructInfo*) proto_priv->info,
                                                name);

        if (method_info != NULL) {
            const char *method_name;

#if GJS_VERBOSE_ENABLE_GI_USAGE
            _gjs_log_info_usage((GIBaseInfo *) method_info);
#endif
            if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
                method_name = g_base_info_get_name((GIBaseInfo *) method_info);

                /* we do not define deprecated methods in the prototype */
                if (g_base_info_is_deprecated((GIBaseInfo *) method_info)) {
                    gjs_debug(GJS_DEBUG_GFUNDAMENTAL,
                              "Ignoring definition of deprecated method %s in prototype %s.%s",
                              method_name,
                              g_base_info_get_namespace((GIBaseInfo *) proto_priv->info),
                              g_base_info_get_name((GIBaseInfo *) proto_priv->info));
                    g_base_info_unref((GIBaseInfo *) method_info);
                    ret = JS_TRUE;
                    goto out;
                }

                gjs_debug(GJS_DEBUG_GFUNDAMENTAL,
                          "Defining method %s in prototype for %s.%s",
                          method_name,
                          g_base_info_get_namespace((GIBaseInfo *) proto_priv->info),
                          g_base_info_get_name((GIBaseInfo *) proto_priv->info));

                if (gjs_define_function(context, obj, proto_priv->gtype,
                                        method_info) == NULL) {
                    g_base_info_unref((GIBaseInfo *) method_info);
                    goto out;
                }

                objp.set(obj);
            }

            g_base_info_unref((GIBaseInfo *) method_info);
        }

        ret = fundamental_instance_new_resolve_interface(context, obj, objp,
                                                         proto_priv, name);
    } else {
        /* We are an instance, not a prototype, so look for
         * per-instance props that we want to define on the
         * JSObject. Generally we do not want to cache these in JS, we
         * want to always pull them from the C object, or JS would not
         * see any changes made from C. So we use the get/set prop
         * hooks, not this resolve hook.
         */
    }

    ret = JS_TRUE;
 out:
    g_free(name);
    return ret;
}
Ejemplo n.º 20
0
/*
 * Like JSResolveOp, but flags provide contextual information as follows:
 *
 *  JSRESOLVE_QUALIFIED   a qualified property id: obj.id or obj[id], not id
 *  JSRESOLVE_ASSIGNING   obj[id] is on the left-hand side of an assignment
 *  JSRESOLVE_DETECTING   'if (o.p)...' or similar detection opcode sequence
 *  JSRESOLVE_DECLARING   var, const, or boxed prolog declaration opcode
 *  JSRESOLVE_CLASSNAME   class name used when constructing
 *
 * The *objp out parameter, on success, should be null to indicate that id
 * was not resolved; and non-null, referring to obj or one of its prototypes,
 * if id was resolved.
 */
static JSBool
union_new_resolve(JSContext *context,
                  JS::HandleObject obj,
                  JS::HandleId id,
                  unsigned flags,
                  JS::MutableHandleObject objp)
{
    Union *priv;
    char *name;
    JSBool ret = JS_TRUE;

    if (!gjs_get_string_id(context, id, &name))
        return JS_TRUE; /* not resolved, but no error */

    priv = priv_from_js(context, obj);
    gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv);

    if (priv == NULL) {
        ret = JS_FALSE; /* wrong class */
        goto out;
    }

    if (priv->gboxed == NULL) {
        /* We are the prototype, so look for methods and other class properties */
        GIFunctionInfo *method_info;

        method_info = g_union_info_find_method((GIUnionInfo*) priv->info,
                                               name);

        if (method_info != NULL) {
            JSObject *union_proto;
            const char *method_name;

#if GJS_VERBOSE_ENABLE_GI_USAGE
            _gjs_log_info_usage((GIBaseInfo*) method_info);
#endif
            if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
                method_name = g_base_info_get_name( (GIBaseInfo*) method_info);

                gjs_debug(GJS_DEBUG_GBOXED,
                          "Defining method %s in prototype for %s.%s",
                          method_name,
                          g_base_info_get_namespace( (GIBaseInfo*) priv->info),
                          g_base_info_get_name( (GIBaseInfo*) priv->info));

                union_proto = obj;

                if (gjs_define_function(context, union_proto,
                                        g_registered_type_info_get_g_type(priv->info),
                                        method_info) == NULL) {
                    g_base_info_unref( (GIBaseInfo*) method_info);
                    ret = JS_FALSE;
                    goto out;
                }

                objp.set(union_proto); /* we defined the prop in object_proto */
            }

            g_base_info_unref( (GIBaseInfo*) method_info);
        }
    } else {
        /* We are an instance, not a prototype, so look for
         * per-instance props that we want to define on the
         * JSObject. Generally we do not want to cache these in JS, we
         * want to always pull them from the C object, or JS would not
         * see any changes made from C. So we use the get/set prop
         * hooks, not this resolve hook.
         */
    }

 out:
    g_free(name);
    return ret;
}