Issue #10833: Use PyErr_Format() and PyUnicode_FromFormat() instead of
PyOS_snprintf() to avoid temporary buffer allocated on the stack and a conversion from bytes to Unicode.
This commit is contained in:
parent
44afe2b35a
commit
6ced7c4333
|
@ -766,7 +766,7 @@ typedef struct
|
|||
PyObject *name;
|
||||
} PyDateTime_TimeZone;
|
||||
|
||||
/* The interned UTC timezone instance */
|
||||
/* The interned UTC timezone instance */
|
||||
static PyObject *PyDateTime_TimeZone_UTC;
|
||||
|
||||
/* Create new timezone instance checking offset range. This
|
||||
|
@ -3287,7 +3287,6 @@ timezone_repr(PyDateTime_TimeZone *self)
|
|||
static PyObject *
|
||||
timezone_str(PyDateTime_TimeZone *self)
|
||||
{
|
||||
char buf[10];
|
||||
int hours, minutes, seconds;
|
||||
PyObject *offset;
|
||||
char sign;
|
||||
|
@ -3313,11 +3312,9 @@ timezone_str(PyDateTime_TimeZone *self)
|
|||
Py_DECREF(offset);
|
||||
minutes = divmod(seconds, 60, &seconds);
|
||||
hours = divmod(minutes, 60, &minutes);
|
||||
assert(seconds == 0);
|
||||
/* XXX ignore sub-minute data, curently not allowed. */
|
||||
PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes);
|
||||
|
||||
return PyUnicode_FromString(buf);
|
||||
assert(seconds == 0);
|
||||
return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
|
|
@ -22,14 +22,7 @@ static PyObject *TestError; /* set to exception object in init */
|
|||
static PyObject *
|
||||
raiseTestError(const char* test_name, const char* msg)
|
||||
{
|
||||
char buf[2048];
|
||||
|
||||
if (strlen(test_name) + strlen(msg) > sizeof(buf) - 50)
|
||||
PyErr_SetString(TestError, "internal error msg too large");
|
||||
else {
|
||||
PyOS_snprintf(buf, sizeof(buf), "%s: %s", test_name, msg);
|
||||
PyErr_SetString(TestError, buf);
|
||||
}
|
||||
PyErr_Format(TestError, "%s: %s", test_name, msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -2400,11 +2400,9 @@ static PyObject *
|
|||
Tktt_Repr(PyObject *self)
|
||||
{
|
||||
TkttObject *v = (TkttObject *)self;
|
||||
char buf[100];
|
||||
|
||||
PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
|
||||
v->func == NULL ? ", handler deleted" : "");
|
||||
return PyUnicode_FromString(buf);
|
||||
return PyUnicode_FromFormat("<tktimertoken at %p%s>",
|
||||
v,
|
||||
v->func == NULL ? ", handler deleted" : "");
|
||||
}
|
||||
|
||||
static PyTypeObject Tktt_Type =
|
||||
|
|
|
@ -233,10 +233,9 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *args)
|
|||
Py_XDECREF(tmp);
|
||||
}
|
||||
else {
|
||||
PyOS_snprintf(buf, sizeof(buf),
|
||||
"set_%.50s(func): argument not callable",
|
||||
funcname);
|
||||
PyErr_SetString(PyExc_TypeError, buf);
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"set_%.50s(func): argument not callable",
|
||||
funcname);
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
|
@ -890,7 +889,7 @@ setup_readline(void)
|
|||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* the libedit readline emulation resets key bindings etc
|
||||
/* the libedit readline emulation resets key bindings etc
|
||||
* when calling rl_initialize. So call it upfront
|
||||
*/
|
||||
if (using_libedit_emulation)
|
||||
|
@ -930,11 +929,11 @@ setup_readline(void)
|
|||
*/
|
||||
#ifdef __APPLE__
|
||||
if (using_libedit_emulation)
|
||||
rl_read_init_file(NULL);
|
||||
rl_read_init_file(NULL);
|
||||
else
|
||||
#endif /* __APPLE__ */
|
||||
rl_initialize();
|
||||
|
||||
|
||||
RESTORE_LOCALE(saved_locale)
|
||||
}
|
||||
|
||||
|
|
|
@ -330,12 +330,10 @@ complex_repr(PyComplexObject *v)
|
|||
int precision = 0;
|
||||
char format_code = 'r';
|
||||
PyObject *result = NULL;
|
||||
Py_ssize_t len;
|
||||
|
||||
/* If these are non-NULL, they'll need to be freed. */
|
||||
char *pre = NULL;
|
||||
char *im = NULL;
|
||||
char *buf = NULL;
|
||||
|
||||
/* These do not need to be freed. re is either an alias
|
||||
for pre or a pointer to a constant. lead and tail
|
||||
|
@ -374,20 +372,10 @@ complex_repr(PyComplexObject *v)
|
|||
lead = "(";
|
||||
tail = ")";
|
||||
}
|
||||
/* Alloc the final buffer. Add one for the "j" in the format string,
|
||||
and one for the trailing zero byte. */
|
||||
len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2;
|
||||
buf = PyMem_Malloc(len);
|
||||
if (!buf) {
|
||||
PyErr_NoMemory();
|
||||
goto done;
|
||||
}
|
||||
PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail);
|
||||
result = PyUnicode_FromString(buf);
|
||||
result = PyUnicode_FromFormat("%s%s%sj%s", lead, re, im, tail);
|
||||
done:
|
||||
PyMem_Free(im);
|
||||
PyMem_Free(pre);
|
||||
PyMem_Free(buf);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -310,20 +310,18 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
|||
if (max == 0) {
|
||||
if (args == NULL)
|
||||
return 1;
|
||||
PyOS_snprintf(msgbuf, sizeof(msgbuf),
|
||||
"%.200s%s takes no arguments",
|
||||
fname==NULL ? "function" : fname,
|
||||
fname==NULL ? "" : "()");
|
||||
PyErr_SetString(PyExc_TypeError, msgbuf);
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%.200s%s takes no arguments",
|
||||
fname==NULL ? "function" : fname,
|
||||
fname==NULL ? "" : "()");
|
||||
return 0;
|
||||
}
|
||||
else if (min == 1 && max == 1) {
|
||||
if (args == NULL) {
|
||||
PyOS_snprintf(msgbuf, sizeof(msgbuf),
|
||||
"%.200s%s takes at least one argument",
|
||||
fname==NULL ? "function" : fname,
|
||||
fname==NULL ? "" : "()");
|
||||
PyErr_SetString(PyExc_TypeError, msgbuf);
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%.200s%s takes at least one argument",
|
||||
fname==NULL ? "function" : fname,
|
||||
fname==NULL ? "" : "()");
|
||||
return 0;
|
||||
}
|
||||
msg = convertitem(args, &format, p_va, flags, levels,
|
||||
|
@ -349,20 +347,18 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
|||
len = PyTuple_GET_SIZE(args);
|
||||
|
||||
if (len < min || max < len) {
|
||||
if (message == NULL) {
|
||||
PyOS_snprintf(msgbuf, sizeof(msgbuf),
|
||||
"%.150s%s takes %s %d argument%s "
|
||||
"(%ld given)",
|
||||
fname==NULL ? "function" : fname,
|
||||
fname==NULL ? "" : "()",
|
||||
min==max ? "exactly"
|
||||
: len < min ? "at least" : "at most",
|
||||
len < min ? min : max,
|
||||
(len < min ? min : max) == 1 ? "" : "s",
|
||||
Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
|
||||
message = msgbuf;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, message);
|
||||
if (message == NULL)
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%.150s%s takes %s %d argument%s (%ld given)",
|
||||
fname==NULL ? "function" : fname,
|
||||
fname==NULL ? "" : "()",
|
||||
min==max ? "exactly"
|
||||
: len < min ? "at least" : "at most",
|
||||
len < min ? min : max,
|
||||
(len < min ? min : max) == 1 ? "" : "s",
|
||||
Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
|
||||
else
|
||||
PyErr_SetString(PyExc_TypeError, message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1458,8 +1454,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
|
|||
nargs = PyTuple_GET_SIZE(args);
|
||||
nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);
|
||||
if (nargs + nkeywords > len) {
|
||||
PyErr_Format(PyExc_TypeError, "%s%s takes at most %d "
|
||||
"argument%s (%d given)",
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%s%s takes at most %d argument%s (%d given)",
|
||||
(fname == NULL) ? "function" : fname,
|
||||
(fname == NULL) ? "" : "()",
|
||||
len,
|
||||
|
|
Loading…
Reference in New Issue