summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2014-02-24 14:03:28 +0100
committerGiovanni Campagna <gcampagna@src.gnome.org>2014-02-26 01:52:04 +0100
commit3d8bd0ab42582e487ab62dacc32a915b7b03c7d4 (patch)
tree9f7ac593355d5adc926b81b8dc0f12d877aa617b
parent9680de88d444d6b7f5eb289f4c92f22c79e8b267 (diff)
downloadgjs-3d8bd0ab42582e487ab62dacc32a915b7b03c7d4.tar.gz
arg: fix cast checking for objects and fundamentals
We must make sure that all code paths successfully set the object or throw an exception. https://bugzilla.gnome.org/show_bug.cgi?id=725061
-rw-r--r--gi/arg.cpp45
1 files changed, 31 insertions, 14 deletions
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 90376e12..aa11570a 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -1482,20 +1482,13 @@ gjs_value_to_g_argument(JSContext *context,
}
} else if (gtype != G_TYPE_NONE) {
- if (g_type_is_a(gtype, G_TYPE_OBJECT) || g_type_is_a(gtype, G_TYPE_INTERFACE)) {
- if (gjs_typecheck_object(context, JSVAL_TO_OBJECT(value),
- gtype, JS_FALSE)) {
+ if (g_type_is_a(gtype, G_TYPE_OBJECT)) {
+ if (gjs_typecheck_object(context, JSVAL_TO_OBJECT(value), gtype, JS_TRUE)) {
arg->v_pointer = gjs_g_object_from_object(context,
JSVAL_TO_OBJECT(value));
if (transfer != GI_TRANSFER_NOTHING)
g_object_ref(G_OBJECT(arg->v_pointer));
- } else if (gjs_typecheck_fundamental(context, JSVAL_TO_OBJECT(value), gtype, JS_FALSE)) {
- arg->v_pointer = gjs_g_fundamental_from_object(context,
- JSVAL_TO_OBJECT(value));
-
- if (transfer != GI_TRANSFER_NOTHING)
- gjs_fundamental_ref(context, arg->v_pointer);
} else {
arg->v_pointer = NULL;
wrong = TRUE;
@@ -1514,12 +1507,36 @@ gjs_value_to_g_argument(JSContext *context,
g_type_name(gtype),
interface_type);
}
- } else if (gjs_typecheck_fundamental(context, JSVAL_TO_OBJECT(value), gtype, JS_FALSE)) {
- arg->v_pointer = gjs_g_fundamental_from_object(context,
- JSVAL_TO_OBJECT(value));
+ } else if (G_TYPE_IS_INSTANTIATABLE(gtype)) {
+ if (gjs_typecheck_fundamental(context, JSVAL_TO_OBJECT(value), gtype, JS_TRUE)) {
+ arg->v_pointer = gjs_g_fundamental_from_object(context,
+ JSVAL_TO_OBJECT(value));
+
+ if (transfer != GI_TRANSFER_NOTHING)
+ gjs_fundamental_ref(context, arg->v_pointer);
+ } else {
+ arg->v_pointer = NULL;
+ wrong = TRUE;
+ }
+ } else if (G_TYPE_IS_INTERFACE(gtype)) {
+ /* Could be a GObject interface that's missing a prerequisite, or could
+ be a fundamental */
+ if (gjs_typecheck_object(context, JSVAL_TO_OBJECT(value), gtype, JS_FALSE)) {
+ arg->v_pointer = gjs_g_object_from_object(context, JSVAL_TO_OBJECT(value));
+
+ if (transfer != GI_TRANSFER_NOTHING)
+ g_object_ref(arg->v_pointer);
+ } else if (gjs_typecheck_fundamental(context, JSVAL_TO_OBJECT(value), gtype, JS_FALSE)) {
+ arg->v_pointer = gjs_g_fundamental_from_object(context, JSVAL_TO_OBJECT(value));
- if (transfer != GI_TRANSFER_NOTHING)
- gjs_fundamental_ref(context, arg->v_pointer);
+ if (transfer != GI_TRANSFER_NOTHING)
+ gjs_fundamental_ref(context, arg->v_pointer);
+ } else {
+ /* Call again with throw=TRUE to set the exception */
+ gjs_typecheck_object(context, JSVAL_TO_OBJECT(value), gtype, JS_TRUE);
+ arg->v_pointer = NULL;
+ wrong = TRUE;
+ }
} else {
gjs_throw(context, "Unhandled GType %s unpacking GArgument from Object",
g_type_name(gtype));