1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-13 14:27:08 +03:00

0030550: Coding - Integer overflow in Standard_CString HashCodes

0030551: Foundation Classes - Integer overflow in NCollection_CellFilter HashCode

Signed integers are not used in hash code functions now to prevent undefined behavior on left shift operations with signed integers.
A possibility of negative values of hash codes is eliminated.
INT_MAX → IntegerLast() in hash code functions.
All found hash code functions behaves uniformly now: they return a value in the range [1, theUpperBound]. Relevant comments are added to such functions.
This commit is contained in:
tiv
2019-03-28 12:42:41 +03:00
committed by bugmaster
parent 833034f301
commit 2b2be3fb82
89 changed files with 878 additions and 580 deletions

View File

@@ -15,6 +15,7 @@
#ifndef _Standard_Integer_HeaderFile
#define _Standard_Integer_HeaderFile
#include <Standard_Std.hxx>
#include <Standard_TypeDef.hxx>
#include <Standard_values.h>
@@ -30,54 +31,6 @@ inline Standard_Integer Abs (const Standard_Integer Value)
return Value >= 0 ? Value : -Value;
}
// ------------------------------------------------------------------
// Hascode : Computes a hascoding value for a given Integer
// ------------------------------------------------------------------
inline Standard_Integer HashCode (const Standard_Integer theMe,
const Standard_Integer theUpper)
{
//return (Abs (theMe) % theUpper) + 1;
return ((theMe & 0x7fffffff ) % theUpper) + 1;
}
// ------------------------------------------------------------------
// IsEqual : Returns Standard_True if two integers are equal
// ------------------------------------------------------------------
inline Standard_Boolean IsEqual (const Standard_Integer theOne,
const Standard_Integer theTwo)
{
return theOne == theTwo;
}
// ------------------------------------------------------------------
// Hascode : Computes a hascoding value for a given long long integer
// ------------------------------------------------------------------
inline Standard_Integer HashCode(const long long int theMe,
const Standard_Integer theUpper)
{
return ((theMe & 0x7fffffffffffffff) % theUpper) + 1;
}
#if (defined(_LP64) || defined(__LP64__) || defined(_WIN64)) || defined(__APPLE__)
// ------------------------------------------------------------------
// Hascode : Computes a hascoding value for a given unsigned integer
// ------------------------------------------------------------------
inline Standard_Integer HashCode (const Standard_Utf32Char theMe,
const Standard_Integer theUpper)
{
return ((theMe & 0x7fffffff ) % theUpper) + 1;
}
// ------------------------------------------------------------------
// IsEqual : Returns Standard_True if two integers are equal
// ------------------------------------------------------------------
inline Standard_Boolean IsEqual (const Standard_Utf32Char theOne,
const Standard_Utf32Char theTwo)
{
return theOne == theTwo;
}
#endif
// ------------------------------------------------------------------
// IsEven : Returns Standard_True if an integer is even
// ------------------------------------------------------------------
@@ -140,4 +93,87 @@ inline Standard_Integer IntegerLast()
inline Standard_Integer IntegerSize()
{ return BITS(Standard_Integer); }
//! Computes a hash code for the given value of some integer type, in range [1, theUpperBound]
//! @tparam TheInteger the type of the integer which hash code is to be computed
//! @param theValue the value of the TheInteger type which hash code is to be computed
//! @param theMask the mask for the last bits of the value that are used in the computation of a hash code
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in range [1, theUpperBound]
template <typename TheInteger>
typename opencascade::std::enable_if<opencascade::is_integer<TheInteger>::value, Standard_Integer>::type
IntegerHashCode (const TheInteger theValue,
const typename opencascade::disable_deduction<TheInteger>::type theMask,
const Standard_Integer theUpperBound)
{
return static_cast<Standard_Integer> ((theValue & theMask) % theUpperBound + 1);
}
//! Computes a hash code for the given value of the Standard_Integer type, in range [1, theUpperBound]
//! @param theValue the value of the Standard_Integer type which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in range [1, theUpperBound]
inline Standard_Integer HashCode (const Standard_Integer theValue,
const Standard_Integer theUpperBound)
{
// return (Abs (theMe) % theUpper) + 1;
return IntegerHashCode(theValue, IntegerLast(), theUpperBound);
}
// ------------------------------------------------------------------
// IsEqual : Returns Standard_True if two integers are equal
// ------------------------------------------------------------------
inline Standard_Boolean IsEqual (const Standard_Integer theOne,
const Standard_Integer theTwo)
{
return theOne == theTwo;
}
//! Computes a hash value for the given unsigned integer, in range [1, theUpperBound]
//! @tparam TheUnsignedInteger the type of the given value (it is "unsigned int",
//! and must not be the same as Standard_Size, because the overload of the HashCode function
//! for Standard_Size type is already presented in Standard_Size.hxx)
//! @param theValue the unsigned integer which hash code is to be computed
//! @return a hash value computed for the given unsigned integer, in range [1, theUpperBound]
template <typename TheUnsignedInteger>
typename opencascade::std::enable_if<!opencascade::std::is_same<Standard_Size, unsigned int>::value
&& opencascade::std::is_same<TheUnsignedInteger, unsigned int>::value,
Standard_Integer>::type
HashCode (const TheUnsignedInteger theValue, const Standard_Integer theUpperBound)
{
return HashCode (static_cast<Standard_Integer> (theValue), theUpperBound);
}
//! Computes a hash code for the given value of the "long long int" type, in range [1, theUpperBound]
//! @param theValue the value of the "long long int" type which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in range [1, theUpperBound]
inline Standard_Integer HashCode (const long long int theValue, const Standard_Integer theUpperBound)
{
return IntegerHashCode(theValue, 0x7fffffffffffffff, theUpperBound);
}
#if (defined(_LP64) || defined(__LP64__) || defined(_WIN64)) || defined(__APPLE__)
//! Computes a hash code for the given value of the Standard_Utf32Char type, in range [1, theUpperBound]
//! @param theValue the value of the Standard_Utf32Char type which hash code is to be computed
//! @param theUpperBound the upper bound of the range a computing hash code must be within
//! @return a computed hash code, in range [1, theUpperBound]
inline Standard_Integer HashCode (const Standard_Utf32Char theValue,
const Standard_Integer theUpperBound)
{
return IntegerHashCode(theValue, IntegerLast(), theUpperBound);
}
// ------------------------------------------------------------------
// IsEqual : Returns Standard_True if two integers are equal
// ------------------------------------------------------------------
inline Standard_Boolean IsEqual (const Standard_Utf32Char theOne,
const Standard_Utf32Char theTwo)
{
return theOne == theTwo;
}
#endif
#endif