Fix for CONC-543 (hash functions conflict with GnuTLS)

To allow static linking with GnuTLS hash lookup functions are now
prefixed with ma_hashtbl_. The files hash.c and hash.h were renamed
to ma_hashtbl.c and ma_hashtbl.h
This commit is contained in:
Georg Richter
2021-04-13 21:34:29 +02:00
parent 89d0c4b831
commit d19c7c6926
6 changed files with 85 additions and 88 deletions

View File

@ -21,7 +21,7 @@
#define _ma_common_h
#include <mysql.h>
#include <ma_hash.h>
#include <ma_hashtbl.h>
enum enum_multi_status {
COM_MULTI_OFF= 0,
@ -54,7 +54,7 @@ struct st_mysql_options_extension {
char *ssl_crlpath;
char *server_public_key_path;
struct mysql_async_context *async_context;
HASH connect_attrs;
MA_HASHTBL connect_attrs;
size_t connect_attrs_len;
void (*report_progress)(const MYSQL *mysql,
unsigned int stage,
@ -74,7 +74,7 @@ struct st_mysql_options_extension {
my_bool read_only;
char *connection_handler;
my_bool (*set_option)(MYSQL *mysql, const char *config_option, const char *config_value);
HASH userdata;
MA_HASHTBL userdata;
char *server_public_key;
char *proxy_header;
size_t proxy_header_len;

View File

@ -21,8 +21,8 @@
is freely available from http://www.php.net
*************************************************************************************/
#ifndef _ma_hash_h
#define _ma_hash_h
#ifndef _ma_hashtbl_h
#define _ma_hashtbl_h
#ifdef __cplusplus
extern "C" {
#endif
@ -31,12 +31,12 @@ typedef uchar *(*hash_get_key)(const uchar *,uint*,my_bool);
typedef void (*hash_free_key)(void *);
/* flags for hash_init */
#define HASH_CASE_INSENSITIVE 1
#define MA_HASHTBL_CASE_INSENSITIVE 1
typedef struct st_hash_info {
uint next; /* index to next key */
uchar *data; /* data for current entry */
} HASH_LINK;
} MA_HASHTBL_LINK;
typedef struct st_hash {
uint key_offset,key_length; /* Length of key if const length */
@ -46,23 +46,23 @@ typedef struct st_hash {
hash_get_key get_key;
void (*free)(void *);
uint (*calc_hashnr)(const uchar *key,uint length);
} HASH;
} MA_HASHTBL;
#define hash_init(A,B,C,D,E,F,G) _hash_init(A,B,C,D,E,F,G CALLER_INFO)
my_bool _hash_init(HASH *hash,uint default_array_elements, uint key_offset,
#define ma_hashtbl_init(A,B,C,D,E,F,G) _ma_hashtbl_init(A,B,C,D,E,F,G CALLER_INFO)
my_bool _ma_hashtbl_init(MA_HASHTBL *hash,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);
uchar *hash_element(HASH *hash,uint idx);
void * hash_search(HASH *info,const uchar *key,uint length);
void * hash_next(HASH *info,const uchar *key,uint length);
my_bool hash_insert(HASH *info,const uchar *data);
my_bool hash_delete(HASH *hash,uchar *record);
my_bool hash_update(HASH *hash,uchar *record,uchar *old_key,uint old_key_length);
my_bool hash_check(HASH *hash); /* Only in debug library */
void ma_hashtbl_free(MA_HASHTBL *tree);
uchar *ma_hashtbl_element(MA_HASHTBL *hash,uint idx);
void * ma_hashtbl_search(MA_HASHTBL *info,const uchar *key,uint length);
void * ma_hashtbl_next(MA_HASHTBL *info,const uchar *key,uint length);
my_bool ma_hashtbl_insert(MA_HASHTBL *info,const uchar *data);
my_bool ma_hashtbl_delete(MA_HASHTBL *hash,uchar *record);
my_bool ma_hashtbl_update(MA_HASHTBL *hash,uchar *record,uchar *old_key,uint old_key_length);
my_bool ma_hashtbl_check(MA_HASHTBL *hash); /* Only in debug library */
#define hash_clear(H) memset((char*) (H), 0,sizeof(*(H)))
#define hash_inited(H) ((H)->array.buffer != 0)
#define ma_hashtbl_clear(H) memset((char*) (H), 0,sizeof(*(H)))
#define ma_hashtbl_inited(H) ((H)->array.buffer != 0)
#ifdef __cplusplus
}

View File

@ -273,7 +273,7 @@ SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES}
${CC_SOURCE_DIR}/plugins/auth/my_auth.c
ma_array.c
ma_charset.c
ma_hash.c
ma_hashtbl.c
ma_net.c
mariadb_charset.c
ma_time.c

View File

@ -29,7 +29,7 @@
#include <ma_sys.h>
#include <ma_string.h>
#include <mariadb_ctype.h>
#include "ma_hash.h"
#include "ma_hashtbl.h"
#define NO_RECORD ((uint) -1)
#define LOWFIND 1
@ -38,18 +38,18 @@
#define HIGHUSED 8
static uint hash_mask(uint hashnr,uint buffmax,uint maxlength);
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
static void movelink(MA_HASHTBL_LINK *array,uint pos,uint next_link,uint newlink);
static uint calc_hashnr(const uchar *key,uint length);
static uint calc_hashnr_caseup(const uchar *key,uint length);
static int hashcmp(HASH *hash,HASH_LINK *pos,const uchar *key,uint length);
static int hashcmp(MA_HASHTBL *hash,MA_HASHTBL_LINK *pos,const uchar *key,uint length);
my_bool _hash_init(HASH *hash,uint size,uint key_offset,uint key_length,
my_bool _ma_hashtbl_init(MA_HASHTBL *hash,uint size,uint key_offset,uint key_length,
hash_get_key get_key,
void (*free_element)(void*),uint flags CALLER_INFO_PROTO)
{
hash->records=0;
if (ma_init_dynamic_array_ci(&hash->array,sizeof(HASH_LINK),size,0))
if (ma_init_dynamic_array_ci(&hash->array,sizeof(MA_HASHTBL_LINK),size,0))
{
hash->free=0; /* Allow call to hash_free */
return(TRUE);
@ -61,7 +61,7 @@ my_bool _hash_init(HASH *hash,uint size,uint key_offset,uint key_length,
hash->get_key=get_key;
hash->free=free_element;
hash->flags=flags;
if (flags & HASH_CASE_INSENSITIVE)
if (flags & MA_HASHTBL_CASE_INSENSITIVE)
hash->calc_hashnr=calc_hashnr_caseup;
else
hash->calc_hashnr=calc_hashnr;
@ -69,12 +69,12 @@ my_bool _hash_init(HASH *hash,uint size,uint key_offset,uint key_length,
}
void hash_free(HASH *hash)
void ma_hashtbl_free(MA_HASHTBL *hash)
{
if (hash->free)
{
uint i,records;
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
MA_HASHTBL_LINK *data=dynamic_element(&hash->array,0,MA_HASHTBL_LINK*);
for (i=0,records=hash->records ; i < records ; i++)
(*hash->free)(data[i].data);
hash->free=0;
@ -92,7 +92,7 @@ void hash_free(HASH *hash)
*/
static inline char*
hash_key(HASH *hash,const uchar *record,uint *length,my_bool first)
hash_key(MA_HASHTBL *hash,const uchar *record,uint *length,my_bool first)
{
if (hash->get_key)
return (char *)(*hash->get_key)(record,(uint *)length,first);
@ -108,7 +108,7 @@ static uint hash_mask(uint hashnr,uint buffmax,uint maxlength)
return (hashnr & ((buffmax >> 1) -1));
}
static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax,
static uint hash_rec_mask(MA_HASHTBL *hash,MA_HASHTBL_LINK *pos,uint buffmax,
uint maxlength)
{
uint length;
@ -116,7 +116,7 @@ static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax,
return hash_mask((*hash->calc_hashnr)(key,length),buffmax,maxlength);
}
#ifndef NEW_HASH_FUNCTION
#ifndef NEW_MA_HASHTBL_FUNCTION
/* Calc hashvalue for a key */
@ -191,7 +191,7 @@ uint calc_hashnr_caseup(const uchar *key, uint len)
#ifndef __SUNPRO_C /* SUNPRO can't handle this */
static inline
#endif
unsigned int rec_hashnr(HASH *hash,const uchar *record)
unsigned int rec_hashnr(MA_HASHTBL *hash,const uchar *record)
{
uint length;
uchar *key= (uchar*) hash_key(hash,record,&length,0);
@ -202,9 +202,9 @@ unsigned int rec_hashnr(HASH *hash,const uchar *record)
/* Search after a record based on a key */
/* Sets info->current_ptr to found record */
void* hash_search(HASH *hash,const uchar *key,uint length)
void* ma_hashtbl_search(MA_HASHTBL *hash,const uchar *key,uint length)
{
HASH_LINK *pos;
MA_HASHTBL_LINK *pos;
uint flag,idx;
flag=1;
@ -215,7 +215,7 @@ void* hash_search(HASH *hash,const uchar *key,uint length)
hash->blength,hash->records);
do
{
pos= dynamic_element(&hash->array,idx,HASH_LINK*);
pos= dynamic_element(&hash->array,idx,MA_HASHTBL_LINK*);
if (!hashcmp(hash,pos,key,length))
{
hash->current_record= idx;
@ -237,14 +237,14 @@ void* hash_search(HASH *hash,const uchar *key,uint length)
/* Get next record with identical key */
/* Can only be called if previous calls was hash_search */
void *hash_next(HASH *hash,const uchar *key,uint length)
void *ma_hashtbl_next(MA_HASHTBL *hash,const uchar *key,uint length)
{
HASH_LINK *pos;
MA_HASHTBL_LINK *pos;
uint idx;
if (hash->current_record != NO_RECORD)
{
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
MA_HASHTBL_LINK *data=dynamic_element(&hash->array,0,MA_HASHTBL_LINK*);
for (idx=data[hash->current_record].next; idx != NO_RECORD ; idx=pos->next)
{
pos=data+idx;
@ -262,9 +262,9 @@ void *hash_next(HASH *hash,const uchar *key,uint length)
/* Change link from pos to new_link */
static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink)
static void movelink(MA_HASHTBL_LINK *array,uint find,uint next_link,uint newlink)
{
HASH_LINK *old_link;
MA_HASHTBL_LINK *old_link;
do
{
old_link=array+next_link;
@ -276,7 +276,7 @@ static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink)
/* Compare a key in a record to a whole key. Return 0 if identical */
static int hashcmp(HASH *hash,HASH_LINK *pos,const uchar *key,uint length)
static int hashcmp(MA_HASHTBL *hash,MA_HASHTBL_LINK *pos,const uchar *key,uint length)
{
uint rec_keylength;
uchar *rec_key= (uchar*) hash_key(hash,pos->data,&rec_keylength,1);
@ -287,22 +287,22 @@ static int hashcmp(HASH *hash,HASH_LINK *pos,const uchar *key,uint length)
/* Write a hash-key to the hash-index */
my_bool hash_insert(HASH *info,const uchar *record)
my_bool ma_hashtbl_insert(MA_HASHTBL *info,const uchar *record)
{
int flag;
uint halfbuff,hash_nr,first_index,idx;
uchar *ptr_to_rec= NULL,*ptr_to_rec2= NULL;
HASH_LINK *data,*empty,*gpos= NULL,*gpos2 = NULL,*pos;
MA_HASHTBL_LINK *data,*empty,*gpos= NULL,*gpos2 = NULL,*pos;
LINT_INIT(gpos); LINT_INIT(gpos2);
LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2);
flag=0;
if (!(empty=(HASH_LINK*) ma_alloc_dynamic(&info->array)))
if (!(empty=(MA_HASHTBL_LINK*) ma_alloc_dynamic(&info->array)))
return(TRUE); /* No more memory */
info->current_record= NO_RECORD;
data=dynamic_element(&info->array,0,HASH_LINK*);
data=dynamic_element(&info->array,0,MA_HASHTBL_LINK*);
halfbuff= info->blength >> 1;
idx=first_index=info->records-halfbuff;
@ -421,15 +421,15 @@ my_bool hash_insert(HASH *info,const uchar *record)
** if there is a free-function it's called for record if found
******************************************************************************/
my_bool hash_delete(HASH *hash,uchar *record)
my_bool ma_hashtbl_delete(MA_HASHTBL *hash,uchar *record)
{
uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
MA_HASHTBL_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
if (!hash->records)
return(1);
blength=hash->blength;
data=dynamic_element(&hash->array,0,HASH_LINK*);
data=dynamic_element(&hash->array,0,MA_HASHTBL_LINK*);
/* Search after record with key */
pos=data+ hash_mask(rec_hashnr(hash,record),blength,hash->records);
gpos = 0;
@ -508,12 +508,12 @@ exit:
This is much more efficient than using a delete & insert.
*/
my_bool hash_update(HASH *hash,uchar *record,uchar *old_key,uint old_key_length)
my_bool ma_hashtbl_update(MA_HASHTBL *hash,uchar *record,uchar *old_key,uint old_key_length)
{
uint idx,new_index,new_pos_index,blength,records,empty;
HASH_LINK org_link,*data,*previous,*pos;
MA_HASHTBL_LINK org_link,*data,*previous,*pos;
data=dynamic_element(&hash->array,0,HASH_LINK*);
data=dynamic_element(&hash->array,0,MA_HASHTBL_LINK*);
blength=hash->blength; records=hash->records;
/* Search after record with key */
@ -572,12 +572,9 @@ my_bool hash_update(HASH *hash,uchar *record,uchar *old_key,uint old_key_length)
}
uchar *hash_element(HASH *hash,uint idx)
uchar *ma_hashtbl_element(MA_HASHTBL *hash,uint idx)
{
if (idx < hash->records)
return dynamic_element(&hash->array,idx,HASH_LINK*)->data;
return dynamic_element(&hash->array,idx,MA_HASHTBL_LINK*)->data;
return 0;
}

View File

@ -64,7 +64,7 @@
#include <ma_global.h>
#include <ma_sys.h>
#include <ma_string.h>
#include <ma_hash.h>
//#include <ma_hashtbl.h>
#include <mariadb_dyncol.h>
#include <mysql.h>

View File

@ -1174,13 +1174,13 @@ char *ma_send_connect_attr(MYSQL *mysql, unsigned char *buffer)
buffer= (unsigned char *)mysql_net_store_length((unsigned char *)buffer, (mysql->options.extension) ?
mysql->options.extension->connect_attrs_len : 0);
if (mysql->options.extension &&
hash_inited(&mysql->options.extension->connect_attrs))
ma_hashtbl_inited(&mysql->options.extension->connect_attrs))
{
uint i;
for (i=0; i < mysql->options.extension->connect_attrs.records; i++)
{
size_t len;
uchar *p= hash_element(&mysql->options.extension->connect_attrs, i);
uchar *p= ma_hashtbl_element(&mysql->options.extension->connect_attrs, i);
len= strlen((char *)p);
buffer= mysql_net_store_length(buffer, len);
@ -1989,10 +1989,10 @@ static void mysql_close_options(MYSQL *mysql)
free(mysql->options.extension->tls_version);
free(mysql->options.extension->url);
free(mysql->options.extension->connection_handler);
if(hash_inited(&mysql->options.extension->connect_attrs))
hash_free(&mysql->options.extension->connect_attrs);
if (hash_inited(&mysql->options.extension->userdata))
hash_free(&mysql->options.extension->userdata);
if(ma_hashtbl_inited(&mysql->options.extension->connect_attrs))
ma_hashtbl_free(&mysql->options.extension->connect_attrs);
if (ma_hashtbl_inited(&mysql->options.extension->userdata))
ma_hashtbl_free(&mysql->options.extension->userdata);
}
free(mysql->options.extension);
@ -3044,8 +3044,8 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
{
uchar *h;
CHECK_OPT_EXTENSION_SET(&mysql->options);
if (hash_inited(&mysql->options.extension->connect_attrs) &&
(h= (uchar *)hash_search(&mysql->options.extension->connect_attrs, (uchar *)arg1,
if (ma_hashtbl_inited(&mysql->options.extension->connect_attrs) &&
(h= (uchar *)ma_hashtbl_search(&mysql->options.extension->connect_attrs, (uchar *)arg1,
arg1 ? (uint)strlen((char *)arg1) : 0)))
{
uchar *p= h;
@ -3054,16 +3054,16 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
p+= key_len + 1;
key_len= strlen((char *)p);
mysql->options.extension->connect_attrs_len-= key_len + get_store_length(key_len);
hash_delete(&mysql->options.extension->connect_attrs, h);
ma_hashtbl_delete(&mysql->options.extension->connect_attrs, h);
}
}
break;
case MYSQL_OPT_CONNECT_ATTR_RESET:
CHECK_OPT_EXTENSION_SET(&mysql->options);
if (hash_inited(&mysql->options.extension->connect_attrs))
if (ma_hashtbl_inited(&mysql->options.extension->connect_attrs))
{
hash_free(&mysql->options.extension->connect_attrs);
ma_hashtbl_free(&mysql->options.extension->connect_attrs);
mysql->options.extension->connect_attrs_len= 0;
}
break;
@ -3115,9 +3115,9 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
}
CHECK_OPT_EXTENSION_SET(&mysql->options);
if (!hash_inited(&mysql->options.extension->userdata))
if (!ma_hashtbl_inited(&mysql->options.extension->userdata))
{
if (_hash_init(&mysql->options.extension->userdata,
if (_ma_hashtbl_init(&mysql->options.extension->userdata,
0, 0, 0, ma_get_hash_keyval, ma_int_hash_free, 0))
{
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
@ -3125,7 +3125,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
}
}
/* check if key is already in buffer */
p= (uchar *)hash_search(&mysql->options.extension->userdata,
p= (uchar *)ma_hashtbl_search(&mysql->options.extension->userdata,
(uchar *)key,
(uint)strlen(key));
if (p)
@ -3146,7 +3146,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
p+= strlen(key) + 1;
memcpy(p, &data, sizeof(void *));
if (hash_insert(&mysql->options.extension->userdata, buffer))
if (ma_hashtbl_insert(&mysql->options.extension->userdata, buffer))
{
free(buffer);
SET_CLIENT_ERROR(mysql, CR_INVALID_PARAMETER_NO, SQLSTATE_UNKNOWN, 0);
@ -3182,9 +3182,9 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
goto end;
}
if (!hash_inited(&mysql->options.extension->connect_attrs))
if (!ma_hashtbl_inited(&mysql->options.extension->connect_attrs))
{
if (_hash_init(&mysql->options.extension->connect_attrs,
if (_ma_hashtbl_init(&mysql->options.extension->connect_attrs,
0, 0, 0, ma_get_hash_keyval, ma_int_hash_free, 0))
{
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
@ -3199,7 +3199,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
if (arg2)
strcpy((char *)p, arg2);
if (hash_insert(&mysql->options.extension->connect_attrs, buffer))
if (ma_hashtbl_insert(&mysql->options.extension->connect_attrs, buffer))
{
free(buffer);
SET_CLIENT_ERROR(mysql, CR_INVALID_PARAMETER_NO, SQLSTATE_UNKNOWN, 0);
@ -3398,7 +3398,7 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...)
*elements= 0;
if (!mysql->options.extension ||
!hash_inited(&mysql->options.extension->connect_attrs))
!ma_hashtbl_inited(&mysql->options.extension->connect_attrs))
break;
*elements= mysql->options.extension->connect_attrs.records;
@ -3407,7 +3407,7 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...)
{
for (i=0; i < *elements; i++)
{
uchar *p= hash_element(&mysql->options.extension->connect_attrs, i);
uchar *p= ma_hashtbl_element(&mysql->options.extension->connect_attrs, i);
if (key)
key[i]= (char *)p;
p+= strlen((char *)p) + 1;
@ -3453,8 +3453,8 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...)
uchar *p;
void *data= va_arg(ap, void *);
char *key= (char *)arg;
if (key && data && mysql->options.extension && hash_inited(&mysql->options.extension->userdata) &&
(p= (uchar *)hash_search(&mysql->options.extension->userdata, (uchar *)key,
if (key && data && mysql->options.extension && ma_hashtbl_inited(&mysql->options.extension->userdata) &&
(p= (uchar *)ma_hashtbl_search(&mysql->options.extension->userdata, (uchar *)key,
(uint)strlen((char *)key))))
{
p+= strlen(key) + 1;