Skip to content

Commit 18fc493

Browse files
committed
fix expandtabs overflow detection to be consistent and not rely on signed overflow
1 parent 8312ecc commit 18fc493

File tree

1 file changed

+19
-19
lines changed

1 file changed

+19
-19
lines changed

Objects/stringlib/transmogrify.h

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
1515
{
1616
const char *e, *p;
1717
char *q;
18-
size_t i, j;
18+
Py_ssize_t i, j;
1919
PyObject *u;
2020
int tabsize = 8;
2121

@@ -25,35 +25,31 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
2525
/* First pass: determine size of output string */
2626
i = j = 0;
2727
e = STRINGLIB_STR(self) + STRINGLIB_LEN(self);
28-
for (p = STRINGLIB_STR(self); p < e; p++)
28+
for (p = STRINGLIB_STR(self); p < e; p++) {
2929
if (*p == '\t') {
3030
if (tabsize > 0) {
31-
j += tabsize - (j % tabsize);
32-
if (j > PY_SSIZE_T_MAX) {
33-
PyErr_SetString(PyExc_OverflowError,
34-
"result is too long");
35-
return NULL;
36-
}
31+
Py_ssize_t incr = tabsize - (j % tabsize);
32+
if (j > PY_SSIZE_T_MAX - incr)
33+
goto overflow;
34+
j += incr;
3735
}
3836
}
3937
else {
38+
if (j > PY_SSIZE_T_MAX - 1)
39+
goto overflow;
4040
j++;
4141
if (*p == '\n' || *p == '\r') {
42+
if (i > PY_SSIZE_T_MAX - j)
43+
goto overflow;
4244
i += j;
4345
j = 0;
44-
if (i > PY_SSIZE_T_MAX) {
45-
PyErr_SetString(PyExc_OverflowError,
46-
"result is too long");
47-
return NULL;
48-
}
4946
}
5047
}
51-
52-
if ((i + j) > PY_SSIZE_T_MAX) {
53-
PyErr_SetString(PyExc_OverflowError, "result is too long");
54-
return NULL;
5548
}
5649

50+
if (i > PY_SSIZE_T_MAX - j)
51+
goto overflow;
52+
5753
/* Second pass: create output string and fill it */
5854
u = STRINGLIB_NEW(NULL, i + j);
5955
if (!u)
@@ -62,7 +58,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
6258
j = 0;
6359
q = STRINGLIB_STR(u);
6460

65-
for (p = STRINGLIB_STR(self); p < e; p++)
61+
for (p = STRINGLIB_STR(self); p < e; p++) {
6662
if (*p == '\t') {
6763
if (tabsize > 0) {
6864
i = tabsize - (j % tabsize);
@@ -77,8 +73,12 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
7773
if (*p == '\n' || *p == '\r')
7874
j = 0;
7975
}
80-
76+
}
77+
8178
return u;
79+
overflow:
80+
PyErr_SetString(PyExc_OverflowError, "result too long");
81+
return NULL;
8282
}
8383

8484
Py_LOCAL_INLINE(PyObject *)

0 commit comments

Comments
 (0)