Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 14 additions & 5 deletions Include/py_curses.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@
# endif
#endif

#if !defined(HAVE_CURSES_IS_PAD) && defined(WINDOW_HAS_FLAGS)
Comment thread
ambv marked this conversation as resolved.
Resolved
/* The following definition is necessary for ncurses 5.7; without it,
some of [n]curses.h set NCURSES_OPAQUE to 1, and then Python
can't get at the WINDOW flags field. */
#if defined(WINDOW_HAS_FLAGS) && defined(__APPLE__)
/* gh-109617, gh-115383: we can rely on the default value for NCURSES_OPAQUE on
most platforms, but not on macOS. This is because, starting with Xcode 15,
Apple-provided ncurses.h comes from ncurses 6 (which defaults to opaque
structs) but can still be linked to older versions of ncurses dynamic
libraries which don't provide functions such as is_pad() to deal with opaque
structs. Setting NCURSES_OPAQUE to 0 is harmless in all ncurses releases to
this date (provided that a thread-safe implementation is not required), but
this might change in the future. This fix might become irrelevant once
support for macOS 13 or earlier is dropped. */
#define NCURSES_OPAQUE 0
#endif

Expand All @@ -39,7 +45,10 @@
#ifdef HAVE_NCURSES_H
/* configure was checking <curses.h>, but we will
use <ncurses.h>, which has some or all these features. */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain the version check in the comment?

#if !defined(WINDOW_HAS_FLAGS) && !(NCURSES_OPAQUE+0)
#if !defined(WINDOW_HAS_FLAGS) && \
(NCURSES_VERSION_PATCH+0 < 20070303 || !(NCURSES_OPAQUE+0))
/* the WINDOW flags field was always accessible in ncurses prior to 20070303;
after that, it depends on the value of NCURSES_OPAQUE. */
#define WINDOW_HAS_FLAGS 1
#endif
#if !defined(HAVE_CURSES_IS_PAD) && NCURSES_VERSION_PATCH+0 >= 20090906
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:mod:`ncurses`: fixed a crash that could occur on macOS 13 or earlier when
Python was built with Apple Xcode 15's SDK.
17 changes: 13 additions & 4 deletions Modules/_cursesmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1156,8 +1156,10 @@ int py_mvwdelch(WINDOW *w, int y, int x)
#endif

#if defined(HAVE_CURSES_IS_PAD)
// is_pad() is defined, either as a macro or as a function
#define py_is_pad(win) is_pad(win)
#elif defined(WINDOW_HAS_FLAGS)
// is_pad() is not defined, but we can inspect WINDOW structure members
#define py_is_pad(win) ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE)
#endif

Expand Down Expand Up @@ -4586,17 +4588,24 @@ make_ncurses_version(PyTypeObject *type)
if (ncurses_version == NULL) {
return NULL;
}

const char *str = curses_version();
unsigned long major = 0, minor = 0, patch = 0;
if (!str || sscanf(str, "%*[^0-9]%lu.%lu.%lu", &major, &minor, &patch) < 3) {
Comment thread
ambv marked this conversation as resolved.
Resolved
// Fallback to header version, which cannot be that wrong
major = NCURSES_VERSION_MAJOR;
minor = NCURSES_VERSION_MINOR;
patch = NCURSES_VERSION_PATCH;
}
#define SetIntItem(flag) \
PyStructSequence_SET_ITEM(ncurses_version, pos++, PyLong_FromLong(flag)); \
if (PyErr_Occurred()) { \
Py_CLEAR(ncurses_version); \
return NULL; \
}

SetIntItem(NCURSES_VERSION_MAJOR)
SetIntItem(NCURSES_VERSION_MINOR)
SetIntItem(NCURSES_VERSION_PATCH)
SetIntItem(major)
SetIntItem(minor)
SetIntItem(patch)
#undef SetIntItem

return ncurses_version;
Expand Down
55 changes: 44 additions & 11 deletions configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -6713,7 +6713,10 @@ AC_DEFUN([PY_CHECK_CURSES_FUNC],
[py_var],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[@%:@include <curses.h>], [
[
#define NCURSES_OPAQUE 0
#include <curses.h>
], [
#ifndef $1
void *x=$1
#endif
Expand Down