Kaydet (Commit) d42f60ed authored tarafından Benjamin Peterson's avatar Benjamin Peterson

fix overflow detection of strop.expandtabs

üst 18fc4934
...@@ -4,6 +4,7 @@ warnings.filterwarnings("ignore", "strop functions are obsolete;", ...@@ -4,6 +4,7 @@ warnings.filterwarnings("ignore", "strop functions are obsolete;",
r'test.test_strop|unittest') r'test.test_strop|unittest')
import strop import strop
import unittest import unittest
import sys
from test import test_support from test import test_support
...@@ -115,6 +116,11 @@ class StropFunctionTestCase(unittest.TestCase): ...@@ -115,6 +116,11 @@ class StropFunctionTestCase(unittest.TestCase):
strop.uppercase strop.uppercase
strop.whitespace strop.whitespace
@unittest.skipUnless(sys.maxsize == 2147483647, "only for 32-bit")
def test_expandtabs_overflow(self):
s = '\t\n' * 0x10000 + 'A' * 0x1000000
self.assertRaises(OverflowError, strop.expandtabs, s, 0x10001)
@test_support.precisionbigmemtest(size=test_support._2G - 1, memuse=5) @test_support.precisionbigmemtest(size=test_support._2G - 1, memuse=5)
def test_stropjoin_huge_list(self, size): def test_stropjoin_huge_list(self, size):
a = "A" * size a = "A" * size
......
...@@ -40,6 +40,9 @@ Core and Builtins ...@@ -40,6 +40,9 @@ Core and Builtins
Library Library
------- -------
- Fix possible overflow bug in strop.expandtabs. You shouldn't be using this
module!
- Issue #20145: `assertRaisesRegex` now raises a TypeError if the second - Issue #20145: `assertRaisesRegex` now raises a TypeError if the second
argument is not a string or compiled regex. argument is not a string or compiled regex.
......
...@@ -593,7 +593,7 @@ strop_expandtabs(PyObject *self, PyObject *args) ...@@ -593,7 +593,7 @@ strop_expandtabs(PyObject *self, PyObject *args)
char* e; char* e;
char* p; char* p;
char* q; char* q;
Py_ssize_t i, j, old_j; Py_ssize_t i, j;
PyObject* out; PyObject* out;
char* string; char* string;
Py_ssize_t stringlen; Py_ssize_t stringlen;
...@@ -610,30 +610,29 @@ strop_expandtabs(PyObject *self, PyObject *args) ...@@ -610,30 +610,29 @@ strop_expandtabs(PyObject *self, PyObject *args)
} }
/* First pass: determine size of output string */ /* First pass: determine size of output string */
i = j = old_j = 0; /* j: current column; i: total of previous lines */ i = j = 0; /* j: current column; i: total of previous lines */
e = string + stringlen; e = string + stringlen;
for (p = string; p < e; p++) { for (p = string; p < e; p++) {
if (*p == '\t') { if (*p == '\t') {
j += tabsize - (j%tabsize); Py_ssize_t incr = tabsize - (j%tabsize);
if (old_j > j) { if (j > PY_SSIZE_T_MAX - incr)
PyErr_SetString(PyExc_OverflowError, goto overflow;
"new string is too long"); j += incr;
return NULL;
}
old_j = j;
} else { } else {
if (j > PY_SSIZE_T_MAX - 1)
goto overflow;
j++; j++;
if (*p == '\n') { if (*p == '\n') {
if (i > PY_SSIZE_T_MAX - j)
goto overflow;
i += j; i += j;
j = 0; j = 0;
} }
} }
} }
if ((i + j) < 0) { if (i > PY_SSIZE_T_MAX - j)
PyErr_SetString(PyExc_OverflowError, "new string is too long"); goto overflow;
return NULL;
}
/* Second pass: create output string and fill it */ /* Second pass: create output string and fill it */
out = PyString_FromStringAndSize(NULL, i+j); out = PyString_FromStringAndSize(NULL, i+j);
...@@ -658,6 +657,9 @@ strop_expandtabs(PyObject *self, PyObject *args) ...@@ -658,6 +657,9 @@ strop_expandtabs(PyObject *self, PyObject *args)
} }
return out; return out;
overflow:
PyErr_SetString(PyExc_OverflowError, "result is too long");
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