summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Sneddon <me@gsnedders.com>2020-04-20 08:25:57 +0100
committerGitHub <noreply@github.com>2020-04-20 09:25:57 +0200
commit2697cdb069add4c143b2d366a86a92c1d29b8d3b (patch)
treefbfbd6acf92f5c508136ea788800c164bcc9cc45
parent105491439c2fbc166e73206c49a34196a4e2ff61 (diff)
downloadcython-2697cdb069add4c143b2d366a86a92c1d29b8d3b.tar.gz
Avoid integer overflow when computing unicode substring (GH-3532)
Fixes #3531.
-rw-r--r--Cython/Utility/StringTools.c3
-rw-r--r--tests/run/unicode_slicing.pyx36
2 files changed, 30 insertions, 9 deletions
diff --git a/Cython/Utility/StringTools.c b/Cython/Utility/StringTools.c
index 29a151d80..4f6009eca 100644
--- a/Cython/Utility/StringTools.c
+++ b/Cython/Utility/StringTools.c
@@ -610,8 +610,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
stop += length;
else if (stop > length)
stop = length;
- length = stop - start;
- if (length <= 0)
+ if (stop <= start)
return PyUnicode_FromUnicode(NULL, 0);
#if CYTHON_PEP393_ENABLED
return PyUnicode_FromKindAndData(PyUnicode_KIND(text),
diff --git a/tests/run/unicode_slicing.pyx b/tests/run/unicode_slicing.pyx
index fa48dde59..c84d7052e 100644
--- a/tests/run/unicode_slicing.pyx
+++ b/tests/run/unicode_slicing.pyx
@@ -151,30 +151,52 @@ __doc__ = u"""
>>> slice_none_none(None, 2, 4)
Traceback (most recent call last):
TypeError: 'NoneType' object is not subscriptable
+
+ >>> slice_start_end(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+ <BLANKLINE>
+ >>> slice_start(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+ <BLANKLINE>
+ >>> slice_end(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+ abcdef
+ >>> slice_all(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+ abcdef
+ >>> slice_start_none(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+ <BLANKLINE>
+ >>> slice_none_end(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+ abcdef
+ >>> slice_none_none(u'abcdef', SSIZE_T_MAX, SSIZE_T_MIN)
+ abcdef
"""
+cdef extern from *:
+ cdef Py_ssize_t PY_SSIZE_T_MIN
+ cdef Py_ssize_t PY_SSIZE_T_MAX
+
+SSIZE_T_MAX = PY_SSIZE_T_MAX
+SSIZE_T_MIN = PY_SSIZE_T_MIN
+
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"(u'", u"('").replace(u" u'", u" '")
-def slice_start_end(unicode s, int i, int j):
+def slice_start_end(unicode s, Py_ssize_t i, Py_ssize_t j):
print(s[i:j])
-def slice_start(unicode s, int i, int j):
+def slice_start(unicode s, Py_ssize_t i, Py_ssize_t j):
print(s[i:])
-def slice_end(unicode s, int i, int j):
+def slice_end(unicode s, Py_ssize_t i, Py_ssize_t j):
print(s[:i])
-def slice_all(unicode s, int i, int j):
+def slice_all(unicode s, Py_ssize_t i, Py_ssize_t j):
print(s[:])
-def slice_start_none(unicode s, int i, int j):
+def slice_start_none(unicode s, Py_ssize_t i, Py_ssize_t j):
print(s[i:None])
-def slice_none_end(unicode s, int i, int j):
+def slice_none_end(unicode s, Py_ssize_t i, Py_ssize_t j):
print(s[None:i])
-def slice_none_none(unicode s, int i, int j):
+def slice_none_none(unicode s, Py_ssize_t i, Py_ssize_t j):
print(s[None:None])