summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Lewandowski <tomasz.lewandoski@delphi.com>2016-12-02 03:46:14 -0800
committerIngo Huerner <ingo_huerner@mentor.com>2016-12-05 14:34:39 +0100
commit4e39784a0de1f2f30e1afb3cde3776dbdc4e2cac (patch)
treea28abf8ebc18ebb5523d345b2af828dd13e62966
parent395b0f504e05ee6c59c1b9d9267c793e072a19ba (diff)
downloadpersistence-common-object-4e39784a0de1f2f30e1afb3cde3776dbdc4e2cac.tar.gz
Fix crash in KISSDB_IteratorNext caused by problem with handling deleted items. [IHU-12393]
Change-Id: I0b072d5d0cec636102823390de9ef1ccef7b24e5 Signed-off-by: Tomasz Lewandowski <tomasz.lewandoski@delphi.com>
-rw-r--r--src/key-value-store/database/kissdb.c24
-rw-r--r--src/key-value-store/database/kissdb.h15
-rw-r--r--src/key-value-store/pers_low_level_db_access.c21
3 files changed, 46 insertions, 14 deletions
diff --git a/src/key-value-store/database/kissdb.c b/src/key-value-store/database/kissdb.c
index 7c0695d..70feeef 100644
--- a/src/key-value-store/database/kissdb.c
+++ b/src/key-value-store/database/kissdb.c
@@ -1310,6 +1310,7 @@ int KISSDB_Iterator_next(KISSDB_Iterator* dbi, void* kbuf, void* vbuf)
{
DataBlock_s* block;
Hashtable_slot_s* ht;
+ int retVal = KISSDB_ITERATOR_NEXT_ITEM_NOT_FOUND;
int64_t offset;
if(dbi->db->htMappedSize < dbi->db->shared->htShmSize)
@@ -1347,7 +1348,7 @@ int KISSDB_Iterator_next(KISSDB_Iterator* dbi, void* kbuf, void* vbuf)
dbi->h_idx = 0;
if (++dbi->h_no >= (dbi->db->shared->htNum))
{
- return 0;
+ return KISSDB_ITERATOR_NEXT_ITEM_NOT_FOUND;//0
}
else
{
@@ -1369,20 +1370,29 @@ int KISSDB_Iterator_next(KISSDB_Iterator* dbi, void* kbuf, void* vbuf)
return KISSDB_ERROR_IO;
}
- block = (DataBlock_s*) (dbi->db->mappedDb + offset);
- memcpy(kbuf,block->key, dbi->db->keySize);
- if (vbuf != NULL)
+ retVal = KISSDB_ITERATOR_NEXT_ITEM_FOUND;
+ if (offset >= 0)
+ {
+ block = (DataBlock_s*) (dbi->db->mappedDb + offset);
+ memcpy(kbuf,block->key, dbi->db->keySize);
+
+ if (vbuf != NULL)
+ {
+ memcpy(vbuf, block->value, dbi->db->valSize);
+ }
+ }
+ else
{
- memcpy(vbuf, block->value, dbi->db->valSize);
+ retVal = KISSDB_ITERATOR_DELETED_ITEM;
}
if (++dbi->h_idx >= dbi->db->htSize)
{
dbi->h_idx = 0;
++dbi->h_no;
}
- return 1;
+ return retVal;//1
}
- return 0;
+ return KISSDB_ITERATOR_NEXT_ITEM_NOT_FOUND;//0
}
diff --git a/src/key-value-store/database/kissdb.h b/src/key-value-store/database/kissdb.h
index 582e786..949f468 100644
--- a/src/key-value-store/database/kissdb.h
+++ b/src/key-value-store/database/kissdb.h
@@ -171,6 +171,20 @@ typedef struct {
int fd; //local fd
} KISSDB;
+/**
+ * Next item not found
+ */
+#define KISSDB_ITERATOR_NEXT_ITEM_NOT_FOUND 0
+
+/**
+ * Next item found
+ */
+#define KISSDB_ITERATOR_NEXT_ITEM_FOUND 1
+
+/**
+ * deleted or invalidated data found
+ */
+#define KISSDB_ITERATOR_DELETED_ITEM 2
/**
* I/O error or file not found
@@ -231,6 +245,7 @@ typedef struct {
* buffer where data should be returned is too small
*/
#define KISSDB_ERROR_WRONG_BUFSIZE -13
+
/**
* Open mode: read only
diff --git a/src/key-value-store/pers_low_level_db_access.c b/src/key-value-store/pers_low_level_db_access.c
index c01243e..d5f5d3c 100644
--- a/src/key-value-store/pers_low_level_db_access.c
+++ b/src/key-value-store/pers_low_level_db_access.c
@@ -2156,6 +2156,7 @@ sint_t getListandSize(KISSDB* db, pstr_t buffer, sint_t size, bool_t bOnlySizeNe
qnobj_t obj;
sint_t availableSize = size;
void* pt;
+ int iter_ret_val;
int keylength = (purpose == PersLldbPurpose_RCT) ? PERS_RCT_MAX_LENGTH_RESOURCE_ID : PERS_DB_MAX_LENGTH_KEY_NAME;
char kbuf[PERS_DB_MAX_LENGTH_KEY_NAME];
@@ -2203,10 +2204,13 @@ sint_t getListandSize(KISSDB* db, pstr_t buffer, sint_t size, bool_t bOnlySizeNe
//look for keys in database file
//Initialise database iterator
KISSDB_Iterator_init(db, &dbi);
- //get number of keys, stored in database file
- while (KISSDB_Iterator_next(&dbi, &kbuf, NULL) > 0)
+ //get number of keys, stored in database file
+ while ( (iter_ret_val = KISSDB_Iterator_next(&dbi, &kbuf, NULL)) > 0)
{
- keyCountFile++;
+ if (iter_ret_val == KISSDB_ITERATOR_NEXT_ITEM_FOUND)
+ {
+ keyCountFile++;
+ }
}
if ((keyCountCache + keyCountFile) > 0)
@@ -2238,12 +2242,15 @@ sint_t getListandSize(KISSDB* db, pstr_t buffer, sint_t size, bool_t bOnlySizeNe
//put keys in database file to hashtable (existing key gets overwritten -> no duplicate keys)
KISSDB_Iterator_init(db, &dbi);
memset(kbuf, 0, keylength);
- while (KISSDB_Iterator_next(&dbi, &kbuf, NULL) > 0)
+ while ( (iter_ret_val = KISSDB_Iterator_next(&dbi, &kbuf, NULL)) > 0)
{
- size_t keyLen = strnlen(kbuf, sizeof(kbuf));
- if (keyLen > 0)
+ if (iter_ret_val == KISSDB_ITERATOR_NEXT_ITEM_FOUND)
{
- tbl->put(tbl, kbuf, "0", 1);
+ size_t keyLen = strnlen(kbuf, sizeof(kbuf));
+ if (keyLen > 0)
+ {
+ tbl->put(tbl, kbuf, "0", 1);
+ }
}
}