ha_innobase.cc, ut0ut.c, univ.i, ut0ut.h:

  Redefine sprintf as ut_sprintf inside InnoDB code; some old Unixes may have a pointer as the return type of sprintf
lock0lock.c:
  Add safety against buffer overruns in latest deadlock info
srv0srv.c:
  Add safety against buffer overruns in SHOW INNODB STATUS
os0thread.h, os0thread.c:
  Fix a portability bug introduced in Windows when we changed os_thread_id_t to be the same as os_thread_t
parent 0005f28b
...@@ -70,7 +70,9 @@ os_thread_create( ...@@ -70,7 +70,9 @@ os_thread_create(
void* arg, /* in: argument to start void* arg, /* in: argument to start
function */ function */
os_thread_id_t* thread_id); /* out: id of created os_thread_id_t* thread_id); /* out: id of created
thread */ thread; currently this is
identical to the handle to
the thread */
/********************************************************************* /*********************************************************************
A thread calling this function ends its execution. */ A thread calling this function ends its execution. */
......
...@@ -63,6 +63,12 @@ Microsoft Visual C++ */ ...@@ -63,6 +63,12 @@ Microsoft Visual C++ */
#define HAVE_PWRITE #define HAVE_PWRITE
#endif #endif
/* Apparently in some old SCO Unixes the return type of sprintf is not
an integer as it should be according to the modern Posix standard. Because
of that we define sprintf inside InnoDB code as our own function ut_sprintf */
#undef sprintf
#define sprintf ut_sprintf
#endif #endif
/* DEBUG VERSION CONTROL /* DEBUG VERSION CONTROL
......
...@@ -17,6 +17,18 @@ Created 1/20/1994 Heikki Tuuri ...@@ -17,6 +17,18 @@ Created 1/20/1994 Heikki Tuuri
typedef time_t ib_time_t; typedef time_t ib_time_t;
/************************************************************
Uses vsprintf to emulate sprintf so that the function always returns
the printed length. Apparently in some old SCO Unixes sprintf did not
return the printed length but a pointer to the end of the printed string. */
ulint
ut_sprintf(
/*=======*/
char* buf, /* in/out: buffer where to print */
const char* format, /* in: format of prints */
...); /* in: arguments to be printed */
/************************************************************ /************************************************************
Gets the high 32 bits in a ulint. That is makes a shift >> 32, Gets the high 32 bits in a ulint. That is makes a shift >> 32,
but since there seem to be compiler bugs in both gcc and Visual C++, but since there seem to be compiler bugs in both gcc and Visual C++,
......
...@@ -2754,6 +2754,8 @@ lock_deadlock_occurs( ...@@ -2754,6 +2754,8 @@ lock_deadlock_occurs(
err_buf += sprintf(err_buf, err_buf += sprintf(err_buf,
"*** WE ROLL BACK TRANSACTION (2)\n"); "*** WE ROLL BACK TRANSACTION (2)\n");
ut_a(strlen(lock_latest_err_buf) < 4100);
/* /*
sess_raise_error_low(trx, DB_DEADLOCK, lock->type_mode, table, sess_raise_error_low(trx, DB_DEADLOCK, lock->type_mode, table,
index, NULL, NULL, NULL); index, NULL, NULL, NULL);
......
...@@ -96,17 +96,20 @@ os_thread_create( ...@@ -96,17 +96,20 @@ os_thread_create(
void* arg, /* in: argument to start void* arg, /* in: argument to start
function */ function */
os_thread_id_t* thread_id) /* out: id of created os_thread_id_t* thread_id) /* out: id of created
thread */ thread; currently this is
identical to the handle to
the thread */
{ {
#ifdef __WIN__ #ifdef __WIN__
os_thread_t thread; os_thread_t thread;
ulint win_thread_id;
thread = CreateThread(NULL, /* no security attributes */ thread = CreateThread(NULL, /* no security attributes */
0, /* default size stack */ 0, /* default size stack */
(LPTHREAD_START_ROUTINE)start_f, (LPTHREAD_START_ROUTINE)start_f,
arg, arg,
0, /* thread runs immediately */ 0, /* thread runs immediately */
thread_id); &win_thread_id);
if (srv_set_thread_priorities) { if (srv_set_thread_priorities) {
...@@ -117,6 +120,8 @@ os_thread_create( ...@@ -117,6 +120,8 @@ os_thread_create(
ut_a(SetThreadPriority(thread, srv_query_thread_priority)); ut_a(SetThreadPriority(thread, srv_query_thread_priority));
} }
*thread_id = thread;
return(thread); return(thread);
#else #else
int ret; int ret;
...@@ -134,6 +139,8 @@ os_thread_create( ...@@ -134,6 +139,8 @@ os_thread_create(
my_pthread_setprio(pthread, srv_query_thread_priority); my_pthread_setprio(pthread, srv_query_thread_priority);
} }
*thread_id = pthread;
return(pthread); return(pthread);
#endif #endif
} }
......
...@@ -2222,6 +2222,7 @@ srv_sprintf_innodb_monitor( ...@@ -2222,6 +2222,7 @@ srv_sprintf_innodb_monitor(
ut_sprintf_timestamp(buf); ut_sprintf_timestamp(buf);
buf = buf + strlen(buf); buf = buf + strlen(buf);
ut_a(buf < buf_end + 1500);
buf += sprintf(buf, " INNODB MONITOR OUTPUT\n" buf += sprintf(buf, " INNODB MONITOR OUTPUT\n"
"=====================================\n"); "=====================================\n");
...@@ -2236,6 +2237,7 @@ srv_sprintf_innodb_monitor( ...@@ -2236,6 +2237,7 @@ srv_sprintf_innodb_monitor(
sync_print(buf, buf_end); sync_print(buf, buf_end);
buf = buf + strlen(buf); buf = buf + strlen(buf);
ut_a(buf < buf_end + 1500);
buf += sprintf(buf, "------------\n" buf += sprintf(buf, "------------\n"
"TRANSACTIONS\n" "TRANSACTIONS\n"
...@@ -2248,15 +2250,18 @@ srv_sprintf_innodb_monitor( ...@@ -2248,15 +2250,18 @@ srv_sprintf_innodb_monitor(
"--------\n"); "--------\n");
os_aio_print(buf, buf_end); os_aio_print(buf, buf_end);
buf = buf + strlen(buf); buf = buf + strlen(buf);
ut_a(buf < buf_end + 1500);
buf += sprintf(buf, "-------------------------------------\n" buf += sprintf(buf, "-------------------------------------\n"
"INSERT BUFFER AND ADAPTIVE HASH INDEX\n" "INSERT BUFFER AND ADAPTIVE HASH INDEX\n"
"-------------------------------------\n"); "-------------------------------------\n");
ibuf_print(buf, buf_end); ibuf_print(buf, buf_end);
buf = buf + strlen(buf); buf = buf + strlen(buf);
ut_a(buf < buf_end + 1500);
ha_print_info(buf, buf_end, btr_search_sys->hash_index); ha_print_info(buf, buf_end, btr_search_sys->hash_index);
buf = buf + strlen(buf); buf = buf + strlen(buf);
ut_a(buf < buf_end + 1500);
buf += sprintf(buf, buf += sprintf(buf,
"%.2f hash searches/s, %.2f non-hash searches/s\n", "%.2f hash searches/s, %.2f non-hash searches/s\n",
...@@ -2272,6 +2277,7 @@ srv_sprintf_innodb_monitor( ...@@ -2272,6 +2277,7 @@ srv_sprintf_innodb_monitor(
"---\n"); "---\n");
log_print(buf, buf_end); log_print(buf, buf_end);
buf = buf + strlen(buf); buf = buf + strlen(buf);
ut_a(buf < buf_end + 1500);
buf += sprintf(buf, "----------------------\n" buf += sprintf(buf, "----------------------\n"
"BUFFER POOL AND MEMORY\n" "BUFFER POOL AND MEMORY\n"
...@@ -2282,6 +2288,7 @@ srv_sprintf_innodb_monitor( ...@@ -2282,6 +2288,7 @@ srv_sprintf_innodb_monitor(
mem_pool_get_reserved(mem_comm_pool)); mem_pool_get_reserved(mem_comm_pool));
buf_print_io(buf, buf_end); buf_print_io(buf, buf_end);
buf = buf + strlen(buf); buf = buf + strlen(buf);
ut_a(buf < buf_end + 1500);
buf += sprintf(buf, "--------------\n" buf += sprintf(buf, "--------------\n"
"ROW OPERATIONS\n" "ROW OPERATIONS\n"
...@@ -2315,6 +2322,8 @@ srv_sprintf_innodb_monitor( ...@@ -2315,6 +2322,8 @@ srv_sprintf_innodb_monitor(
buf += sprintf(buf, "----------------------------\n" buf += sprintf(buf, "----------------------------\n"
"END OF INNODB MONITOR OUTPUT\n" "END OF INNODB MONITOR OUTPUT\n"
"============================\n"); "============================\n");
ut_a(buf < buf_end + 1900);
mutex_exit(&srv_innodb_monitor_mutex); mutex_exit(&srv_innodb_monitor_mutex);
} }
...@@ -2372,7 +2381,9 @@ loop: ...@@ -2372,7 +2381,9 @@ loop:
buf = mem_alloc(100000); buf = mem_alloc(100000);
srv_sprintf_innodb_monitor(buf, 100000); srv_sprintf_innodb_monitor(buf, 90000);
ut_a(strlen(buf) < 99000);
printf("%s", buf); printf("%s", buf);
......
...@@ -12,10 +12,35 @@ Created 5/11/1994 Heikki Tuuri ...@@ -12,10 +12,35 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0ut.ic" #include "ut0ut.ic"
#endif #endif
#include <stdarg.h>
#include "ut0sort.h" #include "ut0sort.h"
ibool ut_always_false = FALSE; ibool ut_always_false = FALSE;
/************************************************************
Uses vsprintf to emulate sprintf so that the function always returns
the printed length. Apparently in some old SCO Unixes sprintf did not
return the printed length but a pointer to the end of the printed string. */
ulint
ut_sprintf(
/*=======*/
char* buf, /* in/out: buffer where to print */
const char* format, /* in: format of prints */
...) /* in: arguments to be printed */
{
va_list args;
va_start(args, format);
vsprintf(buf, format, args);
va_end(args);
return((ulint)strlen(buf));
}
/************************************************************ /************************************************************
Gets the high 32 bits in a ulint. That is makes a shift >> 32, Gets the high 32 bits in a ulint. That is makes a shift >> 32,
but since there seem to be compiler bugs in both gcc and Visual C++, but since there seem to be compiler bugs in both gcc and Visual C++,
......
...@@ -264,82 +264,35 @@ innobase_mysql_print_thd( ...@@ -264,82 +264,35 @@ innobase_mysql_print_thd(
void* input_thd)/* in: pointer to a MySQL THD object */ void* input_thd)/* in: pointer to a MySQL THD object */
{ {
THD* thd; THD* thd;
char* old_buf = buf;
thd = (THD*) input_thd; thd = (THD*) input_thd;
buf += sprintf(buf, "MySQL thread id %lu, query id %lu", buf += ut_sprintf(buf, "MySQL thread id %lu, query id %lu",
thd->thread_id, thd->query_id); thd->thread_id, thd->query_id);
if (thd->host) { if (thd->host) {
buf += sprintf(buf, " %.30s", thd->host); buf += ut_sprintf(buf, " %.30s", thd->host);
} }
if (thd->ip) { if (thd->ip) {
buf += sprintf(buf, " %.20s", thd->ip); buf += ut_sprintf(buf, " %.20s", thd->ip);
} }
if (thd->user) { if (thd->user) {
buf += sprintf(buf, " %.20s", thd->user); buf += ut_sprintf(buf, " %.20s", thd->user);
} }
if (thd->proc_info) { if (thd->proc_info) {
buf += sprintf(buf, " %.50s", thd->proc_info); buf += ut_sprintf(buf, " %.50s", thd->proc_info);
} }
if (thd->query) { if (thd->query) {
buf += sprintf(buf, "\n%.150s", thd->query); buf += ut_sprintf(buf, "\n%.150s", thd->query);
} }
buf += sprintf(buf, "\n"); buf += ut_sprintf(buf, "\n");
#ifdef notdefined ut_a(strlen(old_buf) < 400);
/* August 8, 2002
Revert these changes because they make control characters sometimes
appear in the output and scramble it:
the reason is that the last character of the ouptput will be
'\n', not the null character '\0'. We do not know where the output
ends in buf!
On platforms (what are those?) where sprintf does not work
we should define sprintf as 'my_emulated_sprintf'; InnoDB code
contains lots of sprintfs, it does not help to remove them from
just a single file. */
/* We can't use value of sprintf() as this is not portable */
buf+= my_sprintf(buf,
(buf, "MySQL thread id %lu",
thd->thread_id));
if (thd->host)
{
*buf++=' ';
buf=strnmov(buf, thd->host, 30);
}
if (thd->ip)
{
*buf++=' ';
buf=strnmov(buf, thd->ip, 20);
}
if (thd->user)
{
*buf++=' ';
buf=strnmov(buf, thd->user, 20);
}
if (thd->proc_info)
{
*buf++=' ';
buf=strnmov(buf, thd->proc_info, 50);
}
if (thd->query)
{
*buf++='\n';
buf=strnmov(buf, thd->query, 150);
}
*buf='\n';
/* Here we should add '\0' to the end of output to mark its end */
#endif
} }
} }
...@@ -3467,8 +3420,10 @@ innodb_show_status( ...@@ -3467,8 +3420,10 @@ innodb_show_status(
DBUG_ENTER("innodb_show_status"); DBUG_ENTER("innodb_show_status");
/* We let the InnoDB Monitor to output at most 100 kB of text */ /* We let the InnoDB Monitor to output at most 100 kB of text, add
buf = (char*)ut_malloc(100 * 1024); a safety margin of 10 kB for buffer overruns */
buf = (char*)ut_malloc(110 * 1024);
srv_sprintf_innodb_monitor(buf, 100 * 1024); srv_sprintf_innodb_monitor(buf, 100 * 1024);
......
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