Commit 1756d087 authored by Guilhem Bichot's avatar Guilhem Bichot

Fix for BUG#59894

"set optimizer_switch to e or d causes invalid memory writes/valgrind warnings":
due to prefix support, the argument "e" was overwritten with its full value
"engine_condition_pushdown", which caused a buffer overrun.
This was wrong usage of find_type(); other wrong usages are fixed here too.
Please start reading with the comment of typelib.c.

client/mysqldump.c:
  A bug: find_type() expects a bitmap as 3rd argument
  (each bit is a flag controlling a behaviour of the function);
  here it was instead passed the length of the string to search!
  That could give random behaviour of find_type()
  depending on the string.
  We rather need to pass a correct flag to find_type().
  The correct flag is FIND_TYPE_BASIC (0).
  Flag 8 is not needed as buff cannot have a comma (see how buff is filled).
  Flag 1 looks like a superfluous restriction.
  Flag 4 is not user-friendly (why use
  --compatible=2 rather than --compatible=mysql40 ?, and
  we probably not commit to "2" always meaning "mysql40"
  until the end of times).
include/mysql.h.pp:
  This isn't a problematic API change as we go from char* to const char*:
  existing code will run unchanged.
include/typelib.h:
  named constants. Not an enum to not significantly change
  the declaration of find_type() which would be an API change
  (typelib.h is included in mysql.h).
mysql-test/r/mysqldump.result:
  correct result (see the two requested modes in SQL_MODE)
mysql-test/suite/sys_vars/t/optimizer_switch_basic.test:
  test for BUG#59894. The second SET used to crash.
mysql-test/t/mysqldump.test:
  we had no test for multiple modes in --compatible, which is
  supported according to --help
mysys/typelib.c:
  Fix for BUG#59894. parse_name() is asked to match "e" with a row
  of the TYPELIB (the TYPELIB lists permitted flags of optimizer_switch;
  and comes from optimizer_switch_names[] of sys_vars.cc).
  find_type() is capable of supporting prefixes, but if it is not
  passed flag 2 in third argument, it will overwrite its first
  argument (the string to search for) with the complete name,
  here overwriting "e" with "engine_condition_pushdown". But
  as this "e" was a buffer allocated in an Item, it was not big
  enough to host the longer name, thus the crash.
  We don't need to know the complete flag's name; the output used
  from find_type() is just the flag's number (== function's return
  code). So we can pass flag 2 to find_type() in parse_name().
  After doing this fix and the other fixes in this patch, all usages
  of find_type() were using flag 2; in most usages the string to search for,
  is not guaranteed to be long enough to host the complete name
  (it is either directly from argv, or from alloc_root/my_malloc
  done in an earlier call).
  Thus, flag 2 is here made implicit: callers need not pass it anymore,
  it is always automatically turned on.
  This allows to eliminate an oddity: parse_name() took a const char**,
  and then removed "const" before calling find_type(), which could
  theoretically modify the pointed data, thus lying on constness.
  Last, constants for find_type() are now named.
