Commit 537925e7 authored by Victor Stinner's avatar Victor Stinner

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.
parent 58c5d21e
...@@ -766,7 +766,7 @@ typedef struct ...@@ -766,7 +766,7 @@ typedef struct
PyObject *name; PyObject *name;
} PyDateTime_TimeZone; } PyDateTime_TimeZone;
/* The interned UTC timezone instance */ /* The interned UTC timezone instance */
static PyObject *PyDateTime_TimeZone_UTC; static PyObject *PyDateTime_TimeZone_UTC;
/* Create new timezone instance checking offset range. This /* Create new timezone instance checking offset range. This
...@@ -3287,7 +3287,6 @@ timezone_repr(PyDateTime_TimeZone *self) ...@@ -3287,7 +3287,6 @@ timezone_repr(PyDateTime_TimeZone *self)
static PyObject * static PyObject *
timezone_str(PyDateTime_TimeZone *self) timezone_str(PyDateTime_TimeZone *self)
{ {
char buf[10];
int hours, minutes, seconds; int hours, minutes, seconds;
PyObject *offset; PyObject *offset;
char sign; char sign;
...@@ -3313,11 +3312,9 @@ timezone_str(PyDateTime_TimeZone *self) ...@@ -3313,11 +3312,9 @@ timezone_str(PyDateTime_TimeZone *self)
Py_DECREF(offset); Py_DECREF(offset);
minutes = divmod(seconds, 60, &seconds); minutes = divmod(seconds, 60, &seconds);
hours = divmod(minutes, 60, &minutes); hours = divmod(minutes, 60, &minutes);
assert(seconds == 0);
/* XXX ignore sub-minute data, curently not allowed. */ /* XXX ignore sub-minute data, curently not allowed. */
PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes); assert(seconds == 0);
return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
return PyUnicode_FromString(buf);
} }
static PyObject * static PyObject *
......
...@@ -22,14 +22,7 @@ static PyObject *TestError; /* set to exception object in init */ ...@@ -22,14 +22,7 @@ static PyObject *TestError; /* set to exception object in init */
static PyObject * static PyObject *
raiseTestError(const char* test_name, const char* msg) raiseTestError(const char* test_name, const char* msg)
{ {
char buf[2048]; PyErr_Format(TestError, "%s: %s", test_name, msg);
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);
}
return NULL; return NULL;
} }
......
...@@ -2400,11 +2400,9 @@ static PyObject * ...@@ -2400,11 +2400,9 @@ static PyObject *
Tktt_Repr(PyObject *self) Tktt_Repr(PyObject *self)
{ {
TkttObject *v = (TkttObject *)self; TkttObject *v = (TkttObject *)self;
char buf[100]; return PyUnicode_FromFormat("<tktimertoken at %p%s>",
v,
PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v, v->func == NULL ? ", handler deleted" : "");
v->func == NULL ? ", handler deleted" : "");
return PyUnicode_FromString(buf);
} }
static PyTypeObject Tktt_Type = static PyTypeObject Tktt_Type =
......
...@@ -233,10 +233,9 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *args) ...@@ -233,10 +233,9 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *args)
Py_XDECREF(tmp); Py_XDECREF(tmp);
} }
else { else {
PyOS_snprintf(buf, sizeof(buf), PyErr_Format(PyExc_TypeError,
"set_%.50s(func): argument not callable", "set_%.50s(func): argument not callable",
funcname); funcname);
PyErr_SetString(PyExc_TypeError, buf);
return NULL; return NULL;
} }
Py_RETURN_NONE; Py_RETURN_NONE;
...@@ -890,7 +889,7 @@ setup_readline(void) ...@@ -890,7 +889,7 @@ setup_readline(void)
#endif #endif
#ifdef __APPLE__ #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 * when calling rl_initialize. So call it upfront
*/ */
if (using_libedit_emulation) if (using_libedit_emulation)
...@@ -930,11 +929,11 @@ setup_readline(void) ...@@ -930,11 +929,11 @@ setup_readline(void)
*/ */
#ifdef __APPLE__ #ifdef __APPLE__
if (using_libedit_emulation) if (using_libedit_emulation)
rl_read_init_file(NULL); rl_read_init_file(NULL);
else else
#endif /* __APPLE__ */ #endif /* __APPLE__ */
rl_initialize(); rl_initialize();
RESTORE_LOCALE(saved_locale) RESTORE_LOCALE(saved_locale)
} }
......
...@@ -330,12 +330,10 @@ complex_repr(PyComplexObject *v) ...@@ -330,12 +330,10 @@ complex_repr(PyComplexObject *v)
int precision = 0; int precision = 0;
char format_code = 'r'; char format_code = 'r';
PyObject *result = NULL; PyObject *result = NULL;
Py_ssize_t len;
/* If these are non-NULL, they'll need to be freed. */ /* If these are non-NULL, they'll need to be freed. */
char *pre = NULL; char *pre = NULL;
char *im = NULL; char *im = NULL;
char *buf = NULL;
/* These do not need to be freed. re is either an alias /* These do not need to be freed. re is either an alias
for pre or a pointer to a constant. lead and tail for pre or a pointer to a constant. lead and tail
...@@ -374,20 +372,10 @@ complex_repr(PyComplexObject *v) ...@@ -374,20 +372,10 @@ complex_repr(PyComplexObject *v)
lead = "("; lead = "(";
tail = ")"; tail = ")";
} }
/* Alloc the final buffer. Add one for the "j" in the format string, result = PyUnicode_FromFormat("%s%s%sj%s", lead, re, im, tail);
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);
done: done:
PyMem_Free(im); PyMem_Free(im);
PyMem_Free(pre); PyMem_Free(pre);
PyMem_Free(buf);
return result; return result;
} }
......
...@@ -310,20 +310,18 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) ...@@ -310,20 +310,18 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
if (max == 0) { if (max == 0) {
if (args == NULL) if (args == NULL)
return 1; return 1;
PyOS_snprintf(msgbuf, sizeof(msgbuf), PyErr_Format(PyExc_TypeError,
"%.200s%s takes no arguments", "%.200s%s takes no arguments",
fname==NULL ? "function" : fname, fname==NULL ? "function" : fname,
fname==NULL ? "" : "()"); fname==NULL ? "" : "()");
PyErr_SetString(PyExc_TypeError, msgbuf);
return 0; return 0;
} }
else if (min == 1 && max == 1) { else if (min == 1 && max == 1) {
if (args == NULL) { if (args == NULL) {
PyOS_snprintf(msgbuf, sizeof(msgbuf), PyErr_Format(PyExc_TypeError,
"%.200s%s takes at least one argument", "%.200s%s takes at least one argument",
fname==NULL ? "function" : fname, fname==NULL ? "function" : fname,
fname==NULL ? "" : "()"); fname==NULL ? "" : "()");
PyErr_SetString(PyExc_TypeError, msgbuf);
return 0; return 0;
} }
msg = convertitem(args, &format, p_va, flags, levels, msg = convertitem(args, &format, p_va, flags, levels,
...@@ -349,20 +347,18 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) ...@@ -349,20 +347,18 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
len = PyTuple_GET_SIZE(args); len = PyTuple_GET_SIZE(args);
if (len < min || max < len) { if (len < min || max < len) {
if (message == NULL) { if (message == NULL)
PyOS_snprintf(msgbuf, sizeof(msgbuf), PyErr_Format(PyExc_TypeError,
"%.150s%s takes %s %d argument%s " "%.150s%s takes %s %d argument%s (%ld given)",
"(%ld given)", fname==NULL ? "function" : fname,
fname==NULL ? "function" : fname, fname==NULL ? "" : "()",
fname==NULL ? "" : "()", min==max ? "exactly"
min==max ? "exactly" : len < min ? "at least" : "at most",
: len < min ? "at least" : "at most", len < min ? min : max,
len < min ? min : max, (len < min ? min : max) == 1 ? "" : "s",
(len < min ? min : max) == 1 ? "" : "s", Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
Py_SAFE_DOWNCAST(len, Py_ssize_t, long)); else
message = msgbuf; PyErr_SetString(PyExc_TypeError, message);
}
PyErr_SetString(PyExc_TypeError, message);
return 0; return 0;
} }
...@@ -1458,8 +1454,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1458,8 +1454,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
nargs = PyTuple_GET_SIZE(args); nargs = PyTuple_GET_SIZE(args);
nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords); nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);
if (nargs + nkeywords > len) { if (nargs + nkeywords > len) {
PyErr_Format(PyExc_TypeError, "%s%s takes at most %d " PyErr_Format(PyExc_TypeError,
"argument%s (%d given)", "%s%s takes at most %d argument%s (%d given)",
(fname == NULL) ? "function" : fname, (fname == NULL) ? "function" : fname,
(fname == NULL) ? "" : "()", (fname == NULL) ? "" : "()",
len, len,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment