Commit 336c8106 authored by V Narayanan's avatar V Narayanan

Bug#43572 Handle failures from hash_init

      
Failure to allocate memory for the hash->array element,
caused hash_init to return without initializing the other
members of the hash. Thus although the dynamic array
buffer may be allocated at a later point in the code, the
incompletely initialized hash caused fatal failures.

This patch moves the initialization of the other members
of the hash above the array allocation, so that the usage
of this hash will not result in fatal failures.

include/hash.h:
  Bug#43572 Handle failures from hash_init
  
  hash_inited is used to verify that the hash is
  valid. After the change induced by the current
  patch hash->array.buffer !=0 is not a valid check
  for this condition, since, the dynamic array can
  be allocated even at a later time. Bootstrap SQL
  script is setting some variables, which are
  actually not set due to this hash_inited issue.
  Thus we get empty grant tables.
  
  A better way to check if the hash is valid is
  to verify that hash->blength is greater than 0.
mysys/hash.c:
  Bug#43572 Handle failures from hash_init
  
  Move the initialization of the other members
  of the hash above the array allocation, so that
  the usage of this hash will not result in fatal
  failures.
parent 37d2019d
...@@ -63,7 +63,7 @@ void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, byte *new_row); ...@@ -63,7 +63,7 @@ void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, byte *new_row);
my_bool hash_check(HASH *hash); /* Only in debug library */ my_bool hash_check(HASH *hash); /* Only in debug library */
#define hash_clear(H) bzero((char*) (H),sizeof(*(H))) #define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
#define hash_inited(H) ((H)->array.buffer != 0) #define hash_inited(H) ((H)->blength != 0)
#define hash_init_opt(A,B,C,D,E,F,G,H) \ #define hash_init_opt(A,B,C,D,E,F,G,H) \
(!hash_inited(A) && _hash_init(A,B,C,D,E,F,G, H CALLER_INFO)) (!hash_inited(A) && _hash_init(A,B,C,D,E,F,G, H CALLER_INFO))
......
...@@ -45,6 +45,32 @@ static uint calc_hash(const HASH *hash, const byte *key, uint length) ...@@ -45,6 +45,32 @@ static uint calc_hash(const HASH *hash, const byte *key, uint length)
return nr1; return nr1;
} }
/**
@brief Initialize the hash
@details
Initialize the hash, by defining and giving valid values for
its elements. The failure to allocate memory for the
hash->array element will not result in a fatal failure. The
dynamic array that is part of the hash will allocate memory
as required during insertion.
@param[in,out] hash The hash that is initialized
@param[in] charset The charater set information
@param[in] size The hash size
@param[in] key_offest The key offset for the hash
@param[in] key_length The length of the key used in
the hash
@param[in] get_key get the key for the hash
@param[in] free_element pointer to the function that
does cleanup
@param[in] CALLER_INFO_PROTO flag that define the behaviour
of the hash
@return inidicates success or failure of initialization
@retval 0 success
@retval 1 failure
*/
my_bool my_bool
_hash_init(HASH *hash,CHARSET_INFO *charset, _hash_init(HASH *hash,CHARSET_INFO *charset,
uint size,uint key_offset,uint key_length, uint size,uint key_offset,uint key_length,
...@@ -55,11 +81,6 @@ _hash_init(HASH *hash,CHARSET_INFO *charset, ...@@ -55,11 +81,6 @@ _hash_init(HASH *hash,CHARSET_INFO *charset,
DBUG_PRINT("enter",("hash: 0x%lx size: %d", (long) hash, size)); DBUG_PRINT("enter",("hash: 0x%lx size: %d", (long) hash, size));
hash->records=0; hash->records=0;
if (my_init_dynamic_array_ci(&hash->array,sizeof(HASH_LINK),size,0))
{
hash->free=0; /* Allow call to hash_free */
DBUG_RETURN(1);
}
hash->key_offset=key_offset; hash->key_offset=key_offset;
hash->key_length=key_length; hash->key_length=key_length;
hash->blength=1; hash->blength=1;
...@@ -67,7 +88,8 @@ _hash_init(HASH *hash,CHARSET_INFO *charset, ...@@ -67,7 +88,8 @@ _hash_init(HASH *hash,CHARSET_INFO *charset,
hash->free=free_element; hash->free=free_element;
hash->flags=flags; hash->flags=flags;
hash->charset=charset; hash->charset=charset;
DBUG_RETURN(0); DBUG_RETURN(my_init_dynamic_array_ci(&hash->array,
sizeof(HASH_LINK), size, 0));
} }
...@@ -113,6 +135,7 @@ void hash_free(HASH *hash) ...@@ -113,6 +135,7 @@ void hash_free(HASH *hash)
hash_free_elements(hash); hash_free_elements(hash);
hash->free= 0; hash->free= 0;
delete_dynamic(&hash->array); delete_dynamic(&hash->array);
hash->blength= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment