summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Antonuk <alan.antonuk@gmail.com>2013-07-10 10:29:42 -0700
committerAlan Antonuk <alan.antonuk@gmail.com>2013-07-10 10:29:42 -0700
commit7942af3ac63cfc86090dbc8a70c5bd0673ac30cf (patch)
tree282993ff3972a5a6123adfd75eb342d75295d10b
parent7a217d59484e405685426f9e7508b2e78280268d (diff)
downloadrabbitmq-c-github-ask-7942af3ac63cfc86090dbc8a70c5bd0673ac30cf.tar.gz
FIX: amqp_table_clone handle 0-len table correctly
amqp_pool_alloc_bytes() has undefined behavior when a 0-length buffer is allocated. Properly handles cases where 0-length tables or buffers are encountered when cloning a table. This fixes #127
-rw-r--r--librabbitmq/amqp_table.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/librabbitmq/amqp_table.c b/librabbitmq/amqp_table.c
index d9ac939..6fa6fd3 100644
--- a/librabbitmq/amqp_table.c
+++ b/librabbitmq/amqp_table.c
@@ -522,24 +522,32 @@ amqp_field_value_clone(amqp_field_value_t *original, amqp_field_value_t *clone,
case AMQP_FIELD_KIND_UTF8:
case AMQP_FIELD_KIND_BYTES:
- amqp_pool_alloc_bytes(pool, original->value.bytes.len, &clone->value.bytes);
- if (NULL == clone->value.bytes.bytes) {
- return AMQP_STATUS_NO_MEMORY;
+ if (0 == original->value.bytes.len) {
+ clone->value.bytes = amqp_empty_bytes;
+ } else {
+ amqp_pool_alloc_bytes(pool, original->value.bytes.len, &clone->value.bytes);
+ if (NULL == clone->value.bytes.bytes) {
+ return AMQP_STATUS_NO_MEMORY;
+ }
+ memcpy(clone->value.bytes.bytes, original->value.bytes.bytes, clone->value.bytes.len);
}
- memcpy(clone->value.bytes.bytes, original->value.bytes.bytes, clone->value.bytes.len);
break;
case AMQP_FIELD_KIND_ARRAY:
- clone->value.array.num_entries = original->value.array.num_entries;
- clone->value.array.entries = amqp_pool_alloc(pool, clone->value.array.num_entries * sizeof(amqp_field_value_t));
- if (NULL == clone->value.array.entries) {
- return AMQP_STATUS_NO_MEMORY;
- }
+ if (0 == original->value.array.entries) {
+ clone->value.array = amqp_empty_array;
+ } else {
+ clone->value.array.num_entries = original->value.array.num_entries;
+ clone->value.array.entries = amqp_pool_alloc(pool, clone->value.array.num_entries * sizeof(amqp_field_value_t));
+ if (NULL == clone->value.array.entries) {
+ return AMQP_STATUS_NO_MEMORY;
+ }
- for (i = 0; i < clone->value.array.num_entries; ++i) {
- res = amqp_field_value_clone(&original->value.array.entries[i], &clone->value.array.entries[i], pool);
- if (AMQP_STATUS_OK != res) {
- return res;
+ for (i = 0; i < clone->value.array.num_entries; ++i) {
+ res = amqp_field_value_clone(&original->value.array.entries[i], &clone->value.array.entries[i], pool);
+ if (AMQP_STATUS_OK != res) {
+ return res;
+ }
}
}
break;
@@ -561,6 +569,10 @@ amqp_field_value_clone(amqp_field_value_t *original, amqp_field_value_t *clone,
static int
amqp_table_entry_clone(amqp_table_entry_t *original, amqp_table_entry_t *clone, amqp_pool_t *pool)
{
+ if (0 == original->key.len) {
+ return AMQP_STATUS_INVALID_PARAMETER;
+ }
+
amqp_pool_alloc_bytes(pool, original->key.len, &clone->key);
if (NULL == clone->key.bytes) {
return AMQP_STATUS_NO_MEMORY;
@@ -577,6 +589,11 @@ amqp_table_clone(amqp_table_t *original, amqp_table_t *clone, amqp_pool_t *pool)
int i;
int res;
clone->num_entries = original->num_entries;
+ if (0 == clone->num_entries) {
+ *clone = amqp_empty_table;
+ return AMQP_STATUS_OK;
+ }
+
clone->entries = amqp_pool_alloc(pool, clone->num_entries * sizeof(amqp_table_entry_t));
if (NULL == clone->entries) {