mirror of
https://github.com/python/cpython.git
synced 2025-08-22 09:45:06 +00:00
conditions in the PyOS_vsnprintf C API function. This is a backport of r63728 and r63734 from trunk.
This commit is contained in:
parent
26660401c0
commit
9aa040d4ab
2 changed files with 20 additions and 5 deletions
|
@ -41,6 +41,9 @@ Core and builtins
|
||||||
less than zero will now raise a SystemError and return NULL to indicate a
|
less than zero will now raise a SystemError and return NULL to indicate a
|
||||||
bug in the calling C code.
|
bug in the calling C code.
|
||||||
|
|
||||||
|
- Issue #2588, #2589: Fix potential integer underflow and overflow
|
||||||
|
conditions in the PyOS_vsnprintf C API function.
|
||||||
|
|
||||||
|
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -54,18 +54,28 @@ int
|
||||||
PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
|
PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
|
||||||
{
|
{
|
||||||
int len; /* # bytes written, excluding \0 */
|
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;
|
char *buffer;
|
||||||
#endif
|
#endif
|
||||||
assert(str != NULL);
|
assert(str != NULL);
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
assert(format != NULL);
|
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
|
#ifdef HAVE_SNPRINTF
|
||||||
len = vsnprintf(str, size, format, va);
|
len = vsnprintf(str, size, format, va);
|
||||||
#else
|
#else
|
||||||
/* Emulate it. */
|
/* Emulate it. */
|
||||||
buffer = PyMem_MALLOC(size + 512);
|
buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
len = -666;
|
len = -666;
|
||||||
goto Done;
|
goto Done;
|
||||||
|
@ -75,7 +85,7 @@ PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
/* ignore the error */;
|
/* 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");
|
Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
@ -86,8 +96,10 @@ PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
|
||||||
str[to_copy] = '\0';
|
str[to_copy] = '\0';
|
||||||
}
|
}
|
||||||
PyMem_FREE(buffer);
|
PyMem_FREE(buffer);
|
||||||
Done:
|
|
||||||
#endif
|
#endif
|
||||||
str[size-1] = '\0';
|
Done:
|
||||||
|
if (size > 0)
|
||||||
|
str[size-1] = '\0';
|
||||||
return len;
|
return len;
|
||||||
|
#undef _PyOS_vsnprintf_EXTRA_SPACE
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue