summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/py_curses.h19
-rw-r--r--Misc/NEWS.d/next/Library/2023-10-24-12-39-04.gh-issue-109617.YoI8TV.rst2
-rw-r--r--Modules/_cursesmodule.c17
-rwxr-xr-xconfigure55
-rw-r--r--configure.ac5
5 files changed, 77 insertions, 21 deletions
diff --git a/Include/py_curses.h b/Include/py_curses.h
index e46b08e..a51d998 100644
--- a/Include/py_curses.h
+++ b/Include/py_curses.h
@@ -23,10 +23,16 @@
# endif
#endif
-#if !defined(HAVE_CURSES_IS_PAD) && defined(WINDOW_HAS_FLAGS)
-/* 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
@@ -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. */
-#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
diff --git a/Misc/NEWS.d/next/Library/2023-10-24-12-39-04.gh-issue-109617.YoI8TV.rst b/Misc/NEWS.d/next/Library/2023-10-24-12-39-04.gh-issue-109617.YoI8TV.rst
new file mode 100644
index 0000000..4fda69d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-10-24-12-39-04.gh-issue-109617.YoI8TV.rst
@@ -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.
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index 8bf6824..69b9704 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -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
@@ -4586,7 +4588,14 @@ 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) {
+ // 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()) { \
@@ -4594,9 +4603,9 @@ make_ncurses_version(PyTypeObject *type)
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;
diff --git a/configure b/configure
index cc85aed..0cd1371 100755
--- a/configure
+++ b/configure
@@ -26781,7 +26781,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
@@ -26824,7 +26827,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
@@ -26867,7 +26873,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
@@ -26910,7 +26919,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
@@ -26953,7 +26965,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
@@ -26996,7 +27011,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
@@ -27039,7 +27057,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
@@ -27082,7 +27103,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
@@ -27125,7 +27149,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
@@ -27168,7 +27195,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
@@ -27211,7 +27241,10 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+ #define NCURSES_OPAQUE 0
+ #include <curses.h>
+
int
main (void)
{
diff --git a/configure.ac b/configure.ac
index c55e33a..ae59451 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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