summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2009-03-13 15:27:33 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2009-03-13 15:07:44 -0300
commiteb101261ee8d43dd3a1bfaa982a3336cd8dfa020 (patch)
treeac4f903201b91acc51dd30b191ea00234ec2fbd4
parentae6e4f68f37333e3dbd6b8b89445850b87bcbfe2 (diff)
Fix sdp_copy_record truncating strings with NULLs
When a record's attribute contains embed NULLs in the string, sdp_data_alloc() falls back to doing an strlen() on the string, instead of taking its existing length into account.
-rw-r--r--lib/sdp.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/lib/sdp.c b/lib/sdp.c
index 896c5eb9..71a65c4e 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -97,6 +97,8 @@ static uint128_t bluetooth_base_uuid = {
#define SDP_MAX_ATTR_LEN 65535
static sdp_data_t *sdp_copy_seq(sdp_data_t *data);
+static int sdp_attr_add_new_with_length(sdp_record_t *rec,
+ uint16_t attr, uint8_t dtd, const void *value, uint32_t len);
/* Message structure. */
struct tupla {
@@ -1381,7 +1383,7 @@ static void sdp_copy_pattern(void *value, void *udata)
sdp_pattern_add_uuid(rec, uuid);
}
-static void *sdp_data_value(sdp_data_t *data)
+static void *sdp_data_value(sdp_data_t *data, uint32_t *len)
{
void *val = NULL;
@@ -1435,6 +1437,8 @@ static void *sdp_data_value(sdp_data_t *data)
case SDP_URL_STR32:
case SDP_TEXT_STR32:
val = data->val.str;
+ if (len)
+ *len = data->unitSize - 1;
break;
case SDP_ALT8:
case SDP_ALT16:
@@ -1457,7 +1461,7 @@ static sdp_data_t *sdp_copy_seq(sdp_data_t *data)
sdp_data_t *datatmp;
void *value;
- value = sdp_data_value(tmp);
+ value = sdp_data_value(tmp, NULL);
datatmp = sdp_data_alloc_with_length(tmp->dtd, value,
tmp->unitSize);
@@ -1477,10 +1481,15 @@ static void sdp_copy_attrlist(void *value, void *udata)
sdp_data_t *data = value;
sdp_record_t *rec = udata;
void *val;
+ uint32_t len = 0;
- val = sdp_data_value(data);
+ val = sdp_data_value(data, &len);
- sdp_attr_add_new(rec, data->attrId, data->dtd, val);
+ if (!len)
+ sdp_attr_add_new(rec, data->attrId, data->dtd, val);
+ else
+ sdp_attr_add_new_with_length(rec, data->attrId,
+ data->dtd, val, len);
}
sdp_record_t *sdp_copy_record(sdp_record_t *rec)
@@ -2068,6 +2077,20 @@ int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd,
return -1;
}
+static int sdp_attr_add_new_with_length(sdp_record_t *rec,
+ uint16_t attr, uint8_t dtd, const void *value, uint32_t len)
+{
+ sdp_data_t *d;
+
+ d = sdp_data_alloc_with_length(dtd, value, len);
+ if (!d)
+ return -1;
+
+ sdp_attr_replace(rec, attr, d);
+
+ return 0;
+}
+
/*
* Set the information attributes of the service
* pointed to by rec. The attributes are