summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlav Sandstaa <olav.sandstaa@oracle.com>2010-09-15 13:33:22 +0200
committerOlav Sandstaa <olav.sandstaa@oracle.com>2010-09-15 13:33:22 +0200
commit77844bd10b50fbe08565eb0f7ebbcdaf9a1eab3c (patch)
treeb1c96012cdcd3f151fdcf0ddb95a5ba3154fcb52
parent5b9a2f3b6958aef95505d34648de33c9fe26eb8e (diff)
downloadmariadb-git-77844bd10b50fbe08565eb0f7ebbcdaf9a1eab3c.tar.gz
Fix for Bug#54478 "mysqld crashes during boot when running mtr with --debug option"
The crash during boot was caused by a DBUG_PRINT statement in fill_schema_schemata() (in sql_show.cc). This DBUG_PRINT statement contained several instances of %s in the format string and for one of these we gave a NULL pointer as the argument. This caused the call to vsnprintf() to crash when running on Solaris. The fix for this problem is to replace the call to vsnprintf() with my_vsnprintf() which handles that a NULL pointer is passed as argumens for %s. This patch also extends my_vsnprintf() to support %i in the format string. dbug/dbug.c: Replace the use of vsnprintf() with my_vsnprintf(). On some platforms vsnprintf() did not handle that a NULL pointer was given as an argument for a %s in the format string. include/mysql/service_my_snprintf.h: Add support for %i in format string to my_vsnprintf(). strings/my_vsnprintf.c: Add support for %i in format string to my_vsnprintf(). unittest/mysys/my_vsnprintf-t.c: Add unit tests for %i in format string to my_vsnprintf().
-rw-r--r--dbug/dbug.c6
-rw-r--r--include/mysql/service_my_snprintf.h2
-rw-r--r--strings/my_vsnprintf.c14
-rw-r--r--unittest/mysys/my_vsnprintf-t.c11
4 files changed, 20 insertions, 13 deletions
diff --git a/dbug/dbug.c b/dbug/dbug.c
index fd87669b8ca..4968d9e0568 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -1335,15 +1335,11 @@ void _db_doprnt_(const char *format,...)
* This function is intended as a
* vfprintf clone with consistent, platform independent output for
* problematic formats like %p, %zd and %lld.
- * However: full functionality for my_vsnprintf has not been backported yet,
- * so code using "%g" or "%f" will have undefined behaviour.
*/
static void DbugVfprintf(FILE *stream, const char* format, va_list args)
{
char cvtbuf[1024];
- size_t len;
- /* Do not use my_vsnprintf, it does not support "%g". */
- len = vsnprintf(cvtbuf, sizeof(cvtbuf), format, args);
+ (void) my_vsnprintf(cvtbuf, sizeof(cvtbuf), format, args);
(void) fprintf(stream, "%s\n", cvtbuf);
}
diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h
index d7f8d07e110..f6b4aa39dc5 100644
--- a/include/mysql/service_my_snprintf.h
+++ b/include/mysql/service_my_snprintf.h
@@ -53,7 +53,7 @@
<length modifier> can be 'l', 'll', or 'z'.
Supported formats are 's' (null pointer is accepted, printed as
- "(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x', 'o',
+ "(null)"), 'b' (extension, see below), 'c', 'd', 'i', 'u', 'x', 'o',
'X', 'p' (works as 0x%x).
Standard syntax for positional arguments $n is supported.
diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c
index 251c3905d5a..1284203f739 100644
--- a/strings/my_vsnprintf.c
+++ b/strings/my_vsnprintf.c
@@ -255,7 +255,7 @@ static char *process_int_arg(char *to, char *end, size_t length,
if ((to_length= (size_t) (end-to)) < 16 || length)
store_start= buff;
- if (arg_type == 'd')
+ if (arg_type == 'd' || arg_type == 'i')
store_end= longlong10_to_str(par, store_start, -10);
else if (arg_type == 'u')
store_end= longlong10_to_str(par, store_start, 10);
@@ -399,6 +399,7 @@ start:
args_arr[i].double_arg= va_arg(ap, double);
break;
case 'd':
+ case 'i':
case 'u':
case 'x':
case 'X':
@@ -406,7 +407,7 @@ start:
case 'p':
if (args_arr[i].have_longlong)
args_arr[i].longlong_arg= va_arg(ap,longlong);
- else if (args_arr[i].arg_type == 'd')
+ else if (args_arr[i].arg_type == 'd' || args_arr[i].arg_type == 'i')
args_arr[i].longlong_arg= va_arg(ap, int);
else
args_arr[i].longlong_arg= va_arg(ap, uint);
@@ -458,6 +459,7 @@ start:
break;
}
case 'd':
+ case 'i':
case 'u':
case 'x':
case 'X':
@@ -472,7 +474,7 @@ start:
if (args_arr[print_arr[i].arg_idx].have_longlong)
larg = args_arr[print_arr[i].arg_idx].longlong_arg;
- else if (print_arr[i].arg_type == 'd')
+ else if (print_arr[i].arg_type == 'd' || print_arr[i].arg_type == 'i' )
larg = (int) args_arr[print_arr[i].arg_idx].longlong_arg;
else
larg= (uint) args_arr[print_arr[i].arg_idx].longlong_arg;
@@ -615,8 +617,8 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
to= process_dbl_arg(to, end, width, d, *fmt);
continue;
}
- else if (*fmt == 'd' || *fmt == 'u' || *fmt == 'x' || *fmt == 'X' ||
- *fmt == 'p' || *fmt == 'o')
+ else if (*fmt == 'd' || *fmt == 'i' || *fmt == 'u' || *fmt == 'x' ||
+ *fmt == 'X' || *fmt == 'p' || *fmt == 'o')
{
/* Integer parameter */
longlong larg;
@@ -625,7 +627,7 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
if (have_longlong)
larg = va_arg(ap,longlong);
- else if (*fmt == 'd')
+ else if (*fmt == 'd' || *fmt == 'i')
larg = va_arg(ap, int);
else
larg= va_arg(ap, uint);
diff --git a/unittest/mysys/my_vsnprintf-t.c b/unittest/mysys/my_vsnprintf-t.c
index 4ef6c310c8f..e7f37774f85 100644
--- a/unittest/mysys/my_vsnprintf-t.c
+++ b/unittest/mysys/my_vsnprintf-t.c
@@ -31,7 +31,7 @@ void test1(const char *res, const char *fmt, ...)
int main(void)
{
- plan(54);
+ plan(58);
test1("Constant string",
"Constant string");
@@ -44,6 +44,8 @@ int main(void)
"Format specifier c %c", '!');
test1("Format specifier d 1",
"Format specifier d %d", 1);
+ test1("Format specifier i 1",
+ "Format specifier i %i", 1);
test1("Format specifier u 2",
"Format specifier u %u", 2);
test1("Format specifier o 375",
@@ -77,6 +79,9 @@ int main(void)
test1("Length modifiers work: 1 * -1 * 2 * 3",
"Length modifiers work: %d * %ld * %lld * %zd", 1, -1L, 2LL, (size_t)3);
+ test1("Length modifiers work: 1 * -1 * 2 * 3",
+ "Length modifiers work: %i * %li * %lli * %zd", 1, -1L, 2LL, (size_t)3);
+
test1("long long X: 123456789abcdef0",
"long long X: %llx", 0x123456789abcdef0LL);
@@ -121,6 +126,10 @@ int main(void)
"Hello int, %d", 1);
test1("Hello int, -1",
"Hello int, %d", -1);
+ test1("Hello int, 1",
+ "Hello int, %i", 1);
+ test1("Hello int, -1",
+ "Hello int, %i", -1);
test1("Hello string 'I am a string'",
"Hello string '%s'", "I am a string");
test1("Hello hack hack hack hack hack hack hack 1",