public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/PyGreSQL] rawhide: [bugfix] Fix array/record parser crash on s390x with Python 3.14
@ 2026-07-01 14:38 Michal Schorm
  0 siblings, 0 replies; only message in thread
From: Michal Schorm @ 2026-07-01 14:38 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/PyGreSQL
            Branch : rawhide
            Commit : 2f376ecb2e846497796c927e631c9169b8f08933
            Author : Michal Schorm <mschorm@redhat.com>
            Date   : 2026-07-01T12:30:17+02:00
            Stats  : +48/-0 in 2 file(s)
            URL    : https://src.fedoraproject.org/rpms/PyGreSQL/c/2f376ecb2e846497796c927e631c9169b8f08933?branch=rawhide

            Log:
            [bugfix] Fix array/record parser crash on s390x with Python 3.14

Add fix-cast-array-s390x.patch to fix two bugs in ext/pginternal.c
that cause 2 of 820 tests to fail on s390x (big-endian) only:
  - test_parser_with_data
  - test_parser_with_different_delimiter

Bug 1 -- buffer overread in cast_array() quoted element parser:
The do...while at line 597 unconditionally increments the pointer
past end-of-buffer before checking the termination condition. On
s390x the garbage bytes include 0xe8 (invalid UTF-8 lead byte),
which causes UnicodeDecodeError when the overread data is decoded.
Fix: guard the do...while with an if (s \!= end) check.

Bug 2 -- missing exception check after get_decoded_string() failure
in cast_array() and cast_record():
When get_decoded_string() returns NULL with a pending exception
(UnicodeDecodeError), the code falls through to PyBytes_FromStringAndSize
without clearing it. The subsequent PyObject_CallFunctionObjArgs(str, ...)
succeeds but Python 3.14's stricter _Py_CheckFunctionResult() detects
the stale exception and raises:
  SystemError: <class 'str'> returned a result with an exception set
Fix: check PyErr_Occurred() after NULL return and propagate the error.

Koji scratch build log showing the failure:
  https://koji.fedoraproject.org/koji/getfile?taskID=143907932&volume=DEFAULT&name=build.log

Co-Authored-By: Claude AI <noreply@anthropic.com>

---
diff --git a/PyGreSQL.spec b/PyGreSQL.spec
index 970ae5e..756a5ae 100644
--- a/PyGreSQL.spec
+++ b/PyGreSQL.spec
@@ -13,6 +13,9 @@ License:	PostgreSQL
 
 Source0:	https://github.com/PyGreSQL/%{name}/archive/%{uversion}/%{name}-%{uversion}.tar.gz#/%{name}-%{uversion}.tar.gz
 
+# Fix buffer overread and missing exception check in array/record parser
+# causing test failures on s390x with Python 3.14
+Patch0:		fix-cast-array-s390x.patch
 
 BuildRequires:	gcc
 BuildRequires:	libpq-devel

diff --git a/fix-cast-array-s390x.patch b/fix-cast-array-s390x.patch
new file mode 100644
index 0000000..8e63148
--- /dev/null
+++ b/fix-cast-array-s390x.patch
@@ -0,0 +1,45 @@
+--- a/ext/pginternal.c
++++ b/ext/pginternal.c
+@@ -594,8 +594,10 @@
+                     ++s;
+                 }
+                 esize = s - estr;
+-                do ++s;
+-                while (s != end && *s == ' ');
++                if (s != end) {
++                    do ++s;
++                    while (s != end && *s == ' ');
++                }
+             }
+             else { /* unquoted element */
+                 estr = s;
+@@ -650,7 +652,13 @@
+                     element = encoding == pg_encoding_ascii
+                                   ? NULL
+                                   : get_decoded_string(estr, esize, encoding);
+-                    if (!element) { /* no decoding necessary or possible */
++                    if (!element && PyErr_Occurred()) {
++                        /* decoding failed -- propagate the error */
++                        if (escaped) PyMem_Free(estr);
++                        Py_DECREF(result);
++                        return NULL;
++                    }
++                    if (!element) { /* no decoding necessary */
+                         element = PyBytes_FromStringAndSize(estr, esize);
+                     }
+                     if (element && cast) {
+@@ -831,7 +839,13 @@
+                 element = encoding == pg_encoding_ascii
+                               ? NULL
+                               : get_decoded_string(estr, esize, encoding);
+-                if (!element) { /* no decoding necessary or possible */
++                if (!element && PyErr_Occurred()) {
++                    /* decoding failed -- propagate the error */
++                    if (escaped) PyMem_Free(estr);
++                    Py_DECREF(result);
++                    return NULL;
++                }
++                if (!element) { /* no decoding necessary */
+                     element = PyBytes_FromStringAndSize(estr, esize);
+                 }
+                 if (element && cast) {

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-07-01 14:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-01 14:38 [rpms/PyGreSQL] rawhide: [bugfix] Fix array/record parser crash on s390x with Python 3.14 Michal Schorm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox