[Asterisk-code-review] core/general: avoid overflows in the string hash functions (asterisk[13])

Torrey Searle asteriskteam at digium.com
Fri Apr 7 09:04:35 CDT 2017


Torrey Searle has uploaded a new change for review. ( https://gerrit.asterisk.org/5425 )

Change subject: core/general:  avoid overflows in the string hash functions
......................................................................

core/general:  avoid overflows in the string hash functions

on 2's compliment machines abx(INT_MIN) behavior is undefined and
results in a negative value still being returnd.  This results in
negative hash codes that can result in crashes

ASTERISK-26528 #close

Change-Id: Idff550145ca2133792a61a2e212b4a3e82c6517b
---
M include/asterisk/strings.h
1 file changed, 25 insertions(+), 9 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/25/5425/1

diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h
index eb5b4e4..35de747 100644
--- a/include/asterisk/strings.h
+++ b/include/asterisk/strings.h
@@ -26,6 +26,7 @@
 /* #define DEBUG_OPAQUE */
 
 #include <ctype.h>
+#include <limits.h>
 
 #include "asterisk/utils.h"
 #include "asterisk/threadstorage.h"
@@ -1174,6 +1175,19 @@
 )
 
 /*!
+ * \brief Restrict hash value range
+ * 
+ * Hash values used all over asterisk are expected to be non-
+ * negative (signed) int values.
+ * This function restricts an unsigned int hash value to the positive
+ * half of the (signed) int values.
+ */
+static force_inline int attribute_pure ast_str_hash_restrict(unsigned int uhash)
+{
+	return ((int) (uhash & ((unsigned int) INT_MAX)));
+}
+
+/*!
  * \brief Compute a hash value on a string
  *
  * This famous hash algorithm was written by Dan Bernstein and is
@@ -1183,12 +1197,12 @@
  */
 static force_inline int attribute_pure ast_str_hash(const char *str)
 {
-	int hash = 5381;
+	unsigned int uhash = 5381;
 
 	while (*str)
-		hash = hash * 33 ^ *str++;
+		uhash = uhash * 33 ^ *str++;
 
-	return abs(hash);
+	return ast_str_hash_restrict(uhash);
 }
 
 /*!
@@ -1208,10 +1222,12 @@
  */
 static force_inline int ast_str_hash_add(const char *str, int hash)
 {
-	while (*str)
-		hash = hash * 33 ^ *str++;
+	unsigned int uhash = (unsigned int) hash;
 
-	return abs(hash);
+	while (*str)
+		uhash = uhash * 33 ^ *str++;
+
+	return ast_str_hash_restrict(uhash);
 }
 
 /*!
@@ -1223,13 +1239,13 @@
  */
 static force_inline int attribute_pure ast_str_case_hash(const char *str)
 {
-	int hash = 5381;
+	unsigned int uhash = 5381;
 
 	while (*str) {
-		hash = hash * 33 ^ tolower(*str++);
+		uhash = uhash * 33 ^ tolower(*str++);
 	}
 
-	return abs(hash);
+	return ast_str_hash_restrict(uhash);
 }
 
 /*!

-- 
To view, visit https://gerrit.asterisk.org/5425
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idff550145ca2133792a61a2e212b4a3e82c6517b
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: Torrey Searle <tsearle at gmail.com>



More information about the asterisk-code-review mailing list