sql-common/client.c:
  Two bugs:
  1) The enum was not in sync with the array (due to a bad porting of WL 1054;
  the extra OPT_ values are about options present in 5.1 and deleted in 5.5);
  added a compile_time_assert() to make sure this doesn't happen again
  2) find_type() was writing past the end of opt_arg; as opt_arg was allocated
  with alloc_root() with no extra space, this was an overrun; it could be seen
  when
  ** building with -DWITH_VALGRIND -DHAVE_purify -DEXTRA_DEBUG
  ** making execution go through the faulty code; this faulty
  code is executed only if the client asks to read a configuration
  file like this:
    mysql_options(mysql, MYSQL_READ_DEFAULT_FILE, "/tmp/cnf.cnf");
  so by adding such line to the start of mysql_client_test.c::client_connect(),
  we could see the valgrind warning:
  ==30548== Invalid write of size 1
  ==30548==    at 0x4C2624C: strcpy (mc_replace_strmem.c:303)
  ==30548==    by 0x48DC29: find_type (typelib.c:120)
  ==30548==    by 0x465686: mysql_read_default_options (client.c:1344)
  ==30548==    by 0x46830F: mysql_real_connect (client.c:2971)
  ==30548==    by 0x409339: client_connect (mysql_client_test.c:331)
  ==30548==    by 0x463A7F: main (mysql_client_test.c:19902)
  ==30548==  Address 0x61875ad is 0 bytes after a block of size 29 alloc'd
  ==30548==    at 0x4C25153: malloc (vg_replace_malloc.c:195)
  ==30548==    by 0x49BFF1: my_malloc (my_malloc.c:38)
  ==30548==    by 0x49C65C: alloc_root (my_alloc.c:166)
  ==30548==    by 0x48EF97: handle_default_option (default.c:381)
  ==30548==    by 0x49068C: search_default_file_with_ext (default.c:992)
  ==30548==    by 0x48F929: search_default_file (default.c:670)
  ==30548==    by 0x48EDC4: my_search_option_files (default.c:312)
  ==30548==    by 0x48F4B1: my_load_defaults (default.c:576)
  ==30548==    by 0x46517A: mysql_read_default_options (client.c:1207)
  ==30548==    by 0x46830F: mysql_real_connect (client.c:2971)
  ==30548==    by 0x409339: client_connect (mysql_client_test.c:331)
  ==30548==    by 0x463A7F: main (mysql_client_test.c:19902)
  This is fixed by having find_type() not overwrite anymore.
sql/sql_help.cc:
  cast not needed anymore.
sql/table.cc:
  cast not needed anymore.
