Skip to content

Rare corner case bug in pairwise() #109764

Open
@rhettinger

Description

@rhettinger

If PyTuple_Pack fails with a MemoryError, the iterator needs to be permanently stopped because the most recently fetched input item will have been skipped in the output stream.

Fix:

diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index 4ed34aa5bd..409498665d 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -344,6 +344,15 @@ pairwise_next(pairwiseobject *po)
     }
     /* Future optimization: Reuse the result tuple as we do in enumerate() */
     result = PyTuple_Pack(2, old, new);
+    if (result == NULL) {
+        /* Terminate the iterator because once a new the item has
+           been retrieved from the upstream iterator, it is lost and
+           pairwise() cannot yield a correct result on a subsequent call. */
+        Py_CLEAR(po->it);
+        Py_CLEAR(po->old);
+        Py_DECREF(new);
+        return NULL;
+    }
     Py_SETREF(po->old, new);
     return result;
 }

Off-hand I don't see how to write a test for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.11only security fixes3.12only security fixesextension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions