Checked key_size in LSH table for validness (#2677)
authorIlya Lysenkov <lysenkov.ilya@gmail.com>
Thu, 31 Jan 2013 19:19:19 +0000 (23:19 +0400)
committerIlya Lysenkov <lysenkov.ilya@gmail.com>
Thu, 31 Jan 2013 19:19:19 +0000 (23:19 +0400)
modules/flann/include/opencv2/flann/lsh_table.h

index 126fb2a..a30642a 100644 (file)
@@ -261,6 +261,16 @@ private:
      */
     void initialize(size_t key_size)
     {
+        const size_t key_size_lower_bound = 1;
+        //a value (size_t(1) << key_size) must fit the size_t type so key_size has to be strictly less than size of size_t
+        const size_t key_size_upper_bound = std::min(sizeof(BucketKey) * CHAR_BIT + 1, sizeof(size_t) * CHAR_BIT);
+        if (key_size < key_size_lower_bound || key_size >= key_size_upper_bound)
+        {
+            std::stringstream errorMessage;
+            errorMessage << "Invalid key_size (=" << key_size << "). Valid values for your system are " << key_size_lower_bound << " <= key_size < " << key_size_upper_bound << ".";
+            CV_Error(CV_StsBadArg, errorMessage.str());
+        }
+
         speed_level_ = kHash;
         key_size_ = (unsigned)key_size;
     }
@@ -273,10 +283,10 @@ private:
         if (speed_level_ == kArray) return;
 
         // Use an array if it will be more than half full
-        if (buckets_space_.size() > (unsigned int)((1 << key_size_) / 2)) {
+        if (buckets_space_.size() > ((size_t(1) << key_size_) / 2)) {
             speed_level_ = kArray;
             // Fill the array version of it
-            buckets_speed_.resize(1 << key_size_);
+            buckets_speed_.resize(size_t(1) << key_size_);
             for (BucketsSpace::const_iterator key_bucket = buckets_space_.begin(); key_bucket != buckets_space_.end(); ++key_bucket) buckets_speed_[key_bucket->first] = key_bucket->second;
 
             // Empty the hash table
@@ -287,9 +297,9 @@ private:
         // If the bitset is going to use less than 10% of the RAM of the hash map (at least 1 size_t for the key and two
         // for the vector) or less than 512MB (key_size_ <= 30)
         if (((std::max(buckets_space_.size(), buckets_speed_.size()) * CHAR_BIT * 3 * sizeof(BucketKey)) / 10
-             >= size_t(1 << key_size_)) || (key_size_ <= 32)) {
+             >= (size_t(1) << key_size_)) || (key_size_ <= 32)) {
             speed_level_ = kBitsetHash;
-            key_bitset_.resize(1 << key_size_);
+            key_bitset_.resize(size_t(1) << key_size_);
             key_bitset_.reset();
             // Try with the BucketsSpace
             for (BucketsSpace::const_iterator key_bucket = buckets_space_.begin(); key_bucket != buckets_space_.end(); ++key_bucket) key_bitset_.set(key_bucket->first);