[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: (ITS#7816) Bug in LMDB's mdb_cmp_memn[r] functions



dror.harari@gmail.com wrote:
> Full_Name: Dror Harari
> Version:
> OS: Windows 7 64bit
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (79.181.198.22)
>
>
> The default compare functions start with:
>
> mdb_cmp_memn(const MDB_val *a, const MDB_val *b)
> {
> 	int diff;
> 	ssize_t len_diff;
> 	unsigned int len;
>
> 	len = a->mv_size;
> 	len_diff = (ssize_t) a->mv_size - (ssize_t) b->mv_size;
> 	if (len_diff > 0) {
>
> This code assumes that ssize_t is signed and in all normal platforms it is.
> However, on Windows Visal Studio 2010 (did not check others) it is defined as:
>
> #ifndef _SSIZE_T_DEFINED
> #ifdef  _WIN64
> typedef unsigned __int64    ssize_t;
> #else
> typedef _W64 unsigned int   ssize_t;
> #endif
> #define _SSIZE_T_DEFINED
> #endif
>
> So it is unsigned and len_diff would never become <0.

If this is true, then you've found a bug in MSVC. The extra S in "SSIZE_T" 
means "signed." This is part of the C standard, and even the Microsoft 
documentation agrees with the standard (for once).

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751%28v=vs.85%29.aspx

You should file a bug report with Microsoft. Closing this ITS.

>
> There's a workaround to defined a custom compare function but one can rewrite
> the default compare around this bug (that is, avoiding subtraction).
>
> This issue was detected with SET_KEY_RANGE on a key value of 00 00 00 02 where
> the database had keys:
> 00 00 00 01 65
> 00 00 00 02 65
> 00 00 00 03 65
>
> Instead of getting the 00 00 00 02 65, the code returns 00 00 00 03 65
>
>


-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/