1 /*-------------------------------------------------------------------------
2  *
3  * fe-protocol3.c
4  *	  functions that are specific to frontend/backend protocol version 3
5  *
6  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *	  src/interfaces/libpq/fe-protocol3.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres_fe.h"
16 
17 #include <ctype.h>
18 #include <fcntl.h>
19 
20 #include "libpq-fe.h"
21 #include "libpq-int.h"
22 
23 #include "mb/pg_wchar.h"
24 
25 #ifdef WIN32
26 #include "win32.h"
27 #else
28 #include <unistd.h>
29 #include <netinet/in.h>
30 #ifdef HAVE_NETINET_TCP_H
31 #include <netinet/tcp.h>
32 #endif
33 #include <arpa/inet.h>
34 #endif
35 
36 
37 /*
38  * This macro lists the backend message types that could be "long" (more
39  * than a couple of kilobytes).
40  */
41 #define VALID_LONG_MESSAGE_TYPE(id) \
42 	((id) == 'T' || (id) == 'D' || (id) == 'd' || (id) == 'V' || \
43 	 (id) == 'E' || (id) == 'N' || (id) == 'A')
44 
45 #define PQmblenBounded(s, e)  strnlen(s, PQmblen(s, e))
46 
47 
48 static void handleSyncLoss(PGconn *conn, char id, int msgLength);
49 static int	getRowDescriptions(PGconn *conn, int msgLength);
50 static int	getParamDescriptions(PGconn *conn, int msgLength);
51 static int	getAnotherTuple(PGconn *conn, int msgLength);
52 static int	getParameterStatus(PGconn *conn);
53 static int	getNotify(PGconn *conn);
54 static int	getCopyStart(PGconn *conn, ExecStatusType copytype);
55 static int	getReadyForQuery(PGconn *conn);
56 static void reportErrorPosition(PQExpBuffer msg, const char *query,
57 					int loc, int encoding);
58 static int build_startup_packet(const PGconn *conn, char *packet,
59 					 const PQEnvironmentOption *options);
60 
61 
62 /*
63  * parseInput: if appropriate, parse input data from backend
64  * until input is exhausted or a stopping state is reached.
65  * Note that this function will NOT attempt to read more data from the backend.
66  */
67 void
pqParseInput3(PGconn * conn)68 pqParseInput3(PGconn *conn)
69 {
70 	char		id;
71 	int			msgLength;
72 	int			avail;
73 
74 	/*
75 	 * Loop to parse successive complete messages available in the buffer.
76 	 */
77 	for (;;)
78 	{
79 		/*
80 		 * Try to read a message.  First get the type code and length. Return
81 		 * if not enough data.
82 		 */
83 		conn->inCursor = conn->inStart;
84 		if (pqGetc(&id, conn))
85 			return;
86 		if (pqGetInt(&msgLength, 4, conn))
87 			return;
88 
89 		/*
90 		 * Try to validate message type/length here.  A length less than 4 is
91 		 * definitely broken.  Large lengths should only be believed for a few
92 		 * message types.
93 		 */
94 		if (msgLength < 4)
95 		{
96 			handleSyncLoss(conn, id, msgLength);
97 			return;
98 		}
99 		if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
100 		{
101 			handleSyncLoss(conn, id, msgLength);
102 			return;
103 		}
104 
105 		/*
106 		 * Can't process if message body isn't all here yet.
107 		 */
108 		msgLength -= 4;
109 		avail = conn->inEnd - conn->inCursor;
110 		if (avail < msgLength)
111 		{
112 			/*
113 			 * Before returning, enlarge the input buffer if needed to hold
114 			 * the whole message.  This is better than leaving it to
115 			 * pqReadData because we can avoid multiple cycles of realloc()
116 			 * when the message is large; also, we can implement a reasonable
117 			 * recovery strategy if we are unable to make the buffer big
118 			 * enough.
119 			 */
120 			if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
121 									 conn))
122 			{
123 				/*
124 				 * XXX add some better recovery code... plan is to skip over
125 				 * the message using its length, then report an error. For the
126 				 * moment, just treat this like loss of sync (which indeed it
127 				 * might be!)
128 				 */
129 				handleSyncLoss(conn, id, msgLength);
130 			}
131 			return;
132 		}
133 
134 		/*
135 		 * NOTIFY and NOTICE messages can happen in any state; always process
136 		 * them right away.
137 		 *
138 		 * Most other messages should only be processed while in BUSY state.
139 		 * (In particular, in READY state we hold off further parsing until
140 		 * the application collects the current PGresult.)
141 		 *
142 		 * However, if the state is IDLE then we got trouble; we need to deal
143 		 * with the unexpected message somehow.
144 		 *
145 		 * ParameterStatus ('S') messages are a special case: in IDLE state we
146 		 * must process 'em (this case could happen if a new value was adopted
147 		 * from config file due to SIGHUP), but otherwise we hold off until
148 		 * BUSY state.
149 		 */
150 		if (id == 'A')
151 		{
152 			if (getNotify(conn))
153 				return;
154 		}
155 		else if (id == 'N')
156 		{
157 			if (pqGetErrorNotice3(conn, false))
158 				return;
159 		}
160 		else if (conn->asyncStatus != PGASYNC_BUSY)
161 		{
162 			/* If not IDLE state, just wait ... */
163 			if (conn->asyncStatus != PGASYNC_IDLE)
164 				return;
165 
166 			/*
167 			 * Unexpected message in IDLE state; need to recover somehow.
168 			 * ERROR messages are handled using the notice processor;
169 			 * ParameterStatus is handled normally; anything else is just
170 			 * dropped on the floor after displaying a suitable warning
171 			 * notice.  (An ERROR is very possibly the backend telling us why
172 			 * it is about to close the connection, so we don't want to just
173 			 * discard it...)
174 			 */
175 			if (id == 'E')
176 			{
177 				if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
178 					return;
179 			}
180 			else if (id == 'S')
181 			{
182 				if (getParameterStatus(conn))
183 					return;
184 			}
185 			else
186 			{
187 				pqInternalNotice(&conn->noticeHooks,
188 						"message type 0x%02x arrived from server while idle",
189 								 id);
190 				/* Discard the unexpected message */
191 				conn->inCursor += msgLength;
192 			}
193 		}
194 		else
195 		{
196 			/*
197 			 * In BUSY state, we can process everything.
198 			 */
199 			switch (id)
200 			{
201 				case 'C':		/* command complete */
202 					if (pqGets(&conn->workBuffer, conn))
203 						return;
204 					if (conn->result == NULL)
205 					{
206 						conn->result = PQmakeEmptyPGresult(conn,
207 														   PGRES_COMMAND_OK);
208 						if (!conn->result)
209 						{
210 							printfPQExpBuffer(&conn->errorMessage,
211 											  libpq_gettext("out of memory"));
212 							pqSaveErrorResult(conn);
213 						}
214 					}
215 					if (conn->result)
216 						strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
217 								CMDSTATUS_LEN);
218 					conn->asyncStatus = PGASYNC_READY;
219 					break;
220 				case 'E':		/* error return */
221 					if (pqGetErrorNotice3(conn, true))
222 						return;
223 					conn->asyncStatus = PGASYNC_READY;
224 					break;
225 				case 'Z':		/* backend is ready for new query */
226 					if (getReadyForQuery(conn))
227 						return;
228 					conn->asyncStatus = PGASYNC_IDLE;
229 					break;
230 				case 'I':		/* empty query */
231 					if (conn->result == NULL)
232 					{
233 						conn->result = PQmakeEmptyPGresult(conn,
234 														   PGRES_EMPTY_QUERY);
235 						if (!conn->result)
236 						{
237 							printfPQExpBuffer(&conn->errorMessage,
238 											  libpq_gettext("out of memory"));
239 							pqSaveErrorResult(conn);
240 						}
241 					}
242 					conn->asyncStatus = PGASYNC_READY;
243 					break;
244 				case '1':		/* Parse Complete */
245 					/* If we're doing PQprepare, we're done; else ignore */
246 					if (conn->queryclass == PGQUERY_PREPARE)
247 					{
248 						if (conn->result == NULL)
249 						{
250 							conn->result = PQmakeEmptyPGresult(conn,
251 														   PGRES_COMMAND_OK);
252 							if (!conn->result)
253 							{
254 								printfPQExpBuffer(&conn->errorMessage,
255 											 libpq_gettext("out of memory"));
256 								pqSaveErrorResult(conn);
257 							}
258 						}
259 						conn->asyncStatus = PGASYNC_READY;
260 					}
261 					break;
262 				case '2':		/* Bind Complete */
263 				case '3':		/* Close Complete */
264 					/* Nothing to do for these message types */
265 					break;
266 				case 'S':		/* parameter status */
267 					if (getParameterStatus(conn))
268 						return;
269 					break;
270 				case 'K':		/* secret key data from the backend */
271 
272 					/*
273 					 * This is expected only during backend startup, but it's
274 					 * just as easy to handle it as part of the main loop.
275 					 * Save the data and continue processing.
276 					 */
277 					if (pqGetInt(&(conn->be_pid), 4, conn))
278 						return;
279 					if (pqGetInt(&(conn->be_key), 4, conn))
280 						return;
281 					break;
282 				case 'T':		/* Row Description */
283 					if (conn->result != NULL &&
284 						conn->result->resultStatus == PGRES_FATAL_ERROR)
285 					{
286 						/*
287 						 * We've already choked for some reason.  Just discard
288 						 * the data till we get to the end of the query.
289 						 */
290 						conn->inCursor += msgLength;
291 					}
292 					else if (conn->result == NULL ||
293 							 conn->queryclass == PGQUERY_DESCRIBE)
294 					{
295 						/* First 'T' in a query sequence */
296 						if (getRowDescriptions(conn, msgLength))
297 							return;
298 					}
299 					else
300 					{
301 						/*
302 						 * A new 'T' message is treated as the start of
303 						 * another PGresult.  (It is not clear that this is
304 						 * really possible with the current backend.) We stop
305 						 * parsing until the application accepts the current
306 						 * result.
307 						 */
308 						conn->asyncStatus = PGASYNC_READY;
309 						return;
310 					}
311 					break;
312 				case 'n':		/* No Data */
313 
314 					/*
315 					 * NoData indicates that we will not be seeing a
316 					 * RowDescription message because the statement or portal
317 					 * inquired about doesn't return rows.
318 					 *
319 					 * If we're doing a Describe, we have to pass something
320 					 * back to the client, so set up a COMMAND_OK result,
321 					 * instead of TUPLES_OK.  Otherwise we can just ignore
322 					 * this message.
323 					 */
324 					if (conn->queryclass == PGQUERY_DESCRIBE)
325 					{
326 						if (conn->result == NULL)
327 						{
328 							conn->result = PQmakeEmptyPGresult(conn,
329 														   PGRES_COMMAND_OK);
330 							if (!conn->result)
331 							{
332 								printfPQExpBuffer(&conn->errorMessage,
333 											 libpq_gettext("out of memory"));
334 								pqSaveErrorResult(conn);
335 							}
336 						}
337 						conn->asyncStatus = PGASYNC_READY;
338 					}
339 					break;
340 				case 't':		/* Parameter Description */
341 					if (getParamDescriptions(conn, msgLength))
342 						return;
343 					break;
344 				case 'D':		/* Data Row */
345 					if (conn->result != NULL &&
346 						conn->result->resultStatus == PGRES_TUPLES_OK)
347 					{
348 						/* Read another tuple of a normal query response */
349 						if (getAnotherTuple(conn, msgLength))
350 							return;
351 					}
352 					else if (conn->result != NULL &&
353 							 conn->result->resultStatus == PGRES_FATAL_ERROR)
354 					{
355 						/*
356 						 * We've already choked for some reason.  Just discard
357 						 * tuples till we get to the end of the query.
358 						 */
359 						conn->inCursor += msgLength;
360 					}
361 					else
362 					{
363 						/* Set up to report error at end of query */
364 						printfPQExpBuffer(&conn->errorMessage,
365 										  libpq_gettext("server sent data (\"D\" message) without prior row description (\"T\" message)\n"));
366 						pqSaveErrorResult(conn);
367 						/* Discard the unexpected message */
368 						conn->inCursor += msgLength;
369 					}
370 					break;
371 				case 'G':		/* Start Copy In */
372 					if (getCopyStart(conn, PGRES_COPY_IN))
373 						return;
374 					conn->asyncStatus = PGASYNC_COPY_IN;
375 					break;
376 				case 'H':		/* Start Copy Out */
377 					if (getCopyStart(conn, PGRES_COPY_OUT))
378 						return;
379 					conn->asyncStatus = PGASYNC_COPY_OUT;
380 					conn->copy_already_done = 0;
381 					break;
382 				case 'W':		/* Start Copy Both */
383 					if (getCopyStart(conn, PGRES_COPY_BOTH))
384 						return;
385 					conn->asyncStatus = PGASYNC_COPY_BOTH;
386 					conn->copy_already_done = 0;
387 					break;
388 				case 'd':		/* Copy Data */
389 
390 					/*
391 					 * If we see Copy Data, just silently drop it.  This would
392 					 * only occur if application exits COPY OUT mode too
393 					 * early.
394 					 */
395 					conn->inCursor += msgLength;
396 					break;
397 				case 'c':		/* Copy Done */
398 
399 					/*
400 					 * If we see Copy Done, just silently drop it.  This is
401 					 * the normal case during PQendcopy.  We will keep
402 					 * swallowing data, expecting to see command-complete for
403 					 * the COPY command.
404 					 */
405 					break;
406 				default:
407 					printfPQExpBuffer(&conn->errorMessage,
408 									  libpq_gettext(
409 													"unexpected response from server; first received character was \"%c\"\n"),
410 									  id);
411 					/* build an error result holding the error message */
412 					pqSaveErrorResult(conn);
413 					/* not sure if we will see more, so go to ready state */
414 					conn->asyncStatus = PGASYNC_READY;
415 					/* Discard the unexpected message */
416 					conn->inCursor += msgLength;
417 					break;
418 			}					/* switch on protocol character */
419 		}
420 		/* Successfully consumed this message */
421 		if (conn->inCursor == conn->inStart + 5 + msgLength)
422 		{
423 			/* Normal case: parsing agrees with specified length */
424 			conn->inStart = conn->inCursor;
425 		}
426 		else
427 		{
428 			/* Trouble --- report it */
429 			printfPQExpBuffer(&conn->errorMessage,
430 							  libpq_gettext("message contents do not agree with length in message type \"%c\"\n"),
431 							  id);
432 			/* build an error result holding the error message */
433 			pqSaveErrorResult(conn);
434 			conn->asyncStatus = PGASYNC_READY;
435 			/* trust the specified message length as what to skip */
436 			conn->inStart += 5 + msgLength;
437 		}
438 	}
439 }
440 
441 /*
442  * handleSyncLoss: clean up after loss of message-boundary sync
443  *
444  * There isn't really a lot we can do here except abandon the connection.
445  */
446 static void
handleSyncLoss(PGconn * conn,char id,int msgLength)447 handleSyncLoss(PGconn *conn, char id, int msgLength)
448 {
449 	printfPQExpBuffer(&conn->errorMessage,
450 					  libpq_gettext(
451 	"lost synchronization with server: got message type \"%c\", length %d\n"),
452 					  id, msgLength);
453 	/* build an error result holding the error message */
454 	pqSaveErrorResult(conn);
455 	conn->asyncStatus = PGASYNC_READY;	/* drop out of GetResult wait loop */
456 	/* flush input data since we're giving up on processing it */
457 	pqDropConnection(conn, true);
458 	conn->status = CONNECTION_BAD;		/* No more connection to backend */
459 }
460 
461 /*
462  * parseInput subroutine to read a 'T' (row descriptions) message.
463  * We'll build a new PGresult structure (unless called for a Describe
464  * command for a prepared statement) containing the attribute data.
465  * Returns: 0 if processed message successfully, EOF to suspend parsing
466  * (the latter case is not actually used currently).
467  */
468 static int
getRowDescriptions(PGconn * conn,int msgLength)469 getRowDescriptions(PGconn *conn, int msgLength)
470 {
471 	PGresult   *result;
472 	int			nfields;
473 	const char *errmsg;
474 	int			i;
475 
476 	/*
477 	 * When doing Describe for a prepared statement, there'll already be a
478 	 * PGresult created by getParamDescriptions, and we should fill data into
479 	 * that.  Otherwise, create a new, empty PGresult.
480 	 */
481 	if (conn->queryclass == PGQUERY_DESCRIBE)
482 	{
483 		if (conn->result)
484 			result = conn->result;
485 		else
486 			result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK);
487 	}
488 	else
489 		result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK);
490 	if (!result)
491 	{
492 		errmsg = NULL;			/* means "out of memory", see below */
493 		goto advance_and_error;
494 	}
495 
496 	/* parseInput already read the 'T' label and message length. */
497 	/* the next two bytes are the number of fields */
498 	if (pqGetInt(&(result->numAttributes), 2, conn))
499 	{
500 		/* We should not run out of data here, so complain */
501 		errmsg = libpq_gettext("insufficient data in \"T\" message");
502 		goto advance_and_error;
503 	}
504 	nfields = result->numAttributes;
505 
506 	/* allocate space for the attribute descriptors */
507 	if (nfields > 0)
508 	{
509 		result->attDescs = (PGresAttDesc *)
510 			pqResultAlloc(result, nfields * sizeof(PGresAttDesc), TRUE);
511 		if (!result->attDescs)
512 		{
513 			errmsg = NULL;		/* means "out of memory", see below */
514 			goto advance_and_error;
515 		}
516 		MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc));
517 	}
518 
519 	/* result->binary is true only if ALL columns are binary */
520 	result->binary = (nfields > 0) ? 1 : 0;
521 
522 	/* get type info */
523 	for (i = 0; i < nfields; i++)
524 	{
525 		int			tableid;
526 		int			columnid;
527 		int			typid;
528 		int			typlen;
529 		int			atttypmod;
530 		int			format;
531 
532 		if (pqGets(&conn->workBuffer, conn) ||
533 			pqGetInt(&tableid, 4, conn) ||
534 			pqGetInt(&columnid, 2, conn) ||
535 			pqGetInt(&typid, 4, conn) ||
536 			pqGetInt(&typlen, 2, conn) ||
537 			pqGetInt(&atttypmod, 4, conn) ||
538 			pqGetInt(&format, 2, conn))
539 		{
540 			/* We should not run out of data here, so complain */
541 			errmsg = libpq_gettext("insufficient data in \"T\" message");
542 			goto advance_and_error;
543 		}
544 
545 		/*
546 		 * Since pqGetInt treats 2-byte integers as unsigned, we need to
547 		 * coerce these results to signed form.
548 		 */
549 		columnid = (int) ((int16) columnid);
550 		typlen = (int) ((int16) typlen);
551 		format = (int) ((int16) format);
552 
553 		result->attDescs[i].name = pqResultStrdup(result,
554 												  conn->workBuffer.data);
555 		if (!result->attDescs[i].name)
556 		{
557 			errmsg = NULL;		/* means "out of memory", see below */
558 			goto advance_and_error;
559 		}
560 		result->attDescs[i].tableid = tableid;
561 		result->attDescs[i].columnid = columnid;
562 		result->attDescs[i].format = format;
563 		result->attDescs[i].typid = typid;
564 		result->attDescs[i].typlen = typlen;
565 		result->attDescs[i].atttypmod = atttypmod;
566 
567 		if (format != 1)
568 			result->binary = 0;
569 	}
570 
571 	/* Success! */
572 	conn->result = result;
573 
574 	/*
575 	 * If we're doing a Describe, we're done, and ready to pass the result
576 	 * back to the client.
577 	 */
578 	if (conn->queryclass == PGQUERY_DESCRIBE)
579 	{
580 		conn->asyncStatus = PGASYNC_READY;
581 		return 0;
582 	}
583 
584 	/*
585 	 * We could perform additional setup for the new result set here, but for
586 	 * now there's nothing else to do.
587 	 */
588 
589 	/* And we're done. */
590 	return 0;
591 
592 advance_and_error:
593 	/* Discard unsaved result, if any */
594 	if (result && result != conn->result)
595 		PQclear(result);
596 
597 	/*
598 	 * Replace partially constructed result with an error result. First
599 	 * discard the old result to try to win back some memory.
600 	 */
601 	pqClearAsyncResult(conn);
602 
603 	/*
604 	 * If preceding code didn't provide an error message, assume "out of
605 	 * memory" was meant.  The advantage of having this special case is that
606 	 * freeing the old result first greatly improves the odds that gettext()
607 	 * will succeed in providing a translation.
608 	 */
609 	if (!errmsg)
610 		errmsg = libpq_gettext("out of memory for query result");
611 
612 	printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
613 	pqSaveErrorResult(conn);
614 
615 	/*
616 	 * Show the message as fully consumed, else pqParseInput3 will overwrite
617 	 * our error with a complaint about that.
618 	 */
619 	conn->inCursor = conn->inStart + 5 + msgLength;
620 
621 	/*
622 	 * Return zero to allow input parsing to continue.  Subsequent "D"
623 	 * messages will be ignored until we get to end of data, since an error
624 	 * result is already set up.
625 	 */
626 	return 0;
627 }
628 
629 /*
630  * parseInput subroutine to read a 't' (ParameterDescription) message.
631  * We'll build a new PGresult structure containing the parameter data.
632  * Returns: 0 if processed message successfully, EOF to suspend parsing
633  * (the latter case is not actually used currently).
634  */
635 static int
getParamDescriptions(PGconn * conn,int msgLength)636 getParamDescriptions(PGconn *conn, int msgLength)
637 {
638 	PGresult   *result;
639 	const char *errmsg = NULL;	/* means "out of memory", see below */
640 	int			nparams;
641 	int			i;
642 
643 	result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK);
644 	if (!result)
645 		goto advance_and_error;
646 
647 	/* parseInput already read the 't' label and message length. */
648 	/* the next two bytes are the number of parameters */
649 	if (pqGetInt(&(result->numParameters), 2, conn))
650 		goto not_enough_data;
651 	nparams = result->numParameters;
652 
653 	/* allocate space for the parameter descriptors */
654 	if (nparams > 0)
655 	{
656 		result->paramDescs = (PGresParamDesc *)
657 			pqResultAlloc(result, nparams * sizeof(PGresParamDesc), TRUE);
658 		if (!result->paramDescs)
659 			goto advance_and_error;
660 		MemSet(result->paramDescs, 0, nparams * sizeof(PGresParamDesc));
661 	}
662 
663 	/* get parameter info */
664 	for (i = 0; i < nparams; i++)
665 	{
666 		int			typid;
667 
668 		if (pqGetInt(&typid, 4, conn))
669 			goto not_enough_data;
670 		result->paramDescs[i].typid = typid;
671 	}
672 
673 	/* Success! */
674 	conn->result = result;
675 
676 	return 0;
677 
678 not_enough_data:
679 	errmsg = libpq_gettext("insufficient data in \"t\" message");
680 
681 advance_and_error:
682 	/* Discard unsaved result, if any */
683 	if (result && result != conn->result)
684 		PQclear(result);
685 
686 	/*
687 	 * Replace partially constructed result with an error result. First
688 	 * discard the old result to try to win back some memory.
689 	 */
690 	pqClearAsyncResult(conn);
691 
692 	/*
693 	 * If preceding code didn't provide an error message, assume "out of
694 	 * memory" was meant.  The advantage of having this special case is that
695 	 * freeing the old result first greatly improves the odds that gettext()
696 	 * will succeed in providing a translation.
697 	 */
698 	if (!errmsg)
699 		errmsg = libpq_gettext("out of memory");
700 	printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
701 	pqSaveErrorResult(conn);
702 
703 	/*
704 	 * Show the message as fully consumed, else pqParseInput3 will overwrite
705 	 * our error with a complaint about that.
706 	 */
707 	conn->inCursor = conn->inStart + 5 + msgLength;
708 
709 	/*
710 	 * Return zero to allow input parsing to continue.  Essentially, we've
711 	 * replaced the COMMAND_OK result with an error result, but since this
712 	 * doesn't affect the protocol state, it's fine.
713 	 */
714 	return 0;
715 }
716 
717 /*
718  * parseInput subroutine to read a 'D' (row data) message.
719  * We fill rowbuf with column pointers and then call the row processor.
720  * Returns: 0 if processed message successfully, EOF to suspend parsing
721  * (the latter case is not actually used currently).
722  */
723 static int
getAnotherTuple(PGconn * conn,int msgLength)724 getAnotherTuple(PGconn *conn, int msgLength)
725 {
726 	PGresult   *result = conn->result;
727 	int			nfields = result->numAttributes;
728 	const char *errmsg;
729 	PGdataValue *rowbuf;
730 	int			tupnfields;		/* # fields from tuple */
731 	int			vlen;			/* length of the current field value */
732 	int			i;
733 
734 	/* Get the field count and make sure it's what we expect */
735 	if (pqGetInt(&tupnfields, 2, conn))
736 	{
737 		/* We should not run out of data here, so complain */
738 		errmsg = libpq_gettext("insufficient data in \"D\" message");
739 		goto advance_and_error;
740 	}
741 
742 	if (tupnfields != nfields)
743 	{
744 		errmsg = libpq_gettext("unexpected field count in \"D\" message");
745 		goto advance_and_error;
746 	}
747 
748 	/* Resize row buffer if needed */
749 	rowbuf = conn->rowBuf;
750 	if (nfields > conn->rowBufLen)
751 	{
752 		rowbuf = (PGdataValue *) realloc(rowbuf,
753 										 nfields * sizeof(PGdataValue));
754 		if (!rowbuf)
755 		{
756 			errmsg = NULL;		/* means "out of memory", see below */
757 			goto advance_and_error;
758 		}
759 		conn->rowBuf = rowbuf;
760 		conn->rowBufLen = nfields;
761 	}
762 
763 	/* Scan the fields */
764 	for (i = 0; i < nfields; i++)
765 	{
766 		/* get the value length */
767 		if (pqGetInt(&vlen, 4, conn))
768 		{
769 			/* We should not run out of data here, so complain */
770 			errmsg = libpq_gettext("insufficient data in \"D\" message");
771 			goto advance_and_error;
772 		}
773 		rowbuf[i].len = vlen;
774 
775 		/*
776 		 * rowbuf[i].value always points to the next address in the data
777 		 * buffer even if the value is NULL.  This allows row processors to
778 		 * estimate data sizes more easily.
779 		 */
780 		rowbuf[i].value = conn->inBuffer + conn->inCursor;
781 
782 		/* Skip over the data value */
783 		if (vlen > 0)
784 		{
785 			if (pqSkipnchar(vlen, conn))
786 			{
787 				/* We should not run out of data here, so complain */
788 				errmsg = libpq_gettext("insufficient data in \"D\" message");
789 				goto advance_and_error;
790 			}
791 		}
792 	}
793 
794 	/* Process the collected row */
795 	errmsg = NULL;
796 	if (pqRowProcessor(conn, &errmsg))
797 		return 0;				/* normal, successful exit */
798 
799 	/* pqRowProcessor failed, fall through to report it */
800 
801 advance_and_error:
802 
803 	/*
804 	 * Replace partially constructed result with an error result. First
805 	 * discard the old result to try to win back some memory.
806 	 */
807 	pqClearAsyncResult(conn);
808 
809 	/*
810 	 * If preceding code didn't provide an error message, assume "out of
811 	 * memory" was meant.  The advantage of having this special case is that
812 	 * freeing the old result first greatly improves the odds that gettext()
813 	 * will succeed in providing a translation.
814 	 */
815 	if (!errmsg)
816 		errmsg = libpq_gettext("out of memory for query result");
817 
818 	printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
819 	pqSaveErrorResult(conn);
820 
821 	/*
822 	 * Show the message as fully consumed, else pqParseInput3 will overwrite
823 	 * our error with a complaint about that.
824 	 */
825 	conn->inCursor = conn->inStart + 5 + msgLength;
826 
827 	/*
828 	 * Return zero to allow input parsing to continue.  Subsequent "D"
829 	 * messages will be ignored until we get to end of data, since an error
830 	 * result is already set up.
831 	 */
832 	return 0;
833 }
834 
835 
836 /*
837  * Attempt to read an Error or Notice response message.
838  * This is possible in several places, so we break it out as a subroutine.
839  * Entry: 'E' or 'N' message type and length have already been consumed.
840  * Exit: returns 0 if successfully consumed message.
841  *		 returns EOF if not enough data.
842  */
843 int
pqGetErrorNotice3(PGconn * conn,bool isError)844 pqGetErrorNotice3(PGconn *conn, bool isError)
845 {
846 	PGresult   *res = NULL;
847 	bool		have_position = false;
848 	PQExpBufferData workBuf;
849 	char		id;
850 
851 	/*
852 	 * If this is an error message, pre-emptively clear any incomplete query
853 	 * result we may have.  We'd just throw it away below anyway, and
854 	 * releasing it before collecting the error might avoid out-of-memory.
855 	 */
856 	if (isError)
857 		pqClearAsyncResult(conn);
858 
859 	/*
860 	 * Since the fields might be pretty long, we create a temporary
861 	 * PQExpBuffer rather than using conn->workBuffer.  workBuffer is intended
862 	 * for stuff that is expected to be short.  We shouldn't use
863 	 * conn->errorMessage either, since this might be only a notice.
864 	 */
865 	initPQExpBuffer(&workBuf);
866 
867 	/*
868 	 * Make a PGresult to hold the accumulated fields.  We temporarily lie
869 	 * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
870 	 * copy conn->errorMessage.
871 	 *
872 	 * NB: This allocation can fail, if you run out of memory. The rest of the
873 	 * function handles that gracefully, and we still try to set the error
874 	 * message as the connection's error message.
875 	 */
876 	res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
877 	if (res)
878 		res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
879 
880 	/*
881 	 * Read the fields and save into res.
882 	 *
883 	 * While at it, save the SQLSTATE in conn->last_sqlstate, and note whether
884 	 * we saw a PG_DIAG_STATEMENT_POSITION field.
885 	 */
886 	for (;;)
887 	{
888 		if (pqGetc(&id, conn))
889 			goto fail;
890 		if (id == '\0')
891 			break;				/* terminator found */
892 		if (pqGets(&workBuf, conn))
893 			goto fail;
894 		pqSaveMessageField(res, id, workBuf.data);
895 		if (id == PG_DIAG_SQLSTATE)
896 			strlcpy(conn->last_sqlstate, workBuf.data,
897 					sizeof(conn->last_sqlstate));
898 		else if (id == PG_DIAG_STATEMENT_POSITION)
899 			have_position = true;
900 	}
901 
902 	/*
903 	 * Save the active query text, if any, into res as well; but only if we
904 	 * might need it for an error cursor display, which is only true if there
905 	 * is a PG_DIAG_STATEMENT_POSITION field.
906 	 */
907 	if (have_position && conn->last_query && res)
908 		res->errQuery = pqResultStrdup(res, conn->last_query);
909 
910 	/*
911 	 * Now build the "overall" error message for PQresultErrorMessage.
912 	 */
913 	resetPQExpBuffer(&workBuf);
914 	pqBuildErrorMessage3(&workBuf, res, conn->verbosity, conn->show_context);
915 
916 	/*
917 	 * Either save error as current async result, or just emit the notice.
918 	 */
919 	if (isError)
920 	{
921 		if (res)
922 			res->errMsg = pqResultStrdup(res, workBuf.data);
923 		pqClearAsyncResult(conn);	/* redundant, but be safe */
924 		conn->result = res;
925 		if (PQExpBufferDataBroken(workBuf))
926 			printfPQExpBuffer(&conn->errorMessage,
927 							  libpq_gettext("out of memory"));
928 		else
929 			appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
930 	}
931 	else
932 	{
933 		/* if we couldn't allocate the result set, just discard the NOTICE */
934 		if (res)
935 		{
936 			/* We can cheat a little here and not copy the message. */
937 			res->errMsg = workBuf.data;
938 			if (res->noticeHooks.noticeRec != NULL)
939 				(*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
940 			PQclear(res);
941 		}
942 	}
943 
944 	termPQExpBuffer(&workBuf);
945 	return 0;
946 
947 fail:
948 	PQclear(res);
949 	termPQExpBuffer(&workBuf);
950 	return EOF;
951 }
952 
953 /*
954  * Construct an error message from the fields in the given PGresult,
955  * appending it to the contents of "msg".
956  */
957 void
pqBuildErrorMessage3(PQExpBuffer msg,const PGresult * res,PGVerbosity verbosity,PGContextVisibility show_context)958 pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res,
959 					 PGVerbosity verbosity, PGContextVisibility show_context)
960 {
961 	const char *val;
962 	const char *querytext = NULL;
963 	int			querypos = 0;
964 
965 	/* If we couldn't allocate a PGresult, just say "out of memory" */
966 	if (res == NULL)
967 	{
968 		appendPQExpBuffer(msg, libpq_gettext("out of memory\n"));
969 		return;
970 	}
971 
972 	/*
973 	 * If we don't have any broken-down fields, just return the base message.
974 	 * This mainly applies if we're given a libpq-generated error result.
975 	 */
976 	if (res->errFields == NULL)
977 	{
978 		if (res->errMsg && res->errMsg[0])
979 			appendPQExpBufferStr(msg, res->errMsg);
980 		else
981 			appendPQExpBuffer(msg, libpq_gettext("no error message available\n"));
982 		return;
983 	}
984 
985 	/* Else build error message from relevant fields */
986 	val = PQresultErrorField(res, PG_DIAG_SEVERITY);
987 	if (val)
988 		appendPQExpBuffer(msg, "%s:  ", val);
989 	if (verbosity == PQERRORS_VERBOSE)
990 	{
991 		val = PQresultErrorField(res, PG_DIAG_SQLSTATE);
992 		if (val)
993 			appendPQExpBuffer(msg, "%s: ", val);
994 	}
995 	val = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
996 	if (val)
997 		appendPQExpBufferStr(msg, val);
998 	val = PQresultErrorField(res, PG_DIAG_STATEMENT_POSITION);
999 	if (val)
1000 	{
1001 		if (verbosity != PQERRORS_TERSE && res->errQuery != NULL)
1002 		{
1003 			/* emit position as a syntax cursor display */
1004 			querytext = res->errQuery;
1005 			querypos = atoi(val);
1006 		}
1007 		else
1008 		{
1009 			/* emit position as text addition to primary message */
1010 			/* translator: %s represents a digit string */
1011 			appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1012 							  val);
1013 		}
1014 	}
1015 	else
1016 	{
1017 		val = PQresultErrorField(res, PG_DIAG_INTERNAL_POSITION);
1018 		if (val)
1019 		{
1020 			querytext = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY);
1021 			if (verbosity != PQERRORS_TERSE && querytext != NULL)
1022 			{
1023 				/* emit position as a syntax cursor display */
1024 				querypos = atoi(val);
1025 			}
1026 			else
1027 			{
1028 				/* emit position as text addition to primary message */
1029 				/* translator: %s represents a digit string */
1030 				appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1031 								  val);
1032 			}
1033 		}
1034 	}
1035 	appendPQExpBufferChar(msg, '\n');
1036 	if (verbosity != PQERRORS_TERSE)
1037 	{
1038 		if (querytext && querypos > 0)
1039 			reportErrorPosition(msg, querytext, querypos,
1040 								res->client_encoding);
1041 		val = PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL);
1042 		if (val)
1043 			appendPQExpBuffer(msg, libpq_gettext("DETAIL:  %s\n"), val);
1044 		val = PQresultErrorField(res, PG_DIAG_MESSAGE_HINT);
1045 		if (val)
1046 			appendPQExpBuffer(msg, libpq_gettext("HINT:  %s\n"), val);
1047 		val = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY);
1048 		if (val)
1049 			appendPQExpBuffer(msg, libpq_gettext("QUERY:  %s\n"), val);
1050 		if (show_context == PQSHOW_CONTEXT_ALWAYS ||
1051 			(show_context == PQSHOW_CONTEXT_ERRORS &&
1052 			 res->resultStatus == PGRES_FATAL_ERROR))
1053 		{
1054 			val = PQresultErrorField(res, PG_DIAG_CONTEXT);
1055 			if (val)
1056 				appendPQExpBuffer(msg, libpq_gettext("CONTEXT:  %s\n"),
1057 								  val);
1058 		}
1059 	}
1060 	if (verbosity == PQERRORS_VERBOSE)
1061 	{
1062 		val = PQresultErrorField(res, PG_DIAG_SCHEMA_NAME);
1063 		if (val)
1064 			appendPQExpBuffer(msg,
1065 							  libpq_gettext("SCHEMA NAME:  %s\n"), val);
1066 		val = PQresultErrorField(res, PG_DIAG_TABLE_NAME);
1067 		if (val)
1068 			appendPQExpBuffer(msg,
1069 							  libpq_gettext("TABLE NAME:  %s\n"), val);
1070 		val = PQresultErrorField(res, PG_DIAG_COLUMN_NAME);
1071 		if (val)
1072 			appendPQExpBuffer(msg,
1073 							  libpq_gettext("COLUMN NAME:  %s\n"), val);
1074 		val = PQresultErrorField(res, PG_DIAG_DATATYPE_NAME);
1075 		if (val)
1076 			appendPQExpBuffer(msg,
1077 							  libpq_gettext("DATATYPE NAME:  %s\n"), val);
1078 		val = PQresultErrorField(res, PG_DIAG_CONSTRAINT_NAME);
1079 		if (val)
1080 			appendPQExpBuffer(msg,
1081 							  libpq_gettext("CONSTRAINT NAME:  %s\n"), val);
1082 	}
1083 	if (verbosity == PQERRORS_VERBOSE)
1084 	{
1085 		const char *valf;
1086 		const char *vall;
1087 
1088 		valf = PQresultErrorField(res, PG_DIAG_SOURCE_FILE);
1089 		vall = PQresultErrorField(res, PG_DIAG_SOURCE_LINE);
1090 		val = PQresultErrorField(res, PG_DIAG_SOURCE_FUNCTION);
1091 		if (val || valf || vall)
1092 		{
1093 			appendPQExpBufferStr(msg, libpq_gettext("LOCATION:  "));
1094 			if (val)
1095 				appendPQExpBuffer(msg, libpq_gettext("%s, "), val);
1096 			if (valf && vall)	/* unlikely we'd have just one */
1097 				appendPQExpBuffer(msg, libpq_gettext("%s:%s"),
1098 								  valf, vall);
1099 			appendPQExpBufferChar(msg, '\n');
1100 		}
1101 	}
1102 }
1103 
1104 /*
1105  * Add an error-location display to the error message under construction.
1106  *
1107  * The cursor location is measured in logical characters; the query string
1108  * is presumed to be in the specified encoding.
1109  */
1110 static void
reportErrorPosition(PQExpBuffer msg,const char * query,int loc,int encoding)1111 reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
1112 {
1113 #define DISPLAY_SIZE	60		/* screen width limit, in screen cols */
1114 #define MIN_RIGHT_CUT	10		/* try to keep this far away from EOL */
1115 
1116 	char	   *wquery;
1117 	int			slen,
1118 				cno,
1119 				i,
1120 			   *qidx,
1121 			   *scridx,
1122 				qoffset,
1123 				scroffset,
1124 				ibeg,
1125 				iend,
1126 				loc_line;
1127 	bool		mb_encoding,
1128 				beg_trunc,
1129 				end_trunc;
1130 
1131 	/* Convert loc from 1-based to 0-based; no-op if out of range */
1132 	loc--;
1133 	if (loc < 0)
1134 		return;
1135 
1136 	/* Need a writable copy of the query */
1137 	wquery = strdup(query);
1138 	if (wquery == NULL)
1139 		return;					/* fail silently if out of memory */
1140 
1141 	/*
1142 	 * Each character might occupy multiple physical bytes in the string, and
1143 	 * in some Far Eastern character sets it might take more than one screen
1144 	 * column as well.  We compute the starting byte offset and starting
1145 	 * screen column of each logical character, and store these in qidx[] and
1146 	 * scridx[] respectively.
1147 	 */
1148 
1149 	/* we need a safe allocation size... */
1150 	slen = strlen(wquery) + 1;
1151 
1152 	qidx = (int *) malloc(slen * sizeof(int));
1153 	if (qidx == NULL)
1154 	{
1155 		free(wquery);
1156 		return;
1157 	}
1158 	scridx = (int *) malloc(slen * sizeof(int));
1159 	if (scridx == NULL)
1160 	{
1161 		free(qidx);
1162 		free(wquery);
1163 		return;
1164 	}
1165 
1166 	/* We can optimize a bit if it's a single-byte encoding */
1167 	mb_encoding = (pg_encoding_max_length(encoding) != 1);
1168 
1169 	/*
1170 	 * Within the scanning loop, cno is the current character's logical
1171 	 * number, qoffset is its offset in wquery, and scroffset is its starting
1172 	 * logical screen column (all indexed from 0).  "loc" is the logical
1173 	 * character number of the error location.  We scan to determine loc_line
1174 	 * (the 1-based line number containing loc) and ibeg/iend (first character
1175 	 * number and last+1 character number of the line containing loc). Note
1176 	 * that qidx[] and scridx[] are filled only as far as iend.
1177 	 */
1178 	qoffset = 0;
1179 	scroffset = 0;
1180 	loc_line = 1;
1181 	ibeg = 0;
1182 	iend = -1;					/* -1 means not set yet */
1183 
1184 	for (cno = 0; wquery[qoffset] != '\0'; cno++)
1185 	{
1186 		char		ch = wquery[qoffset];
1187 
1188 		qidx[cno] = qoffset;
1189 		scridx[cno] = scroffset;
1190 
1191 		/*
1192 		 * Replace tabs with spaces in the writable copy.  (Later we might
1193 		 * want to think about coping with their variable screen width, but
1194 		 * not today.)
1195 		 */
1196 		if (ch == '\t')
1197 			wquery[qoffset] = ' ';
1198 
1199 		/*
1200 		 * If end-of-line, count lines and mark positions. Each \r or \n
1201 		 * counts as a line except when \r \n appear together.
1202 		 */
1203 		else if (ch == '\r' || ch == '\n')
1204 		{
1205 			if (cno < loc)
1206 			{
1207 				if (ch == '\r' ||
1208 					cno == 0 ||
1209 					wquery[qidx[cno - 1]] != '\r')
1210 					loc_line++;
1211 				/* extract beginning = last line start before loc. */
1212 				ibeg = cno + 1;
1213 			}
1214 			else
1215 			{
1216 				/* set extract end. */
1217 				iend = cno;
1218 				/* done scanning. */
1219 				break;
1220 			}
1221 		}
1222 
1223 		/* Advance */
1224 		if (mb_encoding)
1225 		{
1226 			int			w;
1227 
1228 			w = pg_encoding_dsplen(encoding, &wquery[qoffset]);
1229 			/* treat any non-tab control chars as width 1 */
1230 			if (w <= 0)
1231 				w = 1;
1232 			scroffset += w;
1233 			qoffset += PQmblenBounded(&wquery[qoffset], encoding);
1234 		}
1235 		else
1236 		{
1237 			/* We assume wide chars only exist in multibyte encodings */
1238 			scroffset++;
1239 			qoffset++;
1240 		}
1241 	}
1242 	/* Fix up if we didn't find an end-of-line after loc */
1243 	if (iend < 0)
1244 	{
1245 		iend = cno;				/* query length in chars, +1 */
1246 		qidx[iend] = qoffset;
1247 		scridx[iend] = scroffset;
1248 	}
1249 
1250 	/* Print only if loc is within computed query length */
1251 	if (loc <= cno)
1252 	{
1253 		/* If the line extracted is too long, we truncate it. */
1254 		beg_trunc = false;
1255 		end_trunc = false;
1256 		if (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
1257 		{
1258 			/*
1259 			 * We first truncate right if it is enough.  This code might be
1260 			 * off a space or so on enforcing MIN_RIGHT_CUT if there's a wide
1261 			 * character right there, but that should be okay.
1262 			 */
1263 			if (scridx[ibeg] + DISPLAY_SIZE >= scridx[loc] + MIN_RIGHT_CUT)
1264 			{
1265 				while (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
1266 					iend--;
1267 				end_trunc = true;
1268 			}
1269 			else
1270 			{
1271 				/* Truncate right if not too close to loc. */
1272 				while (scridx[loc] + MIN_RIGHT_CUT < scridx[iend])
1273 				{
1274 					iend--;
1275 					end_trunc = true;
1276 				}
1277 
1278 				/* Truncate left if still too long. */
1279 				while (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE)
1280 				{
1281 					ibeg++;
1282 					beg_trunc = true;
1283 				}
1284 			}
1285 		}
1286 
1287 		/* truncate working copy at desired endpoint */
1288 		wquery[qidx[iend]] = '\0';
1289 
1290 		/* Begin building the finished message. */
1291 		i = msg->len;
1292 		appendPQExpBuffer(msg, libpq_gettext("LINE %d: "), loc_line);
1293 		if (beg_trunc)
1294 			appendPQExpBufferStr(msg, "...");
1295 
1296 		/*
1297 		 * While we have the prefix in the msg buffer, compute its screen
1298 		 * width.
1299 		 */
1300 		scroffset = 0;
1301 		for (; i < msg->len; i += PQmblenBounded(&msg->data[i], encoding))
1302 		{
1303 			int			w = pg_encoding_dsplen(encoding, &msg->data[i]);
1304 
1305 			if (w <= 0)
1306 				w = 1;
1307 			scroffset += w;
1308 		}
1309 
1310 		/* Finish up the LINE message line. */
1311 		appendPQExpBufferStr(msg, &wquery[qidx[ibeg]]);
1312 		if (end_trunc)
1313 			appendPQExpBufferStr(msg, "...");
1314 		appendPQExpBufferChar(msg, '\n');
1315 
1316 		/* Now emit the cursor marker line. */
1317 		scroffset += scridx[loc] - scridx[ibeg];
1318 		for (i = 0; i < scroffset; i++)
1319 			appendPQExpBufferChar(msg, ' ');
1320 		appendPQExpBufferChar(msg, '^');
1321 		appendPQExpBufferChar(msg, '\n');
1322 	}
1323 
1324 	/* Clean up. */
1325 	free(scridx);
1326 	free(qidx);
1327 	free(wquery);
1328 }
1329 
1330 
1331 /*
1332  * Attempt to read a ParameterStatus message.
1333  * This is possible in several places, so we break it out as a subroutine.
1334  * Entry: 'S' message type and length have already been consumed.
1335  * Exit: returns 0 if successfully consumed message.
1336  *		 returns EOF if not enough data.
1337  */
1338 static int
getParameterStatus(PGconn * conn)1339 getParameterStatus(PGconn *conn)
1340 {
1341 	PQExpBufferData valueBuf;
1342 
1343 	/* Get the parameter name */
1344 	if (pqGets(&conn->workBuffer, conn))
1345 		return EOF;
1346 	/* Get the parameter value (could be large) */
1347 	initPQExpBuffer(&valueBuf);
1348 	if (pqGets(&valueBuf, conn))
1349 	{
1350 		termPQExpBuffer(&valueBuf);
1351 		return EOF;
1352 	}
1353 	/* And save it */
1354 	pqSaveParameterStatus(conn, conn->workBuffer.data, valueBuf.data);
1355 	termPQExpBuffer(&valueBuf);
1356 	return 0;
1357 }
1358 
1359 
1360 /*
1361  * Attempt to read a Notify response message.
1362  * This is possible in several places, so we break it out as a subroutine.
1363  * Entry: 'A' message type and length have already been consumed.
1364  * Exit: returns 0 if successfully consumed Notify message.
1365  *		 returns EOF if not enough data.
1366  */
1367 static int
getNotify(PGconn * conn)1368 getNotify(PGconn *conn)
1369 {
1370 	int			be_pid;
1371 	char	   *svname;
1372 	int			nmlen;
1373 	int			extralen;
1374 	PGnotify   *newNotify;
1375 
1376 	if (pqGetInt(&be_pid, 4, conn))
1377 		return EOF;
1378 	if (pqGets(&conn->workBuffer, conn))
1379 		return EOF;
1380 	/* must save name while getting extra string */
1381 	svname = strdup(conn->workBuffer.data);
1382 	if (!svname)
1383 		return EOF;
1384 	if (pqGets(&conn->workBuffer, conn))
1385 	{
1386 		free(svname);
1387 		return EOF;
1388 	}
1389 
1390 	/*
1391 	 * Store the strings right after the PQnotify structure so it can all be
1392 	 * freed at once.  We don't use NAMEDATALEN because we don't want to tie
1393 	 * this interface to a specific server name length.
1394 	 */
1395 	nmlen = strlen(svname);
1396 	extralen = strlen(conn->workBuffer.data);
1397 	newNotify = (PGnotify *) malloc(sizeof(PGnotify) + nmlen + extralen + 2);
1398 	if (newNotify)
1399 	{
1400 		newNotify->relname = (char *) newNotify + sizeof(PGnotify);
1401 		strcpy(newNotify->relname, svname);
1402 		newNotify->extra = newNotify->relname + nmlen + 1;
1403 		strcpy(newNotify->extra, conn->workBuffer.data);
1404 		newNotify->be_pid = be_pid;
1405 		newNotify->next = NULL;
1406 		if (conn->notifyTail)
1407 			conn->notifyTail->next = newNotify;
1408 		else
1409 			conn->notifyHead = newNotify;
1410 		conn->notifyTail = newNotify;
1411 	}
1412 
1413 	free(svname);
1414 	return 0;
1415 }
1416 
1417 /*
1418  * getCopyStart - process CopyInResponse, CopyOutResponse or
1419  * CopyBothResponse message
1420  *
1421  * parseInput already read the message type and length.
1422  */
1423 static int
getCopyStart(PGconn * conn,ExecStatusType copytype)1424 getCopyStart(PGconn *conn, ExecStatusType copytype)
1425 {
1426 	PGresult   *result;
1427 	int			nfields;
1428 	int			i;
1429 
1430 	result = PQmakeEmptyPGresult(conn, copytype);
1431 	if (!result)
1432 		goto failure;
1433 
1434 	if (pqGetc(&conn->copy_is_binary, conn))
1435 		goto failure;
1436 	result->binary = conn->copy_is_binary;
1437 	/* the next two bytes are the number of fields	*/
1438 	if (pqGetInt(&(result->numAttributes), 2, conn))
1439 		goto failure;
1440 	nfields = result->numAttributes;
1441 
1442 	/* allocate space for the attribute descriptors */
1443 	if (nfields > 0)
1444 	{
1445 		result->attDescs = (PGresAttDesc *)
1446 			pqResultAlloc(result, nfields * sizeof(PGresAttDesc), TRUE);
1447 		if (!result->attDescs)
1448 			goto failure;
1449 		MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc));
1450 	}
1451 
1452 	for (i = 0; i < nfields; i++)
1453 	{
1454 		int			format;
1455 
1456 		if (pqGetInt(&format, 2, conn))
1457 			goto failure;
1458 
1459 		/*
1460 		 * Since pqGetInt treats 2-byte integers as unsigned, we need to
1461 		 * coerce these results to signed form.
1462 		 */
1463 		format = (int) ((int16) format);
1464 		result->attDescs[i].format = format;
1465 	}
1466 
1467 	/* Success! */
1468 	conn->result = result;
1469 	return 0;
1470 
1471 failure:
1472 	PQclear(result);
1473 	return EOF;
1474 }
1475 
1476 /*
1477  * getReadyForQuery - process ReadyForQuery message
1478  */
1479 static int
getReadyForQuery(PGconn * conn)1480 getReadyForQuery(PGconn *conn)
1481 {
1482 	char		xact_status;
1483 
1484 	if (pqGetc(&xact_status, conn))
1485 		return EOF;
1486 	switch (xact_status)
1487 	{
1488 		case 'I':
1489 			conn->xactStatus = PQTRANS_IDLE;
1490 			break;
1491 		case 'T':
1492 			conn->xactStatus = PQTRANS_INTRANS;
1493 			break;
1494 		case 'E':
1495 			conn->xactStatus = PQTRANS_INERROR;
1496 			break;
1497 		default:
1498 			conn->xactStatus = PQTRANS_UNKNOWN;
1499 			break;
1500 	}
1501 
1502 	return 0;
1503 }
1504 
1505 /*
1506  * getCopyDataMessage - fetch next CopyData message, process async messages
1507  *
1508  * Returns length word of CopyData message (> 0), or 0 if no complete
1509  * message available, -1 if end of copy, -2 if error.
1510  */
1511 static int
getCopyDataMessage(PGconn * conn)1512 getCopyDataMessage(PGconn *conn)
1513 {
1514 	char		id;
1515 	int			msgLength;
1516 	int			avail;
1517 
1518 	for (;;)
1519 	{
1520 		/*
1521 		 * Do we have the next input message?  To make life simpler for async
1522 		 * callers, we keep returning 0 until the next message is fully
1523 		 * available, even if it is not Copy Data.
1524 		 */
1525 		conn->inCursor = conn->inStart;
1526 		if (pqGetc(&id, conn))
1527 			return 0;
1528 		if (pqGetInt(&msgLength, 4, conn))
1529 			return 0;
1530 		if (msgLength < 4)
1531 		{
1532 			handleSyncLoss(conn, id, msgLength);
1533 			return -2;
1534 		}
1535 		avail = conn->inEnd - conn->inCursor;
1536 		if (avail < msgLength - 4)
1537 		{
1538 			/*
1539 			 * Before returning, enlarge the input buffer if needed to hold
1540 			 * the whole message.  See notes in parseInput.
1541 			 */
1542 			if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength - 4,
1543 									 conn))
1544 			{
1545 				/*
1546 				 * XXX add some better recovery code... plan is to skip over
1547 				 * the message using its length, then report an error. For the
1548 				 * moment, just treat this like loss of sync (which indeed it
1549 				 * might be!)
1550 				 */
1551 				handleSyncLoss(conn, id, msgLength);
1552 				return -2;
1553 			}
1554 			return 0;
1555 		}
1556 
1557 		/*
1558 		 * If it's a legitimate async message type, process it.  (NOTIFY
1559 		 * messages are not currently possible here, but we handle them for
1560 		 * completeness.)  Otherwise, if it's anything except Copy Data,
1561 		 * report end-of-copy.
1562 		 */
1563 		switch (id)
1564 		{
1565 			case 'A':			/* NOTIFY */
1566 				if (getNotify(conn))
1567 					return 0;
1568 				break;
1569 			case 'N':			/* NOTICE */
1570 				if (pqGetErrorNotice3(conn, false))
1571 					return 0;
1572 				break;
1573 			case 'S':			/* ParameterStatus */
1574 				if (getParameterStatus(conn))
1575 					return 0;
1576 				break;
1577 			case 'd':			/* Copy Data, pass it back to caller */
1578 				return msgLength;
1579 			case 'c':
1580 
1581 				/*
1582 				 * If this is a CopyDone message, exit COPY_OUT mode and let
1583 				 * caller read status with PQgetResult().  If we're in
1584 				 * COPY_BOTH mode, return to COPY_IN mode.
1585 				 */
1586 				if (conn->asyncStatus == PGASYNC_COPY_BOTH)
1587 					conn->asyncStatus = PGASYNC_COPY_IN;
1588 				else
1589 					conn->asyncStatus = PGASYNC_BUSY;
1590 				return -1;
1591 			default:			/* treat as end of copy */
1592 
1593 				/*
1594 				 * Any other message terminates either COPY_IN or COPY_BOTH
1595 				 * mode.
1596 				 */
1597 				conn->asyncStatus = PGASYNC_BUSY;
1598 				return -1;
1599 		}
1600 
1601 		/* Drop the processed message and loop around for another */
1602 		conn->inStart = conn->inCursor;
1603 	}
1604 }
1605 
1606 /*
1607  * PQgetCopyData - read a row of data from the backend during COPY OUT
1608  * or COPY BOTH
1609  *
1610  * If successful, sets *buffer to point to a malloc'd row of data, and
1611  * returns row length (always > 0) as result.
1612  * Returns 0 if no row available yet (only possible if async is true),
1613  * -1 if end of copy (consult PQgetResult), or -2 if error (consult
1614  * PQerrorMessage).
1615  */
1616 int
pqGetCopyData3(PGconn * conn,char ** buffer,int async)1617 pqGetCopyData3(PGconn *conn, char **buffer, int async)
1618 {
1619 	int			msgLength;
1620 
1621 	for (;;)
1622 	{
1623 		/*
1624 		 * Collect the next input message.  To make life simpler for async
1625 		 * callers, we keep returning 0 until the next message is fully
1626 		 * available, even if it is not Copy Data.
1627 		 */
1628 		msgLength = getCopyDataMessage(conn);
1629 		if (msgLength < 0)
1630 			return msgLength;	/* end-of-copy or error */
1631 		if (msgLength == 0)
1632 		{
1633 			/* Don't block if async read requested */
1634 			if (async)
1635 				return 0;
1636 			/* Need to load more data */
1637 			if (pqWait(TRUE, FALSE, conn) ||
1638 				pqReadData(conn) < 0)
1639 				return -2;
1640 			continue;
1641 		}
1642 
1643 		/*
1644 		 * Drop zero-length messages (shouldn't happen anyway).  Otherwise
1645 		 * pass the data back to the caller.
1646 		 */
1647 		msgLength -= 4;
1648 		if (msgLength > 0)
1649 		{
1650 			*buffer = (char *) malloc(msgLength + 1);
1651 			if (*buffer == NULL)
1652 			{
1653 				printfPQExpBuffer(&conn->errorMessage,
1654 								  libpq_gettext("out of memory\n"));
1655 				return -2;
1656 			}
1657 			memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength);
1658 			(*buffer)[msgLength] = '\0';		/* Add terminating null */
1659 
1660 			/* Mark message consumed */
1661 			conn->inStart = conn->inCursor + msgLength;
1662 
1663 			return msgLength;
1664 		}
1665 
1666 		/* Empty, so drop it and loop around for another */
1667 		conn->inStart = conn->inCursor;
1668 	}
1669 }
1670 
1671 /*
1672  * PQgetline - gets a newline-terminated string from the backend.
1673  *
1674  * See fe-exec.c for documentation.
1675  */
1676 int
pqGetline3(PGconn * conn,char * s,int maxlen)1677 pqGetline3(PGconn *conn, char *s, int maxlen)
1678 {
1679 	int			status;
1680 
1681 	if (conn->sock == PGINVALID_SOCKET ||
1682 		(conn->asyncStatus != PGASYNC_COPY_OUT &&
1683 		 conn->asyncStatus != PGASYNC_COPY_BOTH) ||
1684 		conn->copy_is_binary)
1685 	{
1686 		printfPQExpBuffer(&conn->errorMessage,
1687 					  libpq_gettext("PQgetline: not doing text COPY OUT\n"));
1688 		*s = '\0';
1689 		return EOF;
1690 	}
1691 
1692 	while ((status = PQgetlineAsync(conn, s, maxlen - 1)) == 0)
1693 	{
1694 		/* need to load more data */
1695 		if (pqWait(TRUE, FALSE, conn) ||
1696 			pqReadData(conn) < 0)
1697 		{
1698 			*s = '\0';
1699 			return EOF;
1700 		}
1701 	}
1702 
1703 	if (status < 0)
1704 	{
1705 		/* End of copy detected; gin up old-style terminator */
1706 		strcpy(s, "\\.");
1707 		return 0;
1708 	}
1709 
1710 	/* Add null terminator, and strip trailing \n if present */
1711 	if (s[status - 1] == '\n')
1712 	{
1713 		s[status - 1] = '\0';
1714 		return 0;
1715 	}
1716 	else
1717 	{
1718 		s[status] = '\0';
1719 		return 1;
1720 	}
1721 }
1722 
1723 /*
1724  * PQgetlineAsync - gets a COPY data row without blocking.
1725  *
1726  * See fe-exec.c for documentation.
1727  */
1728 int
pqGetlineAsync3(PGconn * conn,char * buffer,int bufsize)1729 pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize)
1730 {
1731 	int			msgLength;
1732 	int			avail;
1733 
1734 	if (conn->asyncStatus != PGASYNC_COPY_OUT
1735 		&& conn->asyncStatus != PGASYNC_COPY_BOTH)
1736 		return -1;				/* we are not doing a copy... */
1737 
1738 	/*
1739 	 * Recognize the next input message.  To make life simpler for async
1740 	 * callers, we keep returning 0 until the next message is fully available
1741 	 * even if it is not Copy Data.  This should keep PQendcopy from blocking.
1742 	 * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.)
1743 	 */
1744 	msgLength = getCopyDataMessage(conn);
1745 	if (msgLength < 0)
1746 		return -1;				/* end-of-copy or error */
1747 	if (msgLength == 0)
1748 		return 0;				/* no data yet */
1749 
1750 	/*
1751 	 * Move data from libpq's buffer to the caller's.  In the case where a
1752 	 * prior call found the caller's buffer too small, we use
1753 	 * conn->copy_already_done to remember how much of the row was already
1754 	 * returned to the caller.
1755 	 */
1756 	conn->inCursor += conn->copy_already_done;
1757 	avail = msgLength - 4 - conn->copy_already_done;
1758 	if (avail <= bufsize)
1759 	{
1760 		/* Able to consume the whole message */
1761 		memcpy(buffer, &conn->inBuffer[conn->inCursor], avail);
1762 		/* Mark message consumed */
1763 		conn->inStart = conn->inCursor + avail;
1764 		/* Reset state for next time */
1765 		conn->copy_already_done = 0;
1766 		return avail;
1767 	}
1768 	else
1769 	{
1770 		/* We must return a partial message */
1771 		memcpy(buffer, &conn->inBuffer[conn->inCursor], bufsize);
1772 		/* The message is NOT consumed from libpq's buffer */
1773 		conn->copy_already_done += bufsize;
1774 		return bufsize;
1775 	}
1776 }
1777 
1778 /*
1779  * PQendcopy
1780  *
1781  * See fe-exec.c for documentation.
1782  */
1783 int
pqEndcopy3(PGconn * conn)1784 pqEndcopy3(PGconn *conn)
1785 {
1786 	PGresult   *result;
1787 
1788 	if (conn->asyncStatus != PGASYNC_COPY_IN &&
1789 		conn->asyncStatus != PGASYNC_COPY_OUT &&
1790 		conn->asyncStatus != PGASYNC_COPY_BOTH)
1791 	{
1792 		printfPQExpBuffer(&conn->errorMessage,
1793 						  libpq_gettext("no COPY in progress\n"));
1794 		return 1;
1795 	}
1796 
1797 	/* Send the CopyDone message if needed */
1798 	if (conn->asyncStatus == PGASYNC_COPY_IN ||
1799 		conn->asyncStatus == PGASYNC_COPY_BOTH)
1800 	{
1801 		if (pqPutMsgStart('c', false, conn) < 0 ||
1802 			pqPutMsgEnd(conn) < 0)
1803 			return 1;
1804 
1805 		/*
1806 		 * If we sent the COPY command in extended-query mode, we must issue a
1807 		 * Sync as well.
1808 		 */
1809 		if (conn->queryclass != PGQUERY_SIMPLE)
1810 		{
1811 			if (pqPutMsgStart('S', false, conn) < 0 ||
1812 				pqPutMsgEnd(conn) < 0)
1813 				return 1;
1814 		}
1815 	}
1816 
1817 	/*
1818 	 * make sure no data is waiting to be sent, abort if we are non-blocking
1819 	 * and the flush fails
1820 	 */
1821 	if (pqFlush(conn) && pqIsnonblocking(conn))
1822 		return 1;
1823 
1824 	/* Return to active duty */
1825 	conn->asyncStatus = PGASYNC_BUSY;
1826 	resetPQExpBuffer(&conn->errorMessage);
1827 
1828 	/*
1829 	 * Non blocking connections may have to abort at this point.  If everyone
1830 	 * played the game there should be no problem, but in error scenarios the
1831 	 * expected messages may not have arrived yet.  (We are assuming that the
1832 	 * backend's packetizing will ensure that CommandComplete arrives along
1833 	 * with the CopyDone; are there corner cases where that doesn't happen?)
1834 	 */
1835 	if (pqIsnonblocking(conn) && PQisBusy(conn))
1836 		return 1;
1837 
1838 	/* Wait for the completion response */
1839 	result = PQgetResult(conn);
1840 
1841 	/* Expecting a successful result */
1842 	if (result && result->resultStatus == PGRES_COMMAND_OK)
1843 	{
1844 		PQclear(result);
1845 		return 0;
1846 	}
1847 
1848 	/*
1849 	 * Trouble. For backwards-compatibility reasons, we issue the error
1850 	 * message as if it were a notice (would be nice to get rid of this
1851 	 * silliness, but too many apps probably don't handle errors from
1852 	 * PQendcopy reasonably).  Note that the app can still obtain the error
1853 	 * status from the PGconn object.
1854 	 */
1855 	if (conn->errorMessage.len > 0)
1856 	{
1857 		/* We have to strip the trailing newline ... pain in neck... */
1858 		char		svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
1859 
1860 		if (svLast == '\n')
1861 			conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
1862 		pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data);
1863 		conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
1864 	}
1865 
1866 	PQclear(result);
1867 
1868 	return 1;
1869 }
1870 
1871 
1872 /*
1873  * PQfn - Send a function call to the POSTGRES backend.
1874  *
1875  * See fe-exec.c for documentation.
1876  */
1877 PGresult *
pqFunctionCall3(PGconn * conn,Oid fnid,int * result_buf,int * actual_result_len,int result_is_int,const PQArgBlock * args,int nargs)1878 pqFunctionCall3(PGconn *conn, Oid fnid,
1879 				int *result_buf, int *actual_result_len,
1880 				int result_is_int,
1881 				const PQArgBlock *args, int nargs)
1882 {
1883 	bool		needInput = false;
1884 	ExecStatusType status = PGRES_FATAL_ERROR;
1885 	char		id;
1886 	int			msgLength;
1887 	int			avail;
1888 	int			i;
1889 
1890 	/* PQfn already validated connection state */
1891 
1892 	if (pqPutMsgStart('F', false, conn) < 0 ||	/* function call msg */
1893 		pqPutInt(fnid, 4, conn) < 0 ||	/* function id */
1894 		pqPutInt(1, 2, conn) < 0 ||		/* # of format codes */
1895 		pqPutInt(1, 2, conn) < 0 ||		/* format code: BINARY */
1896 		pqPutInt(nargs, 2, conn) < 0)	/* # of args */
1897 	{
1898 		pqHandleSendFailure(conn);
1899 		return NULL;
1900 	}
1901 
1902 	for (i = 0; i < nargs; ++i)
1903 	{							/* len.int4 + contents	   */
1904 		if (pqPutInt(args[i].len, 4, conn))
1905 		{
1906 			pqHandleSendFailure(conn);
1907 			return NULL;
1908 		}
1909 		if (args[i].len == -1)
1910 			continue;			/* it's NULL */
1911 
1912 		if (args[i].isint)
1913 		{
1914 			if (pqPutInt(args[i].u.integer, args[i].len, conn))
1915 			{
1916 				pqHandleSendFailure(conn);
1917 				return NULL;
1918 			}
1919 		}
1920 		else
1921 		{
1922 			if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
1923 			{
1924 				pqHandleSendFailure(conn);
1925 				return NULL;
1926 			}
1927 		}
1928 	}
1929 
1930 	if (pqPutInt(1, 2, conn) < 0)		/* result format code: BINARY */
1931 	{
1932 		pqHandleSendFailure(conn);
1933 		return NULL;
1934 	}
1935 
1936 	if (pqPutMsgEnd(conn) < 0 ||
1937 		pqFlush(conn))
1938 	{
1939 		pqHandleSendFailure(conn);
1940 		return NULL;
1941 	}
1942 
1943 	for (;;)
1944 	{
1945 		if (needInput)
1946 		{
1947 			/* Wait for some data to arrive (or for the channel to close) */
1948 			if (pqWait(TRUE, FALSE, conn) ||
1949 				pqReadData(conn) < 0)
1950 				break;
1951 		}
1952 
1953 		/*
1954 		 * Scan the message. If we run out of data, loop around to try again.
1955 		 */
1956 		needInput = true;
1957 
1958 		conn->inCursor = conn->inStart;
1959 		if (pqGetc(&id, conn))
1960 			continue;
1961 		if (pqGetInt(&msgLength, 4, conn))
1962 			continue;
1963 
1964 		/*
1965 		 * Try to validate message type/length here.  A length less than 4 is
1966 		 * definitely broken.  Large lengths should only be believed for a few
1967 		 * message types.
1968 		 */
1969 		if (msgLength < 4)
1970 		{
1971 			handleSyncLoss(conn, id, msgLength);
1972 			break;
1973 		}
1974 		if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
1975 		{
1976 			handleSyncLoss(conn, id, msgLength);
1977 			break;
1978 		}
1979 
1980 		/*
1981 		 * Can't process if message body isn't all here yet.
1982 		 */
1983 		msgLength -= 4;
1984 		avail = conn->inEnd - conn->inCursor;
1985 		if (avail < msgLength)
1986 		{
1987 			/*
1988 			 * Before looping, enlarge the input buffer if needed to hold the
1989 			 * whole message.  See notes in parseInput.
1990 			 */
1991 			if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
1992 									 conn))
1993 			{
1994 				/*
1995 				 * XXX add some better recovery code... plan is to skip over
1996 				 * the message using its length, then report an error. For the
1997 				 * moment, just treat this like loss of sync (which indeed it
1998 				 * might be!)
1999 				 */
2000 				handleSyncLoss(conn, id, msgLength);
2001 				break;
2002 			}
2003 			continue;
2004 		}
2005 
2006 		/*
2007 		 * We should see V or E response to the command, but might get N
2008 		 * and/or A notices first. We also need to swallow the final Z before
2009 		 * returning.
2010 		 */
2011 		switch (id)
2012 		{
2013 			case 'V':			/* function result */
2014 				if (pqGetInt(actual_result_len, 4, conn))
2015 					continue;
2016 				if (*actual_result_len != -1)
2017 				{
2018 					if (result_is_int)
2019 					{
2020 						if (pqGetInt(result_buf, *actual_result_len, conn))
2021 							continue;
2022 					}
2023 					else
2024 					{
2025 						if (pqGetnchar((char *) result_buf,
2026 									   *actual_result_len,
2027 									   conn))
2028 							continue;
2029 					}
2030 				}
2031 				/* correctly finished function result message */
2032 				status = PGRES_COMMAND_OK;
2033 				break;
2034 			case 'E':			/* error return */
2035 				if (pqGetErrorNotice3(conn, true))
2036 					continue;
2037 				status = PGRES_FATAL_ERROR;
2038 				break;
2039 			case 'A':			/* notify message */
2040 				/* handle notify and go back to processing return values */
2041 				if (getNotify(conn))
2042 					continue;
2043 				break;
2044 			case 'N':			/* notice */
2045 				/* handle notice and go back to processing return values */
2046 				if (pqGetErrorNotice3(conn, false))
2047 					continue;
2048 				break;
2049 			case 'Z':			/* backend is ready for new query */
2050 				if (getReadyForQuery(conn))
2051 					continue;
2052 				/* consume the message and exit */
2053 				conn->inStart += 5 + msgLength;
2054 				/* if we saved a result object (probably an error), use it */
2055 				if (conn->result)
2056 					return pqPrepareAsyncResult(conn);
2057 				return PQmakeEmptyPGresult(conn, status);
2058 			case 'S':			/* parameter status */
2059 				if (getParameterStatus(conn))
2060 					continue;
2061 				break;
2062 			default:
2063 				/* The backend violates the protocol. */
2064 				printfPQExpBuffer(&conn->errorMessage,
2065 								  libpq_gettext("protocol error: id=0x%x\n"),
2066 								  id);
2067 				pqSaveErrorResult(conn);
2068 				/* trust the specified message length as what to skip */
2069 				conn->inStart += 5 + msgLength;
2070 				return pqPrepareAsyncResult(conn);
2071 		}
2072 		/* Completed this message, keep going */
2073 		/* trust the specified message length as what to skip */
2074 		conn->inStart += 5 + msgLength;
2075 		needInput = false;
2076 	}
2077 
2078 	/*
2079 	 * We fall out of the loop only upon failing to read data.
2080 	 * conn->errorMessage has been set by pqWait or pqReadData. We want to
2081 	 * append it to any already-received error message.
2082 	 */
2083 	pqSaveErrorResult(conn);
2084 	return pqPrepareAsyncResult(conn);
2085 }
2086 
2087 
2088 /*
2089  * Construct startup packet
2090  *
2091  * Returns a malloc'd packet buffer, or NULL if out of memory
2092  */
2093 char *
pqBuildStartupPacket3(PGconn * conn,int * packetlen,const PQEnvironmentOption * options)2094 pqBuildStartupPacket3(PGconn *conn, int *packetlen,
2095 					  const PQEnvironmentOption *options)
2096 {
2097 	char	   *startpacket;
2098 
2099 	*packetlen = build_startup_packet(conn, NULL, options);
2100 	startpacket = (char *) malloc(*packetlen);
2101 	if (!startpacket)
2102 		return NULL;
2103 	*packetlen = build_startup_packet(conn, startpacket, options);
2104 	return startpacket;
2105 }
2106 
2107 /*
2108  * Build a startup packet given a filled-in PGconn structure.
2109  *
2110  * We need to figure out how much space is needed, then fill it in.
2111  * To avoid duplicate logic, this routine is called twice: the first time
2112  * (with packet == NULL) just counts the space needed, the second time
2113  * (with packet == allocated space) fills it in.  Return value is the number
2114  * of bytes used.
2115  */
2116 static int
build_startup_packet(const PGconn * conn,char * packet,const PQEnvironmentOption * options)2117 build_startup_packet(const PGconn *conn, char *packet,
2118 					 const PQEnvironmentOption *options)
2119 {
2120 	int			packet_len = 0;
2121 	const PQEnvironmentOption *next_eo;
2122 	const char *val;
2123 
2124 	/* Protocol version comes first. */
2125 	if (packet)
2126 	{
2127 		ProtocolVersion pv = htonl(conn->pversion);
2128 
2129 		memcpy(packet + packet_len, &pv, sizeof(ProtocolVersion));
2130 	}
2131 	packet_len += sizeof(ProtocolVersion);
2132 
2133 	/* Add user name, database name, options */
2134 
2135 #define ADD_STARTUP_OPTION(optname, optval) \
2136 	do { \
2137 		if (packet) \
2138 			strcpy(packet + packet_len, optname); \
2139 		packet_len += strlen(optname) + 1; \
2140 		if (packet) \
2141 			strcpy(packet + packet_len, optval); \
2142 		packet_len += strlen(optval) + 1; \
2143 	} while(0)
2144 
2145 	if (conn->pguser && conn->pguser[0])
2146 		ADD_STARTUP_OPTION("user", conn->pguser);
2147 	if (conn->dbName && conn->dbName[0])
2148 		ADD_STARTUP_OPTION("database", conn->dbName);
2149 	if (conn->replication && conn->replication[0])
2150 		ADD_STARTUP_OPTION("replication", conn->replication);
2151 	if (conn->pgoptions && conn->pgoptions[0])
2152 		ADD_STARTUP_OPTION("options", conn->pgoptions);
2153 	if (conn->send_appname)
2154 	{
2155 		/* Use appname if present, otherwise use fallback */
2156 		val = conn->appname ? conn->appname : conn->fbappname;
2157 		if (val && val[0])
2158 			ADD_STARTUP_OPTION("application_name", val);
2159 	}
2160 
2161 	if (conn->client_encoding_initial && conn->client_encoding_initial[0])
2162 		ADD_STARTUP_OPTION("client_encoding", conn->client_encoding_initial);
2163 
2164 	/* Add any environment-driven GUC settings needed */
2165 	for (next_eo = options; next_eo->envName; next_eo++)
2166 	{
2167 		if ((val = getenv(next_eo->envName)) != NULL)
2168 		{
2169 			if (pg_strcasecmp(val, "default") != 0)
2170 				ADD_STARTUP_OPTION(next_eo->pgName, val);
2171 		}
2172 	}
2173 
2174 	/* Add trailing terminator */
2175 	if (packet)
2176 		packet[packet_len] = '\0';
2177 	packet_len++;
2178 
2179 	return packet_len;
2180 }
2181