8000 gh-126595: fix a crash when calling `itertools.count(sys.maxsize)` by picnixz · Pull Request #126617 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-126595: fix a crash when calling itertools.count(sys.maxsize) #126617

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 12, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix a crash in __repr__
  • Loading branch information
picnixz committed Nov 9, 2024
commit eb15e7187df323b4409ca6dd2b404d2ca08ee8f1
38 changes: 36 additions & 2 deletions Modules/itertoolsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3386,13 +3386,35 @@ count_nextlong(countobject *lz)
return long_cnt;
}

static inline int
count_switch_to_slow_mode(countobject *lz)
{
assert(lz->cnt == PY_SSIZE_T_MAX);
assert(lz->long_cnt == NULL);
/* Switch to slow_mode */
PyObject *long_cnt = PyLong_FromSsize_t(PY_SSIZE_T_MAX);
if (long_cnt == NULL) {
return -1;
}
lz->long_cnt = long_cnt;
return 0;
}

static PyObject *
count_next(countobject *lz)
{
#ifndef Py_GIL_DISABLED
if (lz->cnt == PY_SSIZE_T_MAX)
return count_nextlong(lz);
return PyLong_FromSsize_t(lz->cnt++);
PyObject *res = PyLong_FromSsize_t(lz->cnt++);
if (lz->cnt == PY_SSIZE_T_MAX && lz->long_cnt == NULL) {
/* populate lz->long_cnt since it could be used by repr() */
if (count_switch_to_slow_mode(lz) < 0) {
Py_DECREF(res);
return NULL;
}
}
return res;
#else
// free-threading version
// fast mode uses compare-exchange loop
Expand All @@ -3409,7 +3431,19 @@ count_next(countobject *lz)
return returned;
}
if (_Py_atomic_compare_exchange_ssize(&lz->cnt, &cnt, cnt + 1)) {
return PyLong_FromSsize_t(cnt);
/* populate lz->long_cnt now since it could be used by repr() */
returned = PyLong_FromSsize_t(cnt);
if (lz->cnt == PY_SSIZE_T_MAX && lz->long_cnt == NULL) {
int rc;
Py_BEGIN_CRITICAL_SECTION(lz);
rc = count_switch_to_slow_mode(lz);
Py_END_CRITICAL_SECTION();
if (rc < 0) {
Py_DECREF(returned);
return NULL;
}
}
return returned;
}
}
#endif
Expand Down
Loading
0