Kaydet (Commit) c2f02216 authored tarafından Antoine Pitrou's avatar Antoine Pitrou

Issue #4935: The overflow checking code in the expandtabs() method common

to str, bytes and bytearray could be optimized away by the compiler, letting
the interpreter segfault instead of raising an error.
üst 3a5067c2
...@@ -12,6 +12,10 @@ What's New in Python 2.7 alpha 1 ...@@ -12,6 +12,10 @@ What's New in Python 2.7 alpha 1
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #4935: The overflow checking code in the expandtabs() method common
to str, bytes and bytearray could be optimized away by the compiler, letting
the interpreter segfault instead of raising an error.
- Issue #3720: Fix a crash when an iterator modifies its class and removes its - Issue #3720: Fix a crash when an iterator modifies its class and removes its
__next__ method. __next__ method.
......
...@@ -22,7 +22,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args) ...@@ -22,7 +22,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
{ {
const char *e, *p; const char *e, *p;
char *q; char *q;
Py_ssize_t i, j, old_j; size_t i, j;
PyObject *u; PyObject *u;
int tabsize = 8; int tabsize = 8;
...@@ -30,30 +30,25 @@ stringlib_expandtabs(PyObject *self, PyObject *args) ...@@ -30,30 +30,25 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
return NULL; return NULL;
/* First pass: determine size of output string */ /* First pass: determine size of output string */
i = j = old_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); j += tabsize - (j % tabsize);
/* XXX: this depends on a signed integer overflow to < 0 */ if (j > PY_SSIZE_T_MAX) {
/* C compilers, including gcc, do -NOT- guarantee this. */
if (old_j > j) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"result is too long"); "result is too long");
return NULL; return NULL;
} }
old_j = j;
} }
} }
else { else {
j++; j++;
if (*p == '\n' || *p == '\r') { if (*p == '\n' || *p == '\r') {
i += j; i += j;
old_j = j = 0; j = 0;
/* XXX: this depends on a signed integer overflow to < 0 */ if (i > PY_SSIZE_T_MAX) {
/* C compilers, including gcc, do -NOT- guarantee this. */
if (i < 0) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"result is too long"); "result is too long");
return NULL; return NULL;
...@@ -61,9 +56,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args) ...@@ -61,9 +56,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
} }
} }
if ((i + j) < 0) { if ((i + j) > PY_SSIZE_T_MAX) {
/* XXX: this depends on a signed integer overflow to < 0 */
/* C compilers, including gcc, do -NOT- guarantee this. */
PyErr_SetString(PyExc_OverflowError, "result is too long"); PyErr_SetString(PyExc_OverflowError, "result is too long");
return NULL; return NULL;
} }
......
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