diff options
author | Sam Sneddon <me@gsnedders.com> | 2020-04-20 08:25:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-20 09:25:57 +0200 |
commit | 2697cdb069add4c143b2d366a86a92c1d29b8d3b (patch) | |
tree | fbfbd6acf92f5c508136ea788800c164bcc9cc45 | |
parent | 105491439c2fbc166e73206c49a34196a4e2ff61 (diff) | |
download | cython-2697cdb069add4c143b2d366a86a92c1d29b8d3b.tar.gz |
Avoid integer overflow when computing unicode substring (GH-3532)
Fixes #3531.
-rw-r--r-- | Cython/Utility/StringTools.c | 3 | ||||
-rw-r--r-- | tests/run/unicode_slicing.pyx | 36 |
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]) |