diff options
Diffstat (limited to 'mysys/my_vsnprintf.c')
-rw-r--r-- | mysys/my_vsnprintf.c | 58 |
1 files changed, 32 insertions, 26 deletions
diff --git a/mysys/my_vsnprintf.c b/mysys/my_vsnprintf.c index ab8edec4d7b..7490ab4a9f2 100644 --- a/mysys/my_vsnprintf.c +++ b/mysys/my_vsnprintf.c @@ -1,25 +1,25 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, +/* Copyright (C) 2000 MySQL AB + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA */ + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mysys_priv.h" #include "mysys_err.h" #include <m_string.h> #include <stdarg.h> #include <m_ctype.h> +#include <assert.h> int my_snprintf(char* to, size_t n, const char* fmt, ...) { @@ -40,7 +40,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) *to++= *fmt; /* Copy ordinary char */ continue; } - /* Skipp if max size is used (to be compatible with printf) */ + /* Skip if max size is used (to be compatible with printf) */ fmt++; while (isdigit(*fmt) || *fmt == '.' || *fmt == '-') fmt++; @@ -49,14 +49,13 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) if (*fmt == 's') /* String parameter */ { reg2 char *par = va_arg(ap, char *); - uint plen; + uint plen,left_len = (uint)(end-to); if (!par) par = (char*)"(null)"; plen = (uint) strlen(par); - if ((uint) (end-to) > plen) /* Replace if possible */ - { - to=strmov(to,par); - continue; - } + if (left_len <= plen) + plen = left_len - 1; + to=strnmov(to,par,plen); + continue; } else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ { @@ -75,26 +74,34 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) break; *to++='%'; /* % used as % or unknown code */ } + DBUG_ASSERT(to <= end); *to='\0'; /* End of errmessage */ return (uint) (to - start); } #ifdef MAIN +#define OVERRUN_SENTRY 250 static void my_printf(const char * fmt, ...) { - char buf[32]; + char buf[33]; int n; va_list ar; va_start(ar, fmt); - n = my_vsnprintf(buf, sizeof(buf),fmt, ar); + buf[sizeof(buf)-1]=OVERRUN_SENTRY; + n = my_vsnprintf(buf, sizeof(buf)-1,fmt, ar); printf(buf); printf("n=%d, strlen=%d\n", n, strlen(buf)); + if (buf[sizeof(buf)-1] != OVERRUN_SENTRY) + { + fprintf(stderr, "Buffer overrun\n"); + abort(); + } va_end(ar); } int main() { - + my_printf("Hello\n"); my_printf("Hello int, %d\n", 1); my_printf("Hello string '%s'\n", "I am a string"); @@ -109,4 +116,3 @@ int main() return 0; } #endif - |