diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 091da059afd34b..43fd98036991e2 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1870,17 +1870,20 @@ static PyObject * make_freplacement(PyObject *object) { char freplacement[64]; + int len; if (PyTime_Check(object)) { - PyOS_snprintf(freplacement, sizeof(freplacement), - "%06d", TIME_GET_MICROSECOND(object)); + len = PyOS_snprintf(freplacement, sizeof(freplacement), + "%06d", TIME_GET_MICROSECOND(object)); } else if (PyDateTime_Check(object)) { - PyOS_snprintf(freplacement, sizeof(freplacement), - "%06d", DATE_GET_MICROSECOND(object)); + len = PyOS_snprintf(freplacement, sizeof(freplacement), + "%06d", DATE_GET_MICROSECOND(object)); } else { - PyOS_snprintf(freplacement, sizeof(freplacement), "%06d", 0); + len = PyOS_snprintf(freplacement, sizeof(freplacement), "%06d", 0); } + assert(len >= 6); + assert(len < sizeof(freplacement)); return PyUnicode_FromString(freplacement); } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index e9264f765a08e6..c1f9366e1a634e 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -232,6 +232,18 @@ PyBytes_FromString(const char *str) return (PyObject *) op; } +static Py_ALWAYS_INLINE int +_assert_written(int len, Py_ssize_t max_len) +{ + assert(len >= 1); + assert(len < max_len); + return len; +} + +#define SNPRINTF_BYTES(BUFFER, PATTERN, TYP) \ + _assert_written(PyOS_snprintf(BUFFER, sizeof(BUFFER), \ + PATTERN, va_arg(vargs, TYP)), \ + (Py_ssize_t)sizeof(BUFFER)) static char* bytes_fromformat(PyBytesWriter *writer, Py_ssize_t writer_pos, @@ -324,41 +336,37 @@ bytes_fromformat(PyBytesWriter *writer, Py_ssize_t writer_pos, case 'd': if (longflag) { - len = sprintf(buffer, "%ld", va_arg(vargs, long)); + len = SNPRINTF_BYTES(buffer, "%ld", long); } else if (size_tflag) { - len = sprintf(buffer, "%zd", va_arg(vargs, Py_ssize_t)); + len = SNPRINTF_BYTES(buffer, "%zd", Py_ssize_t); } else { - len = sprintf(buffer, "%d", va_arg(vargs, int)); + len = SNPRINTF_BYTES(buffer, "%d", int); } - assert(1 <= len && len < (Py_ssize_t)sizeof(buffer)); WRITE_BYTES(buffer, len); break; case 'u': if (longflag) { - len = sprintf(buffer, "%lu", va_arg(vargs, unsigned long)); + len = SNPRINTF_BYTES(buffer, "%lu", unsigned long); } else if (size_tflag) { - len = sprintf(buffer, "%zu", va_arg(vargs, size_t)); + len = SNPRINTF_BYTES(buffer, "%zu", size_t); } else { - len = sprintf(buffer, "%u", va_arg(vargs, unsigned int)); + len = SNPRINTF_BYTES(buffer, "%u", unsigned int); } - assert(1 <= len && len < (Py_ssize_t)sizeof(buffer)); WRITE_BYTES(buffer, len); break; case 'i': - len = sprintf(buffer, "%i", va_arg(vargs, int)); - assert(1 <= len && len < (Py_ssize_t)sizeof(buffer)); + len = SNPRINTF_BYTES(buffer, "%i", int); WRITE_BYTES(buffer, len); break; case 'x': - len = sprintf(buffer, "%x", va_arg(vargs, int)); - assert(1 <= len && len < (Py_ssize_t)sizeof(buffer)); + len = SNPRINTF_BYTES(buffer, "%x", int); WRITE_BYTES(buffer, len); break; @@ -382,8 +390,7 @@ bytes_fromformat(PyBytesWriter *writer, Py_ssize_t writer_pos, } case 'p': - len = sprintf(buffer, "%p", va_arg(vargs, void*)); - assert(1 <= len && len < (Py_ssize_t)sizeof(buffer)); + len = SNPRINTF_BYTES(buffer, "%p", void*); /* %p is ill-defined: ensure leading 0x. */ if (buffer[1] == 'X') { buffer[1] = 'x'; @@ -415,6 +422,7 @@ bytes_fromformat(PyBytesWriter *writer, Py_ssize_t writer_pos, return s; #undef WRITE_BYTES +#undef SNPRINTF_BYTES }