From 23ae3e9d22f55463680f5b6a42d01b2e7a340717 Mon Sep 17 00:00:00 2001 From: hongweipeng Date: Thu, 13 Sep 2018 09:58:54 +0800 Subject: [PATCH 1/2] bpo-34410: itertools.tee not thread-safe; can segfault --- Modules/itertoolsmodule.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index ec8f0ae14206cb..fa9f3ba9fd6be2 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -492,10 +492,18 @@ teedataobject_getitem(teedataobject *tdo, int i) /* this is the lead iterator, so fetch more data */ assert(i == tdo->numread); value = PyIter_Next(tdo->it); - if (value == NULL) + + if (value != NULL) { + teedataobject *temp = tdo; + while (temp->numread + 1 > LINKCELLS) { + temp = (teedataobject *) teedataobject_jumplink(temp); + } + temp->values[temp->numread] = value; + temp->numread++; + }else if (i == tdo->numread) { return NULL; - tdo->numread++; - tdo->values[i] = value; + } + value = tdo->values[i]; } Py_INCREF(value); return value; From 74996152e63c844bd0344055c6ba2c22cc1270cd Mon Sep 17 00:00:00 2001 From: hongweipeng <961365124@qq.com> Date: Thu, 22 Aug 2019 16:24:21 +0800 Subject: [PATCH 2/2] code review --- .../next/Library/2019-08-22-16-08-46.bpo-34410.4DcUaI.rst | 1 + Modules/itertoolsmodule.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-08-22-16-08-46.bpo-34410.4DcUaI.rst diff --git a/Misc/NEWS.d/next/Library/2019-08-22-16-08-46.bpo-34410.4DcUaI.rst b/Misc/NEWS.d/next/Library/2019-08-22-16-08-46.bpo-34410.4DcUaI.rst new file mode 100644 index 00000000000000..8c1d6ad36819f7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-08-22-16-08-46.bpo-34410.4DcUaI.rst @@ -0,0 +1 @@ +Fix itertools.tee() crash in multithreading. Patch by hongweipeng. diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index fa9f3ba9fd6be2..8024b8c62f090c 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -495,12 +495,12 @@ teedataobject_getitem(teedataobject *tdo, int i) if (value != NULL) { teedataobject *temp = tdo; - while (temp->numread + 1 > LINKCELLS) { + while (temp->numread >= LINKCELLS) { temp = (teedataobject *) teedataobject_jumplink(temp); } temp->values[temp->numread] = value; temp->numread++; - }else if (i == tdo->numread) { + }else if (i == tdo->numread || PyErr_Occurred()) { return NULL; } value = tdo->values[i];