summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-05-26 09:28:23 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-05-26 09:28:23 +0900
commit636c8b48c7da345eeb58b0eb0f436e0386e46e6f (patch)
treed276a2282f2015f1d0cad5ad622c67f6cc8b9e41
parent03c42fd2cb523dad5602d1f5623069ea12560d9a (diff)
downloadefl-636c8b48c7da345eeb58b0eb0f436e0386e46e6f.tar.gz
eina hash - fix stringshare key comparison function
this fixes T3638 @fix a note... thanks so much to aerodynamik for spotting this. i'm rather surprised coverity didn't spot this... unless someone said to "shut up coverity you're wrong" and they should not have. i also might have expected compilers to spot this too... and add a warning. anyway ... this was a seriously subtle bug that could have caused all kinds of havoc in efl. keys that are different may be compared to be the same. it could get ordering wrong and sorting thus maybe insert keys that cannot be found anymore and oh so much more besides.
-rw-r--r--src/lib/eina/eina_hash.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/lib/eina/eina_hash.c b/src/lib/eina/eina_hash.c
index f950b19f7d..ed155e5513 100644
--- a/src/lib/eina/eina_hash.c
+++ b/src/lib/eina/eina_hash.c
@@ -508,7 +508,22 @@ static int
_eina_stringshared_key_cmp(const char *key1, EINA_UNUSED int key1_length,
const char *key2, EINA_UNUSED int key2_length)
{
- return key1 - key2;
+// logically we want to do this:
+// return key1 - key2;
+// but since they are ptrs and an int can't store the different of 2 ptrs in
+// either 32 or 64bit (signed hasn't got enough range for the diff of 2
+// 32bit values regardless of their type... we'd need 33bits or 65bits)
+// so do this...
+ if (key1 == key2) return 0;
+ if (key1 > key2) return 1;
+ return -1;
+// NOTE: this seems odd. we don't sort by string content at all... we sort
+// by pointer location in memory. this seems odd at first, BUT this does
+// work because with stringshare each ptr holds a unique string and we
+// cannot have 2 ptrs in stringshare have the same string content thus we
+// can't go wrong and have 2 ptrs be different yet the string key be the
+// same, thus we can avoid walking the string, so sorting by ptr value is
+// frankly as good as anything. :) (this is only within the bucket too)
}
static unsigned int