Skip to content

Commit c77d066

Browse files
committed
Add some code to ensure that we don't lose communication sync due to
an oversize message, per suggestion from Oliver Jowett. I'm a bit dubious that this is a real problem, since the client likely doesn't have any more space available than the server, but it's not hard to make it behave according to the protocol intention.
1 parent 6e53f18 commit c77d066

File tree

1 file changed

+52
-5
lines changed

1 file changed

+52
-5
lines changed

src/backend/libpq/pqcomm.c

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
3131
* Portions Copyright (c) 1994, Regents of the University of California
3232
*
33-
* $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.172 2004/09/26 00:26:19 tgl Exp $
33+
* $PostgreSQL: pgsql/src/backend/libpq/pqcomm.c,v 1.173 2004/10/18 23:23:19 tgl Exp $
3434
*
3535
*-------------------------------------------------------------------------
3636
*/
@@ -777,6 +777,36 @@ pq_getbytes(char *s, size_t len)
777777
return 0;
778778
}
779779

780+
/* --------------------------------
781+
* pq_discardbytes - throw away a known number of bytes
782+
*
783+
* same as pq_getbytes except we do not copy the data to anyplace.
784+
* this is used for resynchronizing after read errors.
785+
*
786+
* returns 0 if OK, EOF if trouble
787+
* --------------------------------
788+
*/
789+
static int
790+
pq_discardbytes(size_t len)
791+
{
792+
size_t amount;
793+
794+
while (len > 0)
795+
{
796+
while (PqRecvPointer >= PqRecvLength)
797+
{
798+
if (pq_recvbuf()) /* If nothing in buffer, then recv some */
799+
return EOF; /* Failed to recv data */
800+
}
801+
amount = PqRecvLength - PqRecvPointer;
802+
if (amount > len)
803+
amount = len;
804+
PqRecvPointer += amount;
805+
len -= amount;
806+
}
807+
return 0;
808+
}
809+
780810
/* --------------------------------
781811
* pq_getstring - get a null terminated string from connection
782812
*
@@ -867,9 +897,8 @@ pq_getmessage(StringInfo s, int maxlen)
867897
}
868898

869899
len = ntohl(len);
870-
len -= 4; /* discount length itself */
871900

872-
if (len < 0 ||
901+
if (len < 4 ||
873902
(maxlen > 0 && len > maxlen))
874903
{
875904
ereport(COMMERROR,
@@ -878,10 +907,28 @@ pq_getmessage(StringInfo s, int maxlen)
878907
return EOF;
879908
}
880909

910+
len -= 4; /* discount length itself */
911+
881912
if (len > 0)
882913
{
883-
/* Allocate space for message */
884-
enlargeStringInfo(s, len);
914+
/*
915+
* Allocate space for message. If we run out of room (ridiculously
916+
* large message), we will elog(ERROR), but we want to discard the
917+
* message body so as not to lose communication sync.
918+
*/
919+
PG_TRY();
920+
{
921+
enlargeStringInfo(s, len);
922+
}
923+
PG_CATCH();
924+
{
925+
if (pq_discardbytes(len) == EOF)
926+
ereport(COMMERROR,
927+
(errcode(ERRCODE_PROTOCOL_VIOLATION),
928+
errmsg("incomplete message from client")));
929+
PG_RE_THROW();
930+
}
931+
PG_END_TRY();
885932

886933
/* And grab the message */
887934
if (pq_getbytes(s->data, len) == EOF)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy