mariadb/include/hash.h
V Narayanan 336c810618 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.
2009-06-19 17:29:21 +05:30

73 lines
2.6 KiB
C

/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Dynamic hashing of record with different key-length */
#ifndef _hash_h
#define _hash_h
#ifdef __cplusplus
extern "C" {
#endif
/*
Overhead to store an element in hash
Can be used to approximate memory consumption for a hash
*/
#define HASH_OVERHEAD (sizeof(char*)*2)
typedef byte *(*hash_get_key)(const byte *,uint*,my_bool);
typedef void (*hash_free_key)(void *);
typedef struct st_hash {
uint key_offset,key_length; /* Length of key if const length */
uint records, blength;
uint flags;
DYNAMIC_ARRAY array; /* Place for hash_keys */
hash_get_key get_key;
void (*free)(void *);
CHARSET_INFO *charset;
} HASH;
/* A search iterator state */
typedef uint HASH_SEARCH_STATE;
#define hash_init(A,B,C,D,E,F,G,H) _hash_init(A,B,C,D,E,F,G, H CALLER_INFO)
my_bool _hash_init(HASH *hash, CHARSET_INFO *charset,
uint default_array_elements, uint key_offset,
uint key_length, hash_get_key get_key,
void (*free_element)(void*), uint flags CALLER_INFO_PROTO);
void hash_free(HASH *tree);
void my_hash_reset(HASH *hash);
byte *hash_element(HASH *hash,uint idx);
gptr hash_search(const HASH *info, const byte *key, uint length);
gptr hash_first(const HASH *info, const byte *key, uint length,
HASH_SEARCH_STATE *state);
gptr hash_next(const HASH *info, const byte *key, uint length,
HASH_SEARCH_STATE *state);
my_bool my_hash_insert(HASH *info,const byte *data);
my_bool hash_delete(HASH *hash,byte *record);
my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length);
void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, byte *new_row);
my_bool hash_check(HASH *hash); /* Only in debug library */
#define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
#define hash_inited(H) ((H)->blength != 0)
#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))
#ifdef __cplusplus
}
#endif
#endif