< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index  

Re: [reSIProcate] Data::*hash() not working on binary data


FYI - Byron has committed this fix in SVN.  Thanks Bruce.

> -----Original Message-----
> From: resiprocate-devel-bounces@xxxxxxxxxxxxxxxxxxx
> [mailto:resiprocate-devel-bounces@xxxxxxxxxxxxxxxxxxx] On Behalf Of
> Bruce Lowekamp
> Sent: Monday, August 07, 2006 6:31 PM
> To: resiprocate
> Cc: Tiffany Broadbent
> Subject: [reSIProcate] Data::*hash() not working on binary data
> 
> We tracked down a bug with Data that prevents it from calculating
> hashes on binary data (really any Data with characters above 0x7f).
> Since rawHash and rawCaseInsensitiveHash take const char* (signed), do
> arithmetic on those characters, and use the result as an array
> subscript, the subscript gets promoted to int and it winds up using
the
> values randomPermutation[-255,255] in the hash.  On Mac OS, the system
> happens to leave the memory region preceding randomPermutation zeroed,
> so if the last character in the Data was negative, the hash would
> always be zero (which is what started Tiffany looking at this
problem).
> On an x86 FC5 platform, the bug isn't as noticeable unless you add
> something like:
>       cout << (*c ^ bytes[0]) << " "
>          << (*c ^ bytes[1]) << " "
>          << (*c ^ bytes[2]) << " "
>          << (*c ^ bytes[3]) << endl;
> to the inner loop of rawHash()
> 
> anyway, a patch is below which fixes the problem by simply casting the
> char* c parameter to be an unsigned char* before calculating the hash.
> 
> Bruce
> 
> -----------------
> 
> Index: Data.cxx
> ===================================================================
> --- Data.cxx    (revision 610)
> +++ Data.cxx    (working copy)
> @@ -1837,10 +1837,11 @@
>  };
> 
>  size_t
> -Data::rawHash(const char* c, size_t size)
> +Data::rawHash(const char* cx, size_t size)
>  {
>     // 4 byte Pearson's hash
>     // essentially random hashing
> +   const unsigned char* c = (const unsigned char*) cx;
> 
>     union
>     {
> @@ -1853,7 +1854,7 @@
>     bytes[2] = randomPermutation[2];
>     bytes[3] = randomPermutation[3];
> 
> -   const char* end = c + size;
> +   const unsigned char* end = c + size;
>     for ( ; c != end; ++c)
>     {
>        bytes[0] = randomPermutation[*c ^ bytes[0]]; @@ -1868,8 +1869,9
> @@
> 
>  // use only for ascii characters!
>  size_t
> -Data::rawCaseInsensitiveHash(const char* c, size_t size)
> +Data::rawCaseInsensitiveHash(const char* cx, size_t size)
>  {
> +   const unsigned char* c = (const unsigned char*) cx;
>     union
>     {
>           size_t st;
> @@ -1881,10 +1883,10 @@
>     bytes[2] = randomPermutation[2];
>     bytes[3] = randomPermutation[3];
> 
> -   const char* end = c + size;
> +   const unsigned char* end = c + size;
>     for ( ; c != end; ++c)
>     {
> -      char cc = tolower(*c);
> +      unsigned char cc = tolower(*c);
>        bytes[0] = randomPermutation[cc ^ bytes[0]];
>        bytes[1] = randomPermutation[cc ^ bytes[1]];
>        bytes[2] = randomPermutation[cc ^ bytes[2]];
> _______________________________________________
> resiprocate-devel mailing list
> resiprocate-devel@xxxxxxxxxxxxxxxxxxx
> https://list.sipfoundry.org/mailman/listinfo/resiprocate-devel