mirror of https://github.com/python/cpython
fix expandtabs overflow detection to be consistent and not rely on signed overflow
This commit is contained in:
parent
cf25c5caae
commit
23cf403ca1
|
@ -15,7 +15,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
const char *e, *p;
|
const char *e, *p;
|
||||||
char *q;
|
char *q;
|
||||||
size_t i, j;
|
Py_ssize_t i, j;
|
||||||
PyObject *u;
|
PyObject *u;
|
||||||
int tabsize = 8;
|
int tabsize = 8;
|
||||||
|
|
||||||
|
@ -25,35 +25,31 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
|
||||||
/* First pass: determine size of output string */
|
/* First pass: determine size of output string */
|
||||||
i = j = 0;
|
i = j = 0;
|
||||||
e = STRINGLIB_STR(self) + STRINGLIB_LEN(self);
|
e = STRINGLIB_STR(self) + STRINGLIB_LEN(self);
|
||||||
for (p = STRINGLIB_STR(self); p < e; p++)
|
for (p = STRINGLIB_STR(self); p < e; p++) {
|
||||||
if (*p == '\t') {
|
if (*p == '\t') {
|
||||||
if (tabsize > 0) {
|
if (tabsize > 0) {
|
||||||
j += tabsize - (j % tabsize);
|
Py_ssize_t incr = tabsize - (j % tabsize);
|
||||||
if (j > PY_SSIZE_T_MAX) {
|
if (j > PY_SSIZE_T_MAX - incr)
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
goto overflow;
|
||||||
"result is too long");
|
j += incr;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (j > PY_SSIZE_T_MAX - 1)
|
||||||
|
goto overflow;
|
||||||
j++;
|
j++;
|
||||||
if (*p == '\n' || *p == '\r') {
|
if (*p == '\n' || *p == '\r') {
|
||||||
|
if (i > PY_SSIZE_T_MAX - j)
|
||||||
|
goto overflow;
|
||||||
i += j;
|
i += j;
|
||||||
j = 0;
|
j = 0;
|
||||||
if (i > PY_SSIZE_T_MAX) {
|
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
|
||||||
"result is too long");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((i + j) > PY_SSIZE_T_MAX) {
|
|
||||||
PyErr_SetString(PyExc_OverflowError, "result is too long");
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i > PY_SSIZE_T_MAX - j)
|
||||||
|
goto overflow;
|
||||||
|
|
||||||
/* Second pass: create output string and fill it */
|
/* Second pass: create output string and fill it */
|
||||||
u = STRINGLIB_NEW(NULL, i + j);
|
u = STRINGLIB_NEW(NULL, i + j);
|
||||||
if (!u)
|
if (!u)
|
||||||
|
@ -62,7 +58,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
|
||||||
j = 0;
|
j = 0;
|
||||||
q = STRINGLIB_STR(u);
|
q = STRINGLIB_STR(u);
|
||||||
|
|
||||||
for (p = STRINGLIB_STR(self); p < e; p++)
|
for (p = STRINGLIB_STR(self); p < e; p++) {
|
||||||
if (*p == '\t') {
|
if (*p == '\t') {
|
||||||
if (tabsize > 0) {
|
if (tabsize > 0) {
|
||||||
i = tabsize - (j % tabsize);
|
i = tabsize - (j % tabsize);
|
||||||
|
@ -77,8 +73,12 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
|
||||||
if (*p == '\n' || *p == '\r')
|
if (*p == '\n' || *p == '\r')
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return u;
|
return u;
|
||||||
|
overflow:
|
||||||
|
PyErr_SetString(PyExc_OverflowError, "result too long");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_LOCAL_INLINE(PyObject *)
|
Py_LOCAL_INLINE(PyObject *)
|
||||||
|
|
Loading…
Reference in New Issue