summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGregory P. Smith <greg@mad-scientist.com>2008-05-26 21:16:34 (GMT)
committerGregory P. Smith <greg@mad-scientist.com>2008-05-26 21:16:34 (GMT)
commit23921f00e8a2d1a4ac3e3274b9523fddafb42fe1 (patch)
treed72668520d064270ffd5b081996dbfa24fb73b8f
parent06abba3558f0be86134a569f9885b0edcfdbbe16 (diff)
downloadcpython-23921f00e8a2d1a4ac3e3274b9523fddafb42fe1.zip
cpython-23921f00e8a2d1a4ac3e3274b9523fddafb42fe1.tar.gz
cpython-23921f00e8a2d1a4ac3e3274b9523fddafb42fe1.tar.bz2
Fix issue2589: there was a potential integer overflow leading to
memory corruption on esoteric platforms and incorrect behavior on normal platforms.
-rw-r--r--Python/mysnprintf.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/Python/mysnprintf.c b/Python/mysnprintf.c
index 4d3770d..8c47794 100644
--- a/Python/mysnprintf.c
+++ b/Python/mysnprintf.c
@@ -54,18 +54,28 @@ int
PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
{
int len; /* # bytes written, excluding \0 */
-#ifndef HAVE_SNPRINTF
+#ifdef HAVE_SNPRINTF
+#define _PyOS_vsnprintf_EXTRA_SPACE 1
+#else
+#define _PyOS_vsnprintf_EXTRA_SPACE 512
char *buffer;
#endif
assert(str != NULL);
assert(size > 0);
assert(format != NULL);
+ /* We take a size_t as input but return an int. Sanity check
+ * our input so that it won't cause an overflow in the
+ * vsnprintf return value or the buffer malloc size. */
+ if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) {
+ len = -666;
+ goto Done;
+ }
#ifdef HAVE_SNPRINTF
len = vsnprintf(str, size, format, va);
#else
/* Emulate it. */
- buffer = PyMem_MALLOC(size + 512);
+ buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
if (buffer == NULL) {
len = -666;
goto Done;
@@ -75,7 +85,7 @@ PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
if (len < 0)
/* ignore the error */;
- else if ((size_t)len >= size + 512)
+ else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE)
Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
else {
@@ -86,8 +96,9 @@ PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
str[to_copy] = '\0';
}
PyMem_FREE(buffer);
-Done:
#endif
+Done:
str[size-1] = '\0';
return len;
+#undef _PyOS_vsnprintf_EXTRA_SPACE
}