@@ -290,8 +290,6 @@ pqParseInput3(PGconn *conn)
290290 /* First 'T' in a query sequence */
291291 if (getRowDescriptions (conn , msgLength ))
292292 return ;
293- /* getRowDescriptions() moves inStart itself */
294- continue ;
295293 }
296294 else
297295 {
@@ -337,17 +335,14 @@ pqParseInput3(PGconn *conn)
337335 case 't' : /* Parameter Description */
338336 if (getParamDescriptions (conn , msgLength ))
339337 return ;
340- /* getParamDescriptions() moves inStart itself */
341- continue ;
338+ break ;
342339 case 'D' : /* Data Row */
343340 if (conn -> result != NULL &&
344341 conn -> result -> resultStatus == PGRES_TUPLES_OK )
345342 {
346343 /* Read another tuple of a normal query response */
347344 if (getAnotherTuple (conn , msgLength ))
348345 return ;
349- /* getAnotherTuple() moves inStart itself */
350- continue ;
351346 }
352347 else if (conn -> result != NULL &&
353348 conn -> result -> resultStatus == PGRES_FATAL_ERROR )
@@ -462,7 +457,6 @@ handleSyncLoss(PGconn *conn, char id, int msgLength)
462457 * command for a prepared statement) containing the attribute data.
463458 * Returns: 0 if processed message successfully, EOF to suspend parsing
464459 * (the latter case is not actually used currently).
465- * In the former case, conn->inStart has been advanced past the message.
466460 */
467461static int
468462getRowDescriptions (PGconn * conn , int msgLength )
@@ -567,19 +561,9 @@ getRowDescriptions(PGconn *conn, int msgLength)
567561 result -> binary = 0 ;
568562 }
569563
570- /* Sanity check that we absorbed all the data */
571- if (conn -> inCursor != conn -> inStart + 5 + msgLength )
572- {
573- errmsg = libpq_gettext ("extraneous data in \"T\" message" );
574- goto advance_and_error ;
575- }
576-
577564 /* Success! */
578565 conn -> result = result ;
579566
580- /* Advance inStart to show that the "T" message has been processed. */
581- conn -> inStart = conn -> inCursor ;
582-
583567 /*
584568 * If we're doing a Describe, we're done, and ready to pass the result
585569 * back to the client.
@@ -603,9 +587,6 @@ getRowDescriptions(PGconn *conn, int msgLength)
603587 if (result && result != conn -> result )
604588 PQclear (result );
605589
606- /* Discard the failed message by pretending we read it */
607- conn -> inStart += 5 + msgLength ;
608-
609590 /*
610591 * Replace partially constructed result with an error result. First
611592 * discard the old result to try to win back some memory.
@@ -624,6 +605,12 @@ getRowDescriptions(PGconn *conn, int msgLength)
624605 appendPQExpBuffer (& conn -> errorMessage , "%s\n" , errmsg );
625606 pqSaveErrorResult (conn );
626607
608+ /*
609+ * Show the message as fully consumed, else pqParseInput3 will overwrite
610+ * our error with a complaint about that.
611+ */
612+ conn -> inCursor = conn -> inStart + 5 + msgLength ;
613+
627614 /*
628615 * Return zero to allow input parsing to continue. Subsequent "D"
629616 * messages will be ignored until we get to end of data, since an error
@@ -635,12 +622,8 @@ getRowDescriptions(PGconn *conn, int msgLength)
635622/*
636623 * parseInput subroutine to read a 't' (ParameterDescription) message.
637624 * We'll build a new PGresult structure containing the parameter data.
638- * Returns: 0 if completed message, EOF if not enough data yet.
639- * In the former case, conn->inStart has been advanced past the message.
640- *
641- * Note that if we run out of data, we have to release the partially
642- * constructed PGresult, and rebuild it again next time. Fortunately,
643- * that shouldn't happen often, since 't' messages usually fit in a packet.
625+ * Returns: 0 if processed message successfully, EOF to suspend parsing
626+ * (the latter case is not actually used currently).
644627 */
645628static int
646629getParamDescriptions (PGconn * conn , int msgLength )
@@ -680,33 +663,19 @@ getParamDescriptions(PGconn *conn, int msgLength)
680663 result -> paramDescs [i ].typid = typid ;
681664 }
682665
683- /* Sanity check that we absorbed all the data */
684- if (conn -> inCursor != conn -> inStart + 5 + msgLength )
685- {
686- errmsg = libpq_gettext ("extraneous data in \"t\" message" );
687- goto advance_and_error ;
688- }
689-
690666 /* Success! */
691667 conn -> result = result ;
692668
693- /* Advance inStart to show that the "t" message has been processed. */
694- conn -> inStart = conn -> inCursor ;
695-
696669 return 0 ;
697670
698671not_enough_data :
699- PQclear (result );
700- return EOF ;
672+ errmsg = libpq_gettext ("insufficient data in \"t\" message" );
701673
702674advance_and_error :
703675 /* Discard unsaved result, if any */
704676 if (result && result != conn -> result )
705677 PQclear (result );
706678
707- /* Discard the failed message by pretending we read it */
708- conn -> inStart += 5 + msgLength ;
709-
710679 /*
711680 * Replace partially constructed result with an error result. First
712681 * discard the old result to try to win back some memory.
@@ -724,6 +693,12 @@ getParamDescriptions(PGconn *conn, int msgLength)
724693 appendPQExpBuffer (& conn -> errorMessage , "%s\n" , errmsg );
725694 pqSaveErrorResult (conn );
726695
696+ /*
697+ * Show the message as fully consumed, else pqParseInput3 will overwrite
698+ * our error with a complaint about that.
699+ */
700+ conn -> inCursor = conn -> inStart + 5 + msgLength ;
701+
727702 /*
728703 * Return zero to allow input parsing to continue. Essentially, we've
729704 * replaced the COMMAND_OK result with an error result, but since this
@@ -737,7 +712,6 @@ getParamDescriptions(PGconn *conn, int msgLength)
737712 * We fill rowbuf with column pointers and then call the row processor.
738713 * Returns: 0 if processed message successfully, EOF to suspend parsing
739714 * (the latter case is not actually used currently).
740- * In the former case, conn->inStart has been advanced past the message.
741715 */
742716static int
743717getAnotherTuple (PGconn * conn , int msgLength )
@@ -810,28 +784,14 @@ getAnotherTuple(PGconn *conn, int msgLength)
810784 }
811785 }
812786
813- /* Sanity check that we absorbed all the data */
814- if (conn -> inCursor != conn -> inStart + 5 + msgLength )
815- {
816- errmsg = libpq_gettext ("extraneous data in \"D\" message" );
817- goto advance_and_error ;
818- }
819-
820- /* Advance inStart to show that the "D" message has been processed. */
821- conn -> inStart = conn -> inCursor ;
822-
823787 /* Process the collected row */
824788 errmsg = NULL ;
825789 if (pqRowProcessor (conn , & errmsg ))
826790 return 0 ; /* normal, successful exit */
827791
828- goto set_error_result ; /* pqRowProcessor failed, report it */
792+ /* pqRowProcessor failed, fall through to report it */
829793
830794advance_and_error :
831- /* Discard the failed message by pretending we read it */
832- conn -> inStart += 5 + msgLength ;
833-
834- set_error_result :
835795
836796 /*
837797 * Replace partially constructed result with an error result. First
@@ -851,6 +811,12 @@ getAnotherTuple(PGconn *conn, int msgLength)
851811 appendPQExpBuffer (& conn -> errorMessage , "%s\n" , errmsg );
852812 pqSaveErrorResult (conn );
853813
814+ /*
815+ * Show the message as fully consumed, else pqParseInput3 will overwrite
816+ * our error with a complaint about that.
817+ */
818+ conn -> inCursor = conn -> inStart + 5 + msgLength ;
819+
854820 /*
855821 * Return zero to allow input parsing to continue. Subsequent "D"
856822 * messages will be ignored until we get to end of data, since an error
0 commit comments