aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>2011-09-15 14:58:51 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2011-09-16 11:32:40 +0300
commit6a6da5de107e192f62ce2ecdde96eae985181df0 (patch)
tree1c91954d00d2e994432dc16011cc45ea3f0f3f3d
parent4dc449c1e3c34335f45bd9d550bef71b6c89de1a (diff)
downloadbluez-6a6da5de107e192f62ce2ecdde96eae985181df0.tar.gz
bluez-6a6da5de107e192f62ce2ecdde96eae985181df0.tar.xz
bluez-6a6da5de107e192f62ce2ecdde96eae985181df0.zip
Fix allocation of attribute values
Now that pointers to attribute are passed as reference to functions we cannot have they change during run time, what g_try_realloc() could do.
-rw-r--r--attrib/att.h2
-rw-r--r--src/attrib-server.c33
2 files changed, 25 insertions, 10 deletions
diff --git a/attrib/att.h b/attrib/att.h
index 3b8c098f..9db80659 100644
--- a/attrib/att.h
+++ b/attrib/att.h
@@ -130,7 +130,7 @@ struct attribute {
uint8_t (*write_cb)(struct attribute *a, gpointer user_data);
gpointer cb_user_data;
int len;
- uint8_t data[0];
+ uint8_t *data;
};
struct att_data_list {
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 0bda1e3c..5c86085c 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -270,7 +270,9 @@ static struct attribute *client_cfg_attribute(struct gatt_channel *channel,
/* Create a private copy of the Client Characteristic
* Configuration attribute */
- a = g_malloc0(sizeof(*a) + vlen);
+ a = g_new0(struct attribute, 1);
+ a->data = g_malloc0(vlen);
+
memcpy(a, orig_attr, sizeof(*a));
memcpy(a->data, value, vlen);
a->write_cb = client_set_notifications;
@@ -1121,11 +1123,19 @@ failed:
return -1;
}
+static void attrib_free(void *data)
+{
+ struct attribute *a = data;
+
+ g_free(a->data);
+ g_free(a);
+}
+
void attrib_server_exit(void)
{
GSList *l;
- g_slist_free_full(database, g_free);
+ g_slist_free_full(database, attrib_free);
if (l2cap_io) {
g_io_channel_unref(l2cap_io);
@@ -1242,7 +1252,9 @@ struct attribute *attrib_db_add(uint16_t handle, bt_uuid_t *uuid, int read_reqs,
if (g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp))
return NULL;
- a = g_malloc0(sizeof(struct attribute) + len);
+ a = g_new0(struct attribute, 1);
+ a->data = g_malloc0(len);
+
a->handle = handle;
memcpy(&a->uuid, uuid, sizeof(bt_uuid_t));
a->read_reqs = read_reqs;
@@ -1268,21 +1280,23 @@ int attrib_db_update(uint16_t handle, bt_uuid_t *uuid, const uint8_t *value,
if (!l)
return -ENOENT;
- a = g_try_realloc(l->data, sizeof(struct attribute) + len);
- if (a == NULL)
+ a = l->data;
+
+ a->data = g_try_realloc(a->data, len);
+ if (a->data == NULL)
return -ENOMEM;
- l->data = a;
- if (uuid != NULL)
- memcpy(&a->uuid, uuid, sizeof(bt_uuid_t));
a->len = len;
memcpy(a->data, value, len);
- attrib_notify_clients(a);
+ if (uuid != NULL)
+ memcpy(&a->uuid, uuid, sizeof(bt_uuid_t));
if (attr)
*attr = a;
+ attrib_notify_clients(a);
+
return 0;
}
@@ -1300,6 +1314,7 @@ int attrib_db_del(uint16_t handle)
a = l->data;
database = g_slist_remove(database, a);
+ g_free(a->data);
g_free(a);
return 0;