[Python-checkins] r63883 - in python/branches/release25-maint: Misc/NEWS Python/mysnprintf.c

gregory.p.smith python-checkins at python.org
Mon Jun 2 02:07:25 CEST 2008


Author: gregory.p.smith
Date: Mon Jun  2 02:07:25 2008
New Revision: 63883

Log:
- Issue #2588, #2589: Fix potential integer underflow and overflow
  conditions in the PyOS_vsnprintf C API function.

This is a backport of r63728 and r63734 from trunk.


Modified:
   python/branches/release25-maint/Misc/NEWS
   python/branches/release25-maint/Python/mysnprintf.c

Modified: python/branches/release25-maint/Misc/NEWS
==============================================================================
--- python/branches/release25-maint/Misc/NEWS	(original)
+++ python/branches/release25-maint/Misc/NEWS	Mon Jun  2 02:07:25 2008
@@ -41,6 +41,9 @@
   less than zero will now raise a SystemError and return NULL to indicate a
   bug in the calling C code.
 
+- Issue #2588, #2589: Fix potential integer underflow and overflow
+  conditions in the PyOS_vsnprintf C API function.
+
 
 Library
 -------

Modified: python/branches/release25-maint/Python/mysnprintf.c
==============================================================================
--- python/branches/release25-maint/Python/mysnprintf.c	(original)
+++ python/branches/release25-maint/Python/mysnprintf.c	Mon Jun  2 02:07:25 2008
@@ -54,18 +54,28 @@
 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 @@
 	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,10 @@
 		str[to_copy] = '\0';
 	}
 	PyMem_FREE(buffer);
-Done:
 #endif
-	str[size-1] = '\0';
+Done:
+	if (size > 0)
+		str[size-1] = '\0';
 	return len;
+#undef _PyOS_vsnprintf_EXTRA_SPACE
 }


More information about the Python-checkins mailing list