[gjs/gnome-3-24] object: Avoid taking address of empty vector
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/gnome-3-24] object: Avoid taking address of empty vector
- Date: Fri, 8 Sep 2017 03:42:32 +0000 (UTC)
commit 5084c5442d3ffde9eed055789bcb46557030658a
Author: Philip Chimento <philip chimento gmail com>
Date: Tue Aug 29 23:20:41 2017 -0700
object: Avoid taking address of empty vector
Given a std::vector<T> vec, &vec[0] is undefined behaviour when the
vector is empty. C++11 provides a vec.data() method which does the same
thing safely.
This is an opportunity for a small refactor; the free function didn't
actually free the vector, so it should be renamed "clear", and it can
just take in the vector instead of a pointer to the data. We can also
keep all the memory management of the vector in the same place, in
object_instance_init().
https://bugzilla.gnome.org/show_bug.cgi?id=786995
gi/object.cpp | 44 ++++++++++++++++++--------------------------
1 files changed, 18 insertions(+), 26 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 6722cfe..15362fa 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -855,19 +855,10 @@ object_instance_resolve(JSContext *context,
return true;
}
-static void
-free_g_params(GParameter *params,
- int n_params)
-{
- int i;
-
- for (i = 0; i < n_params; ++i) {
- g_value_unset(¶ms[i].value);
- }
-}
-
/* Set properties from args to constructor (argv[0] is supposed to be
* a hash)
+ * The GParameter elements in the passed-in vector must be unset by the caller,
+ * regardless of the return value of this function.
*/
static bool
object_instance_props_to_g_parameters(JSContext *context,
@@ -883,7 +874,6 @@ object_instance_props_to_g_parameters(JSContext *context,
if (!args[0].isObject()) {
gjs_throw(context, "argument should be a hash with props to set");
- free_g_params(&gparams[0], gparams.size());
return false;
}
@@ -893,7 +883,7 @@ object_instance_props_to_g_parameters(JSContext *context,
JS::RootedValue value(context);
if (!ids) {
gjs_throw(context, "Failed to create property iterator for object props hash");
- goto free_array_and_fail;
+ return false;
}
for (ix = 0, length = ids.length(); ix < length; ix++) {
@@ -904,12 +894,10 @@ object_instance_props_to_g_parameters(JSContext *context,
* doesn't know that */
prop_id = ids[ix];
- if (!gjs_object_require_property(context, props, "property list", prop_id, &value)) {
- goto free_array_and_fail;
- }
-
- if (!gjs_get_string_id(context, prop_id, &name))
- goto free_array_and_fail;
+ if (!gjs_object_require_property(context, props, "property list",
+ prop_id, &value) ||
+ !gjs_get_string_id(context, prop_id, &name))
+ return false;
switch (init_g_param_from_property(context, name,
value,
@@ -922,7 +910,7 @@ object_instance_props_to_g_parameters(JSContext *context,
/* fallthrough */
case SOME_ERROR_OCCURRED:
g_free(name);
- goto free_array_and_fail;
+ return false;
case VALUE_WAS_SET:
default:
break;
@@ -934,10 +922,6 @@ object_instance_props_to_g_parameters(JSContext *context,
}
return true;
-
- free_array_and_fail:
- free_g_params(&gparams[0], gparams.size());
- return false;
}
#define DEBUG_DISPOSE 0
@@ -1438,6 +1422,13 @@ disassociate_js_gobject(GObject *gobj)
priv->js_object_finalized = true;
}
+static void
+clear_g_params(std::vector<GParameter>& params)
+{
+ for (GParameter param : params)
+ g_value_unset(¶m.value);
+}
+
static bool
object_instance_init (JSContext *context,
JS::MutableHandleObject object,
@@ -1456,6 +1447,7 @@ object_instance_init (JSContext *context,
if (!object_instance_props_to_g_parameters(context, object, args,
gtype, params)) {
+ clear_g_params(params);
return false;
}
@@ -1468,10 +1460,10 @@ object_instance_init (JSContext *context,
}
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- gobj = (GObject*) g_object_newv(gtype, params.size(), ¶ms[0]);
+ gobj = (GObject*) g_object_newv(gtype, params.size(), params.data());
G_GNUC_END_IGNORE_DEPRECATIONS
- free_g_params(¶ms[0], params.size());
+ clear_g_params(params);
ObjectInstance *other_priv = get_object_qdata(gobj);
if (other_priv && other_priv->keep_alive != object) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]