diff options
author | Alan Antonuk <alan.antonuk@gmail.com> | 2013-07-10 10:29:42 -0700 |
---|---|---|
committer | Alan Antonuk <alan.antonuk@gmail.com> | 2013-07-10 10:29:42 -0700 |
commit | 7942af3ac63cfc86090dbc8a70c5bd0673ac30cf (patch) | |
tree | 282993ff3972a5a6123adfd75eb342d75295d10b | |
parent | 7a217d59484e405685426f9e7508b2e78280268d (diff) | |
download | rabbitmq-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.c | 43 |
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) { |