From e1c76f1b6bb425aee6620cda7d27ec03aef96dcb Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 6 Jun 2017 20:39:21 +0300 Subject: [PATCH 1/5] bpo-27867: Add a porting guide for PySlice_GetIndicesEx(). --- Doc/c-api/slice.rst | 14 ++++++++++++++ Doc/whatsnew/3.7.rst | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst index f8395ec8d770229..9811a02c5237f96 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -53,6 +53,20 @@ Slice Objects Returns ``0`` on success and ``-1`` on error with exception set. + .. note:: + This function considered not safe for resizable sequences. Replace its invocation :: + + if (PySlice_GetIndicesEx(slice, length, &start, &stop, &step, &slicelength) < 0) { + // return error + } + + with using functions :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices`:: + + if (PySlice_Unpack(slice, length, &start, &stop, &step) < 0) { + // return error + } + slicelength = PySlice_AdjustIndices(length, &start, &stop, step); + .. versionchanged:: 3.2 The parameter type for the *slice* parameter was ``PySliceObject*`` before. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 602db8c0ac8e681..ddf06c2c1d4a41d 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -366,6 +366,20 @@ Changes in the Python API (Contributed by Serhiy Storchaka in :issue:`19930`.) +Changes in the C API +-------------------- + +* Function :c:func:`PySlice_GetIndicesEx` is considered not safe for + resizable sequences. It takes the current length of the sequence, but + if the slice indices are not instances of :class:`int`, but objects that + implement the :meth:`__index__` method, the sequence can be resized + during executing the :meth:`!__index__` method, and resulting values can + be computed with wrong sequence length. For avoiding possible issues + use new functions :c:func:`PySlice_Unpack` and + :c:func:`PySlice_AdjustIndices`. + (Contributed by Serhiy Storchaka in :issue:`27867`.) + + CPython bytecode changes ------------------------ From 66bd54b38c051c93c27fd8f81c2e7353c193f8f3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 9 Jun 2017 17:46:02 +0300 Subject: [PATCH 2/5] Fixed a typo. --- Doc/c-api/slice.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst index 9811a02c5237f96..457bca656ac05d9 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -54,7 +54,7 @@ Slice Objects Returns ``0`` on success and ``-1`` on error with exception set. .. note:: - This function considered not safe for resizable sequences. Replace its invocation :: + This function is considered not safe for resizable sequences. Replace its invocation :: if (PySlice_GetIndicesEx(slice, length, &start, &stop, &step, &slicelength) < 0) { // return error From 872784b6fe53fb8868b9bc259800dbbdf1da74af Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 21 Sep 2017 22:10:33 +0300 Subject: [PATCH 3/5] Address review comments. --- Doc/c-api/slice.rst | 8 +++++--- Doc/whatsnew/3.7.rst | 13 ++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst index 457bca656ac05d9..9d3b53b337e6390 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -54,13 +54,15 @@ Slice Objects Returns ``0`` on success and ``-1`` on error with exception set. .. note:: - This function is considered not safe for resizable sequences. Replace its invocation :: + This function is considered not safe for resizable sequences. + Its invocation should be replaced by a combination of + :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices` where :: if (PySlice_GetIndicesEx(slice, length, &start, &stop, &step, &slicelength) < 0) { // return error } - with using functions :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices`:: + is replaced by :: if (PySlice_Unpack(slice, length, &start, &stop, &step) < 0) { // return error @@ -75,7 +77,7 @@ Slice Objects If ``Py_LIMITED_API`` is not set or set to the value between ``0x03050400`` and ``0x03060000`` (not including) or ``0x03060100`` or higher :c:func:`!PySlice_GetIndicesEx` is implemented as a macro using - :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices`. + :c:func:`!PySlice_Unpack` and :c:func:`!PySlice_AdjustIndices`. Arguments *start*, *stop* and *step* are evaluated more than once. .. deprecated:: 3.6.1 diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 75172dd1d2528a1..539f0e67a7267b0 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -505,13 +505,12 @@ Changes in the Python API Changes in the C API -------------------- -* Function :c:func:`PySlice_GetIndicesEx` is considered not safe for - resizable sequences. It takes the current length of the sequence, but - if the slice indices are not instances of :class:`int`, but objects that - implement the :meth:`__index__` method, the sequence can be resized - during executing the :meth:`!__index__` method, and resulting values can - be computed with wrong sequence length. For avoiding possible issues - use new functions :c:func:`PySlice_Unpack` and +* The function :c:func:`PySlice_GetIndicesEx` is considered not safe for + resizable sequences. If the slice indices are not instances of :class:`int`, + but objects that implement the :meth:`!__index__` method, the sequence can be + resized after passing its length to :c:func:`!PySlice_GetIndicesEx`. This + can lead to returning indices out of the length of the sequence. For + avoiding possible problems use new functions :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices`. (Contributed by Serhiy Storchaka in :issue:`27867`.) From d66a578dd0bc4e1b983eae152781c534b74335bc Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 4 Oct 2017 16:26:53 +0300 Subject: [PATCH 4/5] Fix the example. --- Doc/c-api/slice.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst index 9d3b53b337e6390..107a55018382db2 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -58,7 +58,7 @@ Slice Objects Its invocation should be replaced by a combination of :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices` where :: - if (PySlice_GetIndicesEx(slice, length, &start, &stop, &step, &slicelength) < 0) { + if (PySlice_GetIndicesEx(slice, &start, &stop, &step, &slicelength) < 0) { // return error } From 8661b1899dfa85b531e6179b337b115caa0d9d51 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 8 Oct 2017 10:21:55 +0300 Subject: [PATCH 5/5] Correctly fix the example. --- Doc/c-api/slice.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst index 107a55018382db2..8ad9a29b256ebce 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -58,13 +58,13 @@ Slice Objects Its invocation should be replaced by a combination of :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices` where :: - if (PySlice_GetIndicesEx(slice, &start, &stop, &step, &slicelength) < 0) { + if (PySlice_GetIndicesEx(slice, length, &start, &stop, &step, &slicelength) < 0) { // return error } is replaced by :: - if (PySlice_Unpack(slice, length, &start, &stop, &step) < 0) { + if (PySlice_Unpack(slice, &start, &stop, &step) < 0) { // return error } slicelength = PySlice_AdjustIndices(length, &start, &stop, step);