From c88c2881cc73892403338ac4adf3439b0754fafb Mon Sep 17 00:00:00 2001 From: Alexandr Lyapunov <a.lyapunov@corp.mail.ru> Date: Tue, 10 Feb 2015 16:19:29 +0300 Subject: [PATCH] Fixed hash index bug, that could lead to crash; added test. --- src/box/memtx_hash.cc | 9 +++------ src/lib/salad/light.h | 5 +++++ test/big/hash.result | 20 ++++++++++++++++++++ test/big/hash.test.lua | 7 +++++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/box/memtx_hash.cc b/src/box/memtx_hash.cc index 0b6a90e12b..4afad8dac1 100644 --- a/src/box/memtx_hash.cc +++ b/src/box/memtx_hash.cc @@ -170,13 +170,10 @@ hash_iterator_ge(struct iterator *ptr) assert(ptr->free == hash_iterator_free); struct hash_iterator *it = (struct hash_iterator *) ptr; - if (it->h_pos < it->hash_table->table_size) { - struct tuple *res = light_index_get(it->hash_table, it->h_pos); + while (it->h_pos < it->hash_table->table_size) { + if (light_index_pos_valid(it->hash_table, it->h_pos)) + return light_index_get(it->hash_table, it->h_pos++); it->h_pos++; - while (it->h_pos < it->hash_table->table_size - && !light_index_pos_valid(it->hash_table, it->h_pos)) - it->h_pos++; - return res; } return NULL; } diff --git a/src/lib/salad/light.h b/src/lib/salad/light.h index bd3c139ccf..074f15cafe 100644 --- a/src/lib/salad/light.h +++ b/src/lib/salad/light.h @@ -234,6 +234,7 @@ LIGHT(delete)(struct LIGHT(core) *ht, uint32_t slotpos); * @brief Get a value from a desired position * @param ht - pointer to a hash table struct * @param slotpos - ID of an record + * ID must be vaild, check it by light_pos_valid (asserted). */ LIGHT_DATA_TYPE LIGHT(get)(struct LIGHT(core) *ht, uint32_t slotpos); @@ -242,6 +243,7 @@ LIGHT(get)(struct LIGHT(core) *ht, uint32_t slotpos); * @brief Determine if posision holds a value * @param ht - pointer to a hash table struct * @param slotpos - ID of an record + * ID must be in valid range [0, ht->table_size) (asserted). */ bool LIGHT(pos_valid)(struct LIGHT(core) *ht, uint32_t slotpos); @@ -667,8 +669,10 @@ LIGHT(delete_value)(struct LIGHT(core) *ht, uint32_t hash, LIGHT_DATA_TYPE value inline LIGHT_DATA_TYPE LIGHT(get)(struct LIGHT(core) *ht, uint32_t slotpos) { + assert(slotpos < ht->table_size); struct LIGHT(record) *record = (struct LIGHT(record) *) matras_get(&ht->mtable, slotpos); + assert(record->next != slotpos); return record->value; } @@ -680,6 +684,7 @@ LIGHT(get)(struct LIGHT(core) *ht, uint32_t slotpos) inline bool LIGHT(pos_valid)(LIGHT(core) *ht, uint32_t slotpos) { + assert(slotpos < ht->table_size); struct LIGHT(record) *record = (struct LIGHT(record) *) matras_get(&ht->mtable, slotpos); return record->next != slotpos; diff --git a/test/big/hash.result b/test/big/hash.result index da96ab72e5..f1120fcfae 100644 --- a/test/big/hash.result +++ b/test/big/hash.result @@ -674,3 +674,23 @@ hash.index['field3']:get{0} hash:drop() --- ... +hash = box.schema.create_space('tweedledum') +--- +... +hi = hash:create_index('primary', { type = 'hash', parts = {1, 'num'}, unique = true }) +--- +... +hash:insert{0} +--- +- [0] +... +hash:insert{16} +--- +- [16] +... +for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end +--- +... +hash:drop() +--- +... diff --git a/test/big/hash.test.lua b/test/big/hash.test.lua index 7abc2a8436..a3dbb69b39 100644 --- a/test/big/hash.test.lua +++ b/test/big/hash.test.lua @@ -288,3 +288,10 @@ hash.index['field3']:get{10} hash.index['field3']:get{0} hash:drop() + +hash = box.schema.create_space('tweedledum') +hi = hash:create_index('primary', { type = 'hash', parts = {1, 'num'}, unique = true }) +hash:insert{0} +hash:insert{16} +for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end +hash:drop() -- GitLab