]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
libpq: Make error checks in the new buffer draining code more robust
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 9 Jul 2026 15:34:27 +0000 (18:34 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 9 Jul 2026 15:36:41 +0000 (18:36 +0300)
Check explicitly for pqsecure_read() returning an error. It shouldn't
fail, and we would've caught it in the check for a short read, but
better to be explicit so that the error message is more informative.
We also shouldn't update 'inEnd' when the read fails, although that
too is just pro forma as we will bail out and close the connection on
error.

Reported-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://www.postgresql.org/message-id/34844e8c-267c-4daf-b1e0-f26059a4a7d3@eisentraut.org
Backpatch-through: 14

src/interfaces/libpq/fe-misc.c
src/interfaces/libpq/fe-secure.c

index 3633b125baf4792aba1d33b40785758874e57725..01f55732b0a5a957b187bfedcd8aab78f43a957d 100644 (file)
@@ -918,13 +918,18 @@ pqDrainPending(PGconn *conn)
 
        nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd,
                                                  bytes_pending);
-       conn->inEnd += nread;
 
-       /* When there are bytes pending, the read function is not supposed to fail */
+       /*
+        * When there are bytes pending, pqsecure_read() is not supposed to fail
+        * or do a short read, but let's check anyway to be safe.
+        */
+       if (nread < 0)
+               return -1;
+       conn->inEnd += nread;
        if (nread != bytes_pending)
        {
                appendPQExpBuffer(&conn->errorMessage,
-                                                 libpq_gettext("drained only %zu of %zd pending bytes in transport buffer\n"),
+                                                 libpq_gettext("drained only %zd of %zd pending bytes in transport buffer\n"),
                                                  nread, bytes_pending);
                return -1;
        }
index feb50f7e22b911209af5bcce4a6938baaf8cb072..b9ce02a665d92ceda1c6ce61f9c876685363de26 100644 (file)
@@ -288,8 +288,9 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
  *     Return the number of bytes available in the transport buffer.
  *
  * If pqsecure_read() is called for this number of bytes, it's guaranteed to
- * return successfully without reading from the underlying socket.  See
- * pqDrainPending() for a more complete discussion of the concepts involved.
+ * return successfully with the same number of bytes, without reading from the
+ * underlying socket.  See pqDrainPending() for a more complete discussion of
+ * the concepts involved.
  */
 ssize_t
 pqsecure_bytes_pending(PGconn *conn)