Lines 54-71
int
Link Here
|
54 |
PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) |
54 |
PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) |
55 |
{ |
55 |
{ |
56 |
int len; /* # bytes written, excluding \0 */ |
56 |
int len; /* # bytes written, excluding \0 */ |
57 |
#ifndef HAVE_SNPRINTF |
57 |
#ifdef HAVE_SNPRINTF |
|
|
58 |
#define _PyOS_vsnprintf_EXTRA_SPACE 1 |
59 |
#else |
60 |
#define _PyOS_vsnprintf_EXTRA_SPACE 512 |
58 |
char *buffer; |
61 |
char *buffer; |
59 |
#endif |
62 |
#endif |
60 |
assert(str != NULL); |
63 |
assert(str != NULL); |
61 |
assert(size > 0); |
64 |
assert(size > 0); |
62 |
assert(format != NULL); |
65 |
assert(format != NULL); |
|
|
66 |
/* We take a size_t as input but return an int. Sanity check |
67 |
* our input so that it won't cause an overflow in the |
68 |
* vsnprintf return value or the buffer malloc size. */ |
69 |
if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) { |
70 |
len = -666; |
71 |
goto Done; |
72 |
} |
63 |
|
73 |
|
64 |
#ifdef HAVE_SNPRINTF |
74 |
#ifdef HAVE_SNPRINTF |
65 |
len = vsnprintf(str, size, format, va); |
75 |
len = vsnprintf(str, size, format, va); |
66 |
#else |
76 |
#else |
67 |
/* Emulate it. */ |
77 |
/* Emulate it. */ |
68 |
buffer = PyMem_MALLOC(size + 512); |
78 |
buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE); |
69 |
if (buffer == NULL) { |
79 |
if (buffer == NULL) { |
70 |
len = -666; |
80 |
len = -666; |
71 |
goto Done; |
81 |
goto Done; |
Lines 75-81
PyOS_vsnprintf(char *str, size_t size, c
Link Here
|
75 |
if (len < 0) |
85 |
if (len < 0) |
76 |
/* ignore the error */; |
86 |
/* ignore the error */; |
77 |
|
87 |
|
78 |
else if ((size_t)len >= size + 512) |
88 |
else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE) |
79 |
Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf"); |
89 |
Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf"); |
80 |
|
90 |
|
81 |
else { |
91 |
else { |
Lines 86-93
PyOS_vsnprintf(char *str, size_t size, c
Link Here
|
86 |
str[to_copy] = '\0'; |
96 |
str[to_copy] = '\0'; |
87 |
} |
97 |
} |
88 |
PyMem_FREE(buffer); |
98 |
PyMem_FREE(buffer); |
89 |
Done: |
|
|
90 |
#endif |
99 |
#endif |
91 |
str[size-1] = '\0'; |
100 |
Done: |
|
|
101 |
if (size > 0) |
102 |
str[size-1] = '\0'; |
92 |
return len; |
103 |
return len; |
|
|
104 |
#undef _PyOS_vsnprintf_EXTRA_SPACE |
93 |
} |
105 |
} |