Commit 4d15fc5e authored by cmiller@zippy.(none)'s avatar cmiller@zippy.(none)

Merge zippy.(none):/home/cmiller/work/mysql/mysql-5.0__bug17667

into  zippy.(none):/home/cmiller/work/mysql/mysql-5.1-new__bug17667
parents b050f975 0f63c3d3
...@@ -601,6 +601,11 @@ extern char *_my_strndup(const byte *from, uint length, ...@@ -601,6 +601,11 @@ extern char *_my_strndup(const byte *from, uint length,
const char *sFile, uint uLine, const char *sFile, uint uLine,
myf MyFlag); myf MyFlag);
/* implemented in my_memmem.c */
extern void *my_memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
#ifdef __WIN__ #ifdef __WIN__
extern int my_access(const char *path, int amode); extern int my_access(const char *path, int amode);
extern File my_sopen(const char *path, int oflag, int shflag, int pmode); extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
......
...@@ -53,6 +53,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ ...@@ -53,6 +53,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \ charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
my_gethostbyname.c rijndael.c my_aes.c sha1.c \ my_gethostbyname.c rijndael.c my_aes.c sha1.c \
my_handler.c my_netware.c my_largepage.c \ my_handler.c my_netware.c my_largepage.c \
my_memmem.c \
my_windac.c my_access.c base64.c my_windac.c my_access.c base64.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c \ thr_mutex.c thr_rwlock.c \
......
...@@ -252,37 +252,89 @@ uint my_b_printf(IO_CACHE *info, const char* fmt, ...) ...@@ -252,37 +252,89 @@ uint my_b_printf(IO_CACHE *info, const char* fmt, ...)
uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
{ {
uint out_length=0; uint out_length=0;
uint minimum_width; /* as yet unimplemented */
uint minimum_width_sign;
uint precision; /* as yet unimplemented for anything but %b */
for (; *fmt ; fmt++) /*
Store the location of the beginning of a format directive, for the
case where we learn we shouldn't have been parsing a format string
at all, and we don't want to lose the flag/precision/width/size
information.
*/
const char* backtrack;
for (; *fmt != '\0'; fmt++)
{ {
if (*fmt++ != '%') /* Copy everything until '%' or end of string */
const char *start=fmt;
uint length;
for (; (*fmt != '\0') && (*fmt != '%'); fmt++) ;
length= (uint) (fmt - start);
out_length+=length;
if (my_b_write(info, start, length))
goto err;
if (*fmt == '\0') /* End of format */
{ {
/* Copy everything until '%' or end of string */ return out_length;
const char *start=fmt-1;
uint length;
for (; *fmt && *fmt != '%' ; fmt++ ) ;
length= (uint) (fmt - start);
out_length+=length;
if (my_b_write(info, start, length))
goto err;
if (!*fmt) /* End of format */
{
return out_length;
}
fmt++;
/* Found one '%' */
} }
/*
By this point, *fmt must be a percent; Keep track of this location and
skip over the percent character.
*/
DBUG_ASSERT(*fmt == '%');
backtrack= fmt;
fmt++;
minimum_width= 0;
precision= 0;
minimum_width_sign= 1;
/* Skip if max size is used (to be compatible with printf) */ /* Skip if max size is used (to be compatible with printf) */
while (my_isdigit(&my_charset_latin1, *fmt) || *fmt == '.' || *fmt == '-') while (*fmt == '-') { fmt++; minimum_width_sign= -1; }
if (*fmt == '*') {
precision= (int) va_arg(args, int);
fmt++;
} else {
while (my_isdigit(&my_charset_latin1, *fmt)) {
minimum_width=(minimum_width * 10) + (*fmt - '0');
fmt++;
}
}
minimum_width*= minimum_width_sign;
if (*fmt == '.') {
fmt++; fmt++;
if (*fmt == '*') {
precision= (int) va_arg(args, int);
fmt++;
} else {
while (my_isdigit(&my_charset_latin1, *fmt)) {
precision=(precision * 10) + (*fmt - '0');
fmt++;
}
}
}
if (*fmt == 's') /* String parameter */ if (*fmt == 's') /* String parameter */
{ {
reg2 char *par = va_arg(args, char *); reg2 char *par = va_arg(args, char *);
uint length = (uint) strlen(par); uint length = (uint) strlen(par);
/* TODO: implement minimum width and precision */
out_length+=length; out_length+=length;
if (my_b_write(info, par, length)) if (my_b_write(info, par, length))
goto err; goto err;
} }
else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
{
char *par = va_arg(args, char *);
out_length+= precision;
if (my_b_write(info, par, precision))
goto err;
}
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
{ {
register int iarg; register int iarg;
...@@ -317,9 +369,9 @@ uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) ...@@ -317,9 +369,9 @@ uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
else else
{ {
/* %% or unknown code */ /* %% or unknown code */
if (my_b_write(info, "%", 1)) if (my_b_write(info, backtrack, fmt-backtrack))
goto err; goto err;
out_length++; out_length+= fmt-backtrack;
} }
} }
return out_length; return out_length;
......
#include "my_base.h"
/*
my_memmem, port of a GNU extension.
Returns a pointer to the beginning of the substring, needle, or NULL if the
substring is not found in haystack.
*/
void *my_memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen)
{
const void *cursor;
const void *last_possible_needle_location = haystack + haystacklen - needlelen;
/* Easy answers */
if (needlelen > haystacklen) return(NULL);
if (needle == NULL) return(NULL);
if (haystack == NULL) return(NULL);
if (needlelen == 0) return(NULL);
if (haystacklen == 0) return(NULL);
for (cursor = haystack; cursor <= last_possible_needle_location; cursor++) {
if (memcmp(needle, cursor, needlelen) == 0) {
return((void *) cursor);
}
}
return(NULL);
}
#ifdef MAIN
#include <assert.h>
int main(int argc, char *argv[]) {
char haystack[10], needle[3];
memmove(haystack, "0123456789", 10);
memmove(needle, "no", 2);
assert(my_memmem(haystack, 10, needle, 2) == NULL);
memmove(needle, "345", 3);
assert(my_memmem(haystack, 10, needle, 3) != NULL);
memmove(needle, "789", 3);
assert(my_memmem(haystack, 10, needle, 3) != NULL);
assert(my_memmem(haystack, 9, needle, 3) == NULL);
memmove(needle, "012", 3);
assert(my_memmem(haystack, 10, needle, 3) != NULL);
assert(my_memmem(NULL, 10, needle, 3) == NULL);
assert(my_memmem(NULL, 10, needle, 3) == NULL);
assert(my_memmem(haystack, 0, needle, 3) == NULL);
assert(my_memmem(haystack, 10, NULL, 3) == NULL);
assert(my_memmem(haystack, 10, needle, 0) == NULL);
assert(my_memmem(haystack, 1, needle, 3) == NULL);
printf("success\n");
return(0);
}
#endif
This diff is collapsed.
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
%#[l]d %#[l]d
%#[l]u %#[l]u
%#[l]x %#[l]x
%#.#b Local format; note first # is ignored and second is REQUIRED
%#.#s Note first # is ignored %#.#s Note first # is ignored
RETURN RETURN
...@@ -40,7 +41,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) ...@@ -40,7 +41,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
for (; *fmt ; fmt++) for (; *fmt ; fmt++)
{ {
if (fmt[0] != '%') if (*fmt != '%')
{ {
if (to == end) /* End of buffer */ if (to == end) /* End of buffer */
break; break;
...@@ -95,6 +96,16 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) ...@@ -95,6 +96,16 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
to=strnmov(to,par,plen); to=strnmov(to,par,plen);
continue; continue;
} }
else if (*fmt == 'b') /* Buffer parameter */
{
char *par = va_arg(ap, char *);
DBUG_ASSERT(to <= end);
if (to + abs(width) + 1 > end)
width= end - to - 1; /* sign doesn't matter */
memmove(to, par, abs(width));
to+= width;
continue;
}
else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x') /* Integer parameter */ else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x') /* Integer parameter */
{ {
register long larg; register long larg;
......
...@@ -43,7 +43,7 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ ...@@ -43,7 +43,7 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
LIBS = @CLIENT_LIBS@ LIBS = @CLIENT_LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ \ LDADD = @CLIENT_EXTRA_LDFLAGS@ \
$(top_builddir)/libmysql/libmysqlclient.la $(top_builddir)/libmysql/libmysqlclient.la
mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) -lmysys -L../mysys
mysql_client_test_SOURCES= mysql_client_test.c $(yassl_dummy_link_fix) mysql_client_test_SOURCES= mysql_client_test.c $(yassl_dummy_link_fix)
insert_test_SOURCES= insert_test.c $(yassl_dummy_link_fix) insert_test_SOURCES= insert_test.c $(yassl_dummy_link_fix)
select_test_SOURCES= select_test.c $(yassl_dummy_link_fix) select_test_SOURCES= select_test.c $(yassl_dummy_link_fix)
......
...@@ -1213,7 +1213,7 @@ static void test_tran_bdb() ...@@ -1213,7 +1213,7 @@ static void test_tran_bdb()
/* create the table 'mytran_demo' of type BDB' or 'InnoDB' */ /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */
rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction( " rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction( "
"col1 int , col2 varchar(30)) ENGINE= BDB"); "col1 int , col2 varchar(30)) TYPE= BDB");
myquery(rc); myquery(rc);
/* insert a row and commit the transaction */ /* insert a row and commit the transaction */
...@@ -1286,7 +1286,7 @@ static void test_tran_innodb() ...@@ -1286,7 +1286,7 @@ static void test_tran_innodb()
/* create the table 'mytran_demo' of type BDB' or 'InnoDB' */ /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */
rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction(col1 int, " rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction(col1 int, "
"col2 varchar(30)) ENGINE= InnoDB"); "col2 varchar(30)) TYPE= InnoDB");
myquery(rc); myquery(rc);
/* insert a row and commit the transaction */ /* insert a row and commit the transaction */
...@@ -9810,7 +9810,7 @@ static void test_derived() ...@@ -9810,7 +9810,7 @@ static void test_derived()
myquery(rc); myquery(rc);
rc= mysql_query(mysql, "create table t1 (id int(8), primary key (id)) \ rc= mysql_query(mysql, "create table t1 (id int(8), primary key (id)) \
ENGINE=InnoDB DEFAULT CHARSET=utf8"); TYPE=InnoDB DEFAULT CHARSET=utf8");
myquery(rc); myquery(rc);
rc= mysql_query(mysql, "insert into t1 values (1)"); rc= mysql_query(mysql, "insert into t1 values (1)");
...@@ -9858,16 +9858,16 @@ static void test_xjoin() ...@@ -9858,16 +9858,16 @@ static void test_xjoin()
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4"); rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
myquery(rc); myquery(rc);
rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) ENGINE=InnoDB DEFAULT CHARSET=utf8"); rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) TYPE=InnoDB DEFAULT CHARSET=utf8");
myquery(rc); myquery(rc);
rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8"); rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) TYPE=InnoDB DEFAULT CHARSET=utf8");
myquery(rc); myquery(rc);
rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) TYPE=InnoDB DEFAULT CHARSET=utf8;");
myquery(rc); myquery(rc);
rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8"); rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) TYPE=InnoDB DEFAULT CHARSET=utf8");
myquery(rc); myquery(rc);
rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)"); rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)");
...@@ -14401,7 +14401,7 @@ static void test_bug14210() ...@@ -14401,7 +14401,7 @@ static void test_bug14210()
itself is not InnoDB related. In case the table is MyISAM this test itself is not InnoDB related. In case the table is MyISAM this test
is harmless. is harmless.
*/ */
mysql_query(mysql, "create table t1 (a varchar(255)) engine=InnoDB"); mysql_query(mysql, "create table t1 (a varchar(255)) type=InnoDB");
rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))"); rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))");
myquery(rc); myquery(rc);
rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384"); rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384");
...@@ -14758,24 +14758,6 @@ static void test_bug16143() ...@@ -14758,24 +14758,6 @@ static void test_bug16143()
} }
/* Bug #16144: mysql_stmt_attr_get type error */
static void test_bug16144()
{
const my_bool flag_orig= (my_bool) 0xde;
my_bool flag= flag_orig;
MYSQL_STMT *stmt;
myheader("test_bug16144");
/* Check that attr_get returns correct data on little and big endian CPUs */
stmt= mysql_stmt_init(mysql);
mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
DIE_UNLESS(flag == flag_orig);
mysql_stmt_close(stmt);
}
/* /*
Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
field length" field length"
...@@ -14839,6 +14821,72 @@ static void test_bug15613() ...@@ -14839,6 +14821,72 @@ static void test_bug15613()
myquery(rc); myquery(rc);
mysql_stmt_close(stmt); mysql_stmt_close(stmt);
} }
/*
Bug#17667: An attacker has the opportunity to bypass query logging.
*/
static void test_bug17667()
{
int rc;
myheader("test_bug17667");
struct buffer_and_length {
const char *buffer;
const uint length;
} statements[]= {
{ "drop table if exists bug17667", 29 },
{ "create table bug17667 (c varchar(20))", 37 },
{ "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
{ "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
{ "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
{ "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
{ "drop table bug17667", 19 },
{ NULL, 0 } };
struct buffer_and_length *statement_cursor;
FILE *log_file;
for (statement_cursor= statements; statement_cursor->buffer != NULL;
statement_cursor++) {
rc= mysql_real_query(mysql, statement_cursor->buffer,
statement_cursor->length);
myquery(rc);
}
sleep(1); /* The server may need time to flush the data to the log. */
log_file= fopen("var/log/master.log", "r");
if (log_file != NULL) {
for (statement_cursor= statements; statement_cursor->buffer != NULL;
statement_cursor++) {
char line_buffer[MAX_TEST_QUERY_LENGTH*2];
/* more than enough room for the query and some marginalia. */
do {
memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
DIE_UNLESS(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) !=
NULL);
/* If we reach EOF before finishing the statement list, then we failed. */
} while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
statement_cursor->buffer, statement_cursor->length) == NULL);
}
printf("success. All queries found intact in the log.\n");
} else {
fprintf(stderr, "Could not find the log file, var/log/master.log, so "
"test_bug17667 is \ninconclusive. Run test from the "
"mysql-test/mysql-test-run* program \nto set up the correct "
"environment for this test.\n\n");
}
if (log_file != NULL)
fclose(log_file);
}
/* /*
Bug#14169: type of group_concat() result changed to blob if tmp_table was used Bug#14169: type of group_concat() result changed to blob if tmp_table was used
*/ */
...@@ -15132,13 +15180,13 @@ static struct my_tests_st my_tests[]= { ...@@ -15132,13 +15180,13 @@ static struct my_tests_st my_tests[]= {
{ "test_bug13488", test_bug13488 }, { "test_bug13488", test_bug13488 },
{ "test_bug13524", test_bug13524 }, { "test_bug13524", test_bug13524 },
{ "test_bug14845", test_bug14845 }, { "test_bug14845", test_bug14845 },
{ "test_bug15510", test_bug15510 },
{ "test_opt_reconnect", test_opt_reconnect }, { "test_opt_reconnect", test_opt_reconnect },
{ "test_bug15510", test_bug15510},
{ "test_bug12744", test_bug12744 }, { "test_bug12744", test_bug12744 },
{ "test_bug16143", test_bug16143 }, { "test_bug16143", test_bug16143 },
{ "test_bug16144", test_bug16144 },
{ "test_bug15613", test_bug15613 }, { "test_bug15613", test_bug15613 },
{ "test_bug14169", test_bug14169 }, { "test_bug14169", test_bug14169 },
{ "test_bug17667", test_bug17667 },
{ 0, 0 } { 0, 0 }
}; };
...@@ -15252,6 +15300,7 @@ int main(int argc, char **argv) ...@@ -15252,6 +15300,7 @@ int main(int argc, char **argv)
{ {
struct my_tests_st *fptr; struct my_tests_st *fptr;
DEBUGGER_OFF;
MY_INIT(argv[0]); MY_INIT(argv[0]);
load_defaults("my", client_test_load_default_groups, &argc, &argv); load_defaults("my", client_test_load_default_groups, &argc, &argv);
......
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