Re: BUG #17421: Core dump in ECPGdo() when calling PostgreSQL API from 32-bit client for RHEL8 - Mailing list pgsql-bugs

From Tom Lane
Subject Re: BUG #17421: Core dump in ECPGdo() when calling PostgreSQL API from 32-bit client for RHEL8
Date
Msg-id 908758.1654527712@sss.pgh.pa.us
Whole thread Raw
In response to RE: BUG #17421: Core dump in ECPGdo() when calling PostgreSQL API from 32-bit client for RHEL8  ("hirose.masay-01@fujitsu.com" <hirose.masay-01@fujitsu.com>)
Responses RE: BUG #17421: Core dump in ECPGdo() when calling PostgreSQL API from 32-bit client for RHEL8
List pgsql-bugs
"hirose.masay-01@fujitsu.com" <hirose.masay-01@fujitsu.com> writes:
> [Problem]
> The potential problem is no value is set to "message" after PQresultErrorField() is called in ecpg_raise_backend().

Ah-hah.  You're right, and this explains the symptoms exactly, because
libpq-generated error results don't contain broken-down fields, so we'd
get a null precisely in cases such as lost connection.

> |        if (message == NULL)
> |            message = ecpg_gettext("empty message text");

No, that'd be pretty unhelpful.  The best response is to substitute
PQerrorMessage(conn) in such cases.  We do that in, for example,
postgres_fdw.

(I don't feel a need to change ECPGnoticeReceiver, because that only
deals with NOTICE results which should always have such a field, and
PQerrorMessage wouldn't be relevant to a non-ERROR result anyway.)

Will fix, thanks for the report!

            regards, tom lane

diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c
index cd6c6a6819..26fdcdb69e 100644
--- a/src/interfaces/ecpg/ecpglib/error.c
+++ b/src/interfaces/ecpg/ecpglib/error.c
@@ -229,18 +229,17 @@ ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat)
         return;
     }

-    if (result)
-    {
-        sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
-        if (sqlstate == NULL)
-            sqlstate = ECPG_SQLSTATE_ECPG_INTERNAL_ERROR;
-        message = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
-    }
-    else
-    {
+    /*
+     * PQresultErrorField will return NULL if "result" is NULL, or if there is
+     * no such field, which will happen for libpq-generated errors.  Fall back
+     * to PQerrorMessage in such cases.
+     */
+    sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
+    if (sqlstate == NULL)
         sqlstate = ECPG_SQLSTATE_ECPG_INTERNAL_ERROR;
+    message = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
+    if (message == NULL)
         message = PQerrorMessage(conn);
-    }

     if (strcmp(sqlstate, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR) == 0)
     {

pgsql-bugs by date:

Previous
From: Robert Haas
Date:
Subject: Re: BUG #17504: psql --single-transaction -vON_ERROR_STOP=1 still commits after client-side error
Next
From: Tom Lane
Date:
Subject: Re: BUG #17510: cache lookup failed for type