parent 654dd03f
...@@ -369,7 +369,8 @@ int main(int argc,char *argv[]) ...@@ -369,7 +369,8 @@ int main(int argc,char *argv[])
/* Return 0 if all commands are PING */ /* Return 0 if all commands are PING */
for (; argc > 0; argv++, argc--) for (; argc > 0; argv++, argc--)
{ {
if (find_type(argv[0], &command_typelib, 2) != ADMIN_PING) if (find_type(argv[0], &command_typelib, FIND_TYPE_BASIC) !=
ADMIN_PING)
{ {
error= 1; error= 1;
break; break;
...@@ -592,7 +593,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) ...@@ -592,7 +593,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
for (; argc > 0 ; argv++,argc--) for (; argc > 0 ; argv++,argc--)
{ {
switch (find_type(argv[0],&command_typelib,2)) { switch (find_type(argv[0],&command_typelib, FIND_TYPE_BASIC)) {
case ADMIN_CREATE: case ADMIN_CREATE:
{ {
char buff[FN_REFLEN+20]; char buff[FN_REFLEN+20];
...@@ -931,7 +932,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) ...@@ -931,7 +932,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
if (typed_password[0]) if (typed_password[0])
{ {
bool old= (find_type(argv[0], &command_typelib, 2) == bool old= (find_type(argv[0], &command_typelib, FIND_TYPE_BASIC) ==
ADMIN_OLD_PASSWORD); ADMIN_OLD_PASSWORD);
#ifdef __WIN__ #ifdef __WIN__
size_t pw_len= strlen(typed_password); size_t pw_len= strlen(typed_password);
......
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -4644,7 +4644,7 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length, ...@@ -4644,7 +4644,7 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length,
for (; pos != end && *pos != ','; pos++) ; for (; pos != end && *pos != ','; pos++) ;
var_len= (uint) (pos - start); var_len= (uint) (pos - start);
strmake(buff, start, min(sizeof(buff) - 1, var_len)); strmake(buff, start, min(sizeof(buff) - 1, var_len));
find= find_type(buff, lib, var_len); find= find_type(buff, lib, FIND_TYPE_BASIC);
if (!find) if (!find)
{ {
*err_pos= (char*) start; *err_pos= (char*) start;
......
...@@ -8017,7 +8017,7 @@ void get_command_type(struct st_command* command) ...@@ -8017,7 +8017,7 @@ void get_command_type(struct st_command* command)
save= command->query[command->first_word_len]; save= command->query[command->first_word_len];
command->query[command->first_word_len]= 0; command->query[command->first_word_len]= 0;
type= find_type(command->query, &command_typelib, 1+2); type= find_type(command->query, &command_typelib, FIND_TYPE_NO_PREFIX);
command->query[command->first_word_len]= save; command->query[command->first_word_len]= save;
if (type > 0) if (type > 0)
{ {
......
...@@ -227,7 +227,7 @@ typedef struct st_typelib { ...@@ -227,7 +227,7 @@ typedef struct st_typelib {
extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position); extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
extern int find_type_or_exit(const char *x, TYPELIB *typelib, extern int find_type_or_exit(const char *x, TYPELIB *typelib,
const char *option); const char *option);
extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name); extern int find_type(const char *x, const TYPELIB *typelib, unsigned int flags);
extern void make_type(char *to,unsigned int nr,TYPELIB *typelib); extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
extern const char *get_type(TYPELIB *typelib,unsigned int nr); extern const char *get_type(TYPELIB *typelib,unsigned int nr);
extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from); extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
......
/* Copyright (C) 2000 MySQL AB /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -29,7 +29,17 @@ typedef struct st_typelib { /* Different types saved here */ ...@@ -29,7 +29,17 @@ typedef struct st_typelib { /* Different types saved here */
extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position); extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
extern int find_type_or_exit(const char *x, TYPELIB *typelib, extern int find_type_or_exit(const char *x, TYPELIB *typelib,
const char *option); const char *option);
extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name); #define FIND_TYPE_BASIC 0
/** makes @c find_type() require the whole name, no prefix */
#define FIND_TYPE_NO_PREFIX (1 << 0)
/** always implicitely on, so unused, but old code may pass it */
#define FIND_TYPE_NO_OVERWRITE (1 << 1)
/** makes @c find_type() accept a number */
#define FIND_TYPE_ALLOW_NUMBER (1 << 2)
/** makes @c find_type() treat ',' as terminator */
#define FIND_TYPE_COMMA_TERM (1 << 3)
extern int find_type(const char *x, const TYPELIB *typelib, unsigned int flags);
extern void make_type(char *to,unsigned int nr,TYPELIB *typelib); extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
extern const char *get_type(TYPELIB *typelib,unsigned int nr); extern const char *get_type(TYPELIB *typelib,unsigned int nr);
extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from); extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
......
...@@ -4593,3 +4593,35 @@ DROP TABLE `comment_table`; ...@@ -4593,3 +4593,35 @@ DROP TABLE `comment_table`;
# #
# End of 5.1 tests # End of 5.1 tests
# #
#
# Verify that two modes can be given in --compatible;
# and are reflected in SET SQL_MODE in the mysqldump output.
# Also verify that a prefix of the mode's name is enough.
#
CREATE TABLE t1 (a INT);
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
);
/*!40101 SET character_set_client = @saved_cs_client */;
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
DROP TABLE t1;
...@@ -60,6 +60,13 @@ set session optimizer_switch="index_merge"; ...@@ -60,6 +60,13 @@ set session optimizer_switch="index_merge";
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge' ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'index_merge'
set session optimizer_switch="foobar"; set session optimizer_switch="foobar";
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'foobar' ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'foobar'
#
# Bug#59894 set optimizer_switch to e or d causes invalid
# memory writes/valgrind warnings
set global optimizer_switch = 'd';
set global optimizer_switch = 'e';
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'e'
SET @@global.optimizer_switch = @start_global_value; SET @@global.optimizer_switch = @start_global_value;
SELECT @@global.optimizer_switch; SELECT @@global.optimizer_switch;
@@global.optimizer_switch @@global.optimizer_switch
......
...@@ -46,5 +46,13 @@ set session optimizer_switch="index_merge"; ...@@ -46,5 +46,13 @@ set session optimizer_switch="index_merge";
--error ER_WRONG_VALUE_FOR_VAR --error ER_WRONG_VALUE_FOR_VAR
set session optimizer_switch="foobar"; set session optimizer_switch="foobar";
--echo #
--echo # Bug#59894 set optimizer_switch to e or d causes invalid
--echo # memory writes/valgrind warnings
--echo
set global optimizer_switch = 'd'; # means default
--error ER_WRONG_VALUE_FOR_VAR
set global optimizer_switch = 'e';
SET @@global.optimizer_switch = @start_global_value; SET @@global.optimizer_switch = @start_global_value;
SELECT @@global.optimizer_switch; SELECT @@global.optimizer_switch;
...@@ -2182,5 +2182,15 @@ DROP TABLE `comment_table`; ...@@ -2182,5 +2182,15 @@ DROP TABLE `comment_table`;
--echo # End of 5.1 tests --echo # End of 5.1 tests
--echo # --echo #
--echo #
--echo # Verify that two modes can be given in --compatible;
--echo # and are reflected in SET SQL_MODE in the mysqldump output.
--echo # Also verify that a prefix of the mode's name is enough.
--echo #
CREATE TABLE t1 (a INT);
# no_t = no_table_options; no_f = no_field_options
--exec $MYSQL_DUMP --compatible=no_t,no_f --skip-comments test
DROP TABLE t1;
# Wait till we reached the initial number of concurrent sessions # Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc
/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -376,7 +376,7 @@ static int handle_default_option(void *in_ctx, const char *group_name, ...@@ -376,7 +376,7 @@ static int handle_default_option(void *in_ctx, const char *group_name,
if (!option) if (!option)
return 0; return 0;
if (find_type((char *)group_name, ctx->group, 3)) if (find_type((char *)group_name, ctx->group, FIND_TYPE_NO_PREFIX))
{ {
if (!(tmp= alloc_root(ctx->alloc, strlen(option) + 1))) if (!(tmp= alloc_root(ctx->alloc, strlen(option) + 1)))
return 1; return 1;
......
/* Copyright (C) 2002-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc /* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -695,7 +695,7 @@ static int setval(const struct my_option *opts, void *value, char *argument, ...@@ -695,7 +695,7 @@ static int setval(const struct my_option *opts, void *value, char *argument,
break; break;
case GET_ENUM: case GET_ENUM:
{ {
int type= find_type(argument, opts->typelib, 2); int type= find_type(argument, opts->typelib, FIND_TYPE_BASIC);
if (type == 0) if (type == 0)
{ {
/* /*
......
/* Copyright (C) 2000 MySQL AB /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -27,7 +27,7 @@ int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option) ...@@ -27,7 +27,7 @@ int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
int res; int res;
const char **ptr; const char **ptr;
if ((res= find_type((char *) x, typelib, 2)) <= 0) if ((res= find_type((char *) x, typelib, FIND_TYPE_BASIC)) <= 0)
{ {
ptr= typelib->type_names; ptr= typelib->type_names;
if (!*x) if (!*x)
...@@ -48,16 +48,13 @@ int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option) ...@@ -48,16 +48,13 @@ int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
Search after a string in a list of strings. Endspace in x is not compared. Search after a string in a list of strings. Endspace in x is not compared.
@param x String to find @param x String to find
@param lib TYPELIB (struct of pointer to values + count) @param typelib TYPELIB (struct of pointer to values + count)
@param full_name bitmap of what to do @param flags flags to tune behaviour: a combination of
If & 1 accept only whole names FIND_TYPE_NO_PREFIX
If & 2 don't expand if half field FIND_TYPE_ALLOW_NUMBER
If & 4 allow #number# as type FIND_TYPE_COMMA_TERM.
If & 8 use ',' as string terminator FIND_TYPE_NO_OVERWRITE can be passed but is
superfluous (is always implicitely on).
@note
If part, uniq field is found and full_name == 0 then x is expanded
to full field.
@retval @retval
-1 Too many matching values -1 Too many matching values
...@@ -68,15 +65,17 @@ int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option) ...@@ -68,15 +65,17 @@ int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
*/ */
int find_type(char *x, const TYPELIB *typelib, uint full_name) int find_type(const char *x, const TYPELIB *typelib, uint flags)
{ {
int find,pos; int find,pos;
int UNINIT_VAR(findpos); /* guarded by find */ int UNINIT_VAR(findpos); /* guarded by find */
reg1 char * i; const char *i;
reg2 const char *j; const char *j;
DBUG_ENTER("find_type"); DBUG_ENTER("find_type");
DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) typelib)); DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) typelib));
DBUG_ASSERT(!(flags & ~(FIND_TYPE_NO_PREFIX | FIND_TYPE_ALLOW_NUMBER |
FIND_TYPE_NO_OVERWRITE | FIND_TYPE_COMMA_TERM)));
if (!typelib->count) if (!typelib->count)
{ {
DBUG_PRINT("exit",("no count")); DBUG_PRINT("exit",("no count"));
...@@ -86,24 +85,26 @@ int find_type(char *x, const TYPELIB *typelib, uint full_name) ...@@ -86,24 +85,26 @@ int find_type(char *x, const TYPELIB *typelib, uint full_name)
for (pos=0 ; (j=typelib->type_names[pos]) ; pos++) for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
{ {
for (i=x ; for (i=x ;
*i && (!(full_name & 8) || !is_field_separator(*i)) && *i && (!(flags & FIND_TYPE_COMMA_TERM) || !is_field_separator(*i)) &&
my_toupper(&my_charset_latin1,*i) == my_toupper(&my_charset_latin1,*i) ==
my_toupper(&my_charset_latin1,*j) ; i++, j++) ; my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
if (! *j) if (! *j)
{ {
while (*i == ' ') while (*i == ' ')
i++; /* skip_end_space */ i++; /* skip_end_space */
if (! *i || ((full_name & 8) && is_field_separator(*i))) if (! *i || ((flags & FIND_TYPE_COMMA_TERM) && is_field_separator(*i)))
DBUG_RETURN(pos+1); DBUG_RETURN(pos+1);
} }
if ((!*i && (!(full_name & 8) || !is_field_separator(*i))) && if ((!*i &&
(!*j || !(full_name & 1))) (!(flags & FIND_TYPE_COMMA_TERM) || !is_field_separator(*i))) &&
(!*j || !(flags & FIND_TYPE_NO_PREFIX)))
{ {
find++; find++;
findpos=pos; findpos=pos;
} }
} }
if (find == 0 && (full_name & 4) && x[0] == '#' && strend(x)[-1] == '#' && if (find == 0 && (flags & FIND_TYPE_ALLOW_NUMBER) && x[0] == '#' &&
strend(x)[-1] == '#' &&
(findpos=atoi(x+1)-1) >= 0 && (uint) findpos < typelib->count) (findpos=atoi(x+1)-1) >= 0 && (uint) findpos < typelib->count)
find=1; find=1;
else if (find == 0 || ! x[0]) else if (find == 0 || ! x[0])
...@@ -111,13 +112,11 @@ int find_type(char *x, const TYPELIB *typelib, uint full_name) ...@@ -111,13 +112,11 @@ int find_type(char *x, const TYPELIB *typelib, uint full_name)
DBUG_PRINT("exit",("Couldn't find type")); DBUG_PRINT("exit",("Couldn't find type"));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
else if (find != 1 || (full_name & 1)) else if (find != 1 || (flags & FIND_TYPE_NO_PREFIX))
{ {
DBUG_PRINT("exit",("Too many possybilities")); DBUG_PRINT("exit",("Too many possybilities"));
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (!(full_name & 2))
(void) strmov(x,typelib->type_names[findpos]);
DBUG_RETURN(findpos+1); DBUG_RETURN(findpos+1);
} /* find_type */ } /* find_type */
...@@ -192,7 +191,7 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err) ...@@ -192,7 +191,7 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
x++; x++;
if (x[0] && x[1]) /* skip separator if found */ if (x[0] && x[1]) /* skip separator if found */
x++; x++;
if ((find= find_type(i, lib, 2 | 8) - 1) < 0) if ((find= find_type(i, lib, FIND_TYPE_COMMA_TERM) - 1) < 0)
DBUG_RETURN(0); DBUG_RETURN(0);
result|= (ULL(1) << find); result|= (ULL(1) << find);
} }
...@@ -276,7 +275,7 @@ static TYPELIB on_off_default_typelib= {array_elements(on_off_default_names)-1, ...@@ -276,7 +275,7 @@ static TYPELIB on_off_default_typelib= {array_elements(on_off_default_names)-1,
static uint parse_name(const TYPELIB *lib, const char **strpos, const char *end) static uint parse_name(const TYPELIB *lib, const char **strpos, const char *end)
{ {
const char *pos= *strpos; const char *pos= *strpos;
uint find= find_type((char*)pos, lib, 8); uint find= find_type(pos, lib, FIND_TYPE_COMMA_TERM);
for (; pos != end && *pos != '=' && *pos !=',' ; pos++); for (; pos != end && *pos != '=' && *pos !=',' ; pos++);
*strpos= pos; *strpos= pos;
return find; return find;
......
/* Copyright (C) 2000-2003 MySQL AB /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -1145,10 +1145,10 @@ enum option_id { ...@@ -1145,10 +1145,10 @@ enum option_id {
OPT_ssl_key, OPT_ssl_cert, OPT_ssl_ca, OPT_ssl_capath, OPT_ssl_key, OPT_ssl_cert, OPT_ssl_ca, OPT_ssl_capath,
OPT_character_sets_dir, OPT_default_character_set, OPT_interactive_timeout, OPT_character_sets_dir, OPT_default_character_set, OPT_interactive_timeout,
OPT_connect_timeout, OPT_local_infile, OPT_disable_local_infile, OPT_connect_timeout, OPT_local_infile, OPT_disable_local_infile,
OPT_replication_probe, OPT_enable_reads_from_master, OPT_repl_parse_query,
OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name, OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name,
OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth, OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth,
OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth, OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth,
OPT_keep_this_one_last
}; };
static TYPELIB option_types={array_elements(default_options)-1, static TYPELIB option_types={array_elements(default_options)-1,
...@@ -1198,6 +1198,9 @@ void mysql_read_default_options(struct st_mysql_options *options, ...@@ -1198,6 +1198,9 @@ void mysql_read_default_options(struct st_mysql_options *options,
DBUG_ENTER("mysql_read_default_options"); DBUG_ENTER("mysql_read_default_options");
DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL")); DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL"));
compile_time_assert(OPT_keep_this_one_last ==
array_elements(default_options));
argc=1; argv=argv_buff; argv_buff[0]= (char*) "client"; argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0; groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
...@@ -1222,7 +1225,7 @@ void mysql_read_default_options(struct st_mysql_options *options, ...@@ -1222,7 +1225,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
/* Change all '_' in variable name to '-' */ /* Change all '_' in variable name to '-' */
for (end= *option ; *(end= strcend(end,'_')) ; ) for (end= *option ; *(end= strcend(end,'_')) ; )
*end= '-'; *end= '-';
switch (find_type(*option+2,&option_types,2)) { switch (find_type(*option + 2, &option_types, FIND_TYPE_BASIC)) {
case OPT_port: case OPT_port:
if (opt_arg) if (opt_arg)
options->port=atoi(opt_arg); options->port=atoi(opt_arg);
...@@ -1338,8 +1341,8 @@ void mysql_read_default_options(struct st_mysql_options *options, ...@@ -1338,8 +1341,8 @@ void mysql_read_default_options(struct st_mysql_options *options,
options->max_allowed_packet= atoi(opt_arg); options->max_allowed_packet= atoi(opt_arg);
break; break;
case OPT_protocol: case OPT_protocol:
if ((options->protocol= find_type(opt_arg, if ((options->protocol= find_type(opt_arg, &sql_protocol_typelib,
&sql_protocol_typelib,0)) <= 0) FIND_TYPE_BASIC)) <= 0)
{ {
fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg); fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
exit(1); exit(1);
......
/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -1038,9 +1038,9 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, ...@@ -1038,9 +1038,9 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp,
} }
if (!(extension= strrchr(file->name, '.'))) if (!(extension= strrchr(file->name, '.')))
extension= strend(file->name); extension= strend(file->name);
if (find_type(extension, &deletable_extentions,1+2) <= 0) if (find_type(extension, &deletable_extentions, FIND_TYPE_NO_PREFIX) <= 0)
{ {
if (find_type(extension, ha_known_exts(),1+2) <= 0) if (find_type(extension, ha_known_exts(), FIND_TYPE_NO_PREFIX) <= 0)
*found_other_files= true; *found_other_files= true;
continue; continue;
} }
......
/* Copyright (C) 2000-2004 MySQL AB, 2008-2009 Sun Microsystems, Inc /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -613,7 +613,8 @@ retry: ...@@ -613,7 +613,8 @@ retry:
if (keyname) if (keyname)
{ {
if ((keyno=find_type(keyname, &table->s->keynames, 1+2)-1)<0) if ((keyno= find_type(keyname, &table->s->keynames,
FIND_TYPE_NO_PREFIX) - 1) < 0)
{ {
my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias); my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias);
goto err; goto err;
......
/* Copyright (C) 2000 MySQL AB /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -284,10 +284,12 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations, ...@@ -284,10 +284,12 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
Field *rtopic_id, *rkey_id; Field *rtopic_id, *rkey_id;
DBUG_ENTER("get_topics_for_keyword"); DBUG_ENTER("get_topics_for_keyword");
if ((iindex_topic= find_type((char*) primary_key_name, if ((iindex_topic=
&topics->s->keynames, 1+2)-1)<0 || find_type(primary_key_name, &topics->s->keynames,
(iindex_relations= find_type((char*) primary_key_name, FIND_TYPE_NO_PREFIX) - 1) < 0 ||
&relations->s->keynames, 1+2)-1)<0) (iindex_relations=
find_type(primary_key_name, &relations->s->keynames,
FIND_TYPE_NO_PREFIX) - 1) < 0)
{ {
my_message(ER_CORRUPT_HELP_DB, ER(ER_CORRUPT_HELP_DB), MYF(0)); my_message(ER_CORRUPT_HELP_DB, ER(ER_CORRUPT_HELP_DB), MYF(0));
DBUG_RETURN(-1); DBUG_RETURN(-1);
......
/* Copyright (C) 2003 MySQL AB /* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -96,7 +96,7 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs, ...@@ -96,7 +96,7 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
/* /*
Function to find a string in a TYPELIB Function to find a string in a TYPELIB
(Same format as mysys/typelib.c) (similar to find_type() of mysys/typelib.c)
SYNOPSIS SYNOPSIS
find_type() find_type()
......
...@@ -1444,8 +1444,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, ...@@ -1444,8 +1444,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
/* Fix key->name and key_part->field */ /* Fix key->name and key_part->field */
if (key_parts) if (key_parts)
{ {
uint primary_key=(uint) (find_type((char*) primary_key_name, uint primary_key=(uint) (find_type(primary_key_name, &share->keynames,
&share->keynames, 3) - 1); FIND_TYPE_NO_PREFIX) - 1);
longlong ha_option= handler_file->ha_table_flags(); longlong ha_option= handler_file->ha_table_flags();
keyinfo= share->key_info; keyinfo= share->key_info;
key_part= keyinfo->key_part; key_part= keyinfo->key_part;
......
/* Copyright (C) 2000-2003 MySQL AB /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -673,7 +673,8 @@ get_one_option(int optid, ...@@ -673,7 +673,8 @@ get_one_option(int optid,
int method; int method;
enum_mi_stats_method UNINIT_VAR(method_conv); enum_mi_stats_method UNINIT_VAR(method_conv);
myisam_stats_method_str= argument; myisam_stats_method_str= argument;
if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0) if ((method= find_type(argument, &myisam_stats_method_typelib,
FIND_TYPE_BASIC)) <= 0)
{ {
fprintf(stderr, "Invalid value of stats_method: %s.\n", argument); fprintf(stderr, "Invalid value of stats_method: %s.\n", argument);
exit(1); exit(1);
......
/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -77,7 +77,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) ...@@ -77,7 +77,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{ {
if (!strncmp(buff+1,"INSERT_METHOD=",14)) if (!strncmp(buff+1,"INSERT_METHOD=",14))
{ /* Lookup insert method */ { /* Lookup insert method */
int tmp=find_type(buff+15,&merge_insert_method,2); int tmp= find_type(buff + 15, &merge_insert_method, FIND_TYPE_BASIC);
found_merge_insert_method = (uint) (tmp >= 0 ? tmp : 0); found_merge_insert_method = (uint) (tmp >= 0 ? tmp : 0);
} }
continue; /* Skip comments */ continue; /* Skip comments */
...@@ -271,7 +271,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name, ...@@ -271,7 +271,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name,
{ {
/* Compare buffer with global methods list: merge_insert_method. */ /* Compare buffer with global methods list: merge_insert_method. */
insert_method= find_type(child_name_buff + 15, insert_method= find_type(child_name_buff + 15,
&merge_insert_method, 2); &merge_insert_method, FIND_TYPE_BASIC);
} }
continue; continue;
} }
......
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