summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'mysys')
-rw-r--r--mysys/my_vsnprintf.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/mysys/my_vsnprintf.c b/mysys/my_vsnprintf.c
index 0fe6eff24a6..7490ab4a9f2 100644
--- a/mysys/my_vsnprintf.c
+++ b/mysys/my_vsnprintf.c
@@ -19,6 +19,7 @@
#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, ...)
{
@@ -39,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++;
@@ -48,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 */
{
@@ -74,20 +74,28 @@ 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);
}