Re: BUG #5697: Infinite loop inside PQexecStart function

From: Boris Bondarenko <bbondarenko(at)nyc(dot)yamaha(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Boris <admin(at)nyc(dot)yamaha(dot)com>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #5697: Infinite loop inside PQexecStart function
Date: 2010-10-07 15:51:36
Message-ID: 4CADEC88.9040308@nyc.yamaha.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

That was a short form i used to point out the issue, the actual code
from src/interfaces/libpq/fe-exec.c

1368 static bool
1369 PQexecStart(PGconn *conn)
1370 {
1371 PGresult *result;
1372
1373 if (!conn)
1374 return false;
1375
1376 /*
1377 * Silently discard any prior query result that
application didn't eat.
1378 * This is probably poor design, but it's here for
backward compatibility.
1379 */
1380 while ((result = PQgetResult(conn)) != NULL)
1381 {
1382 ExecStatusType resultStatus = result->resultStatus;
1383
1384 PQclear(result); /* only need
its status */
1385 if (resultStatus == PGRES_COPY_IN)
1386 {
1387 if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
1388 {
1389 /* In protocol 3, we can get
out of a COPY IN state */
1390 if (PQputCopyEnd(conn,
1391
libpq_gettext("COPY terminated by new PQexec")) < 0)
1392 return false;
1393 /* keep waiting to swallow the
copy's failure message */
1394 }
1395 else
1396 {
1397 /* In older protocols we have
to punt */
1398
printfPQExpBuffer(&conn->errorMessage,
1399 libpq_gettext("COPY IN state
must be terminated first\n"));
1400 return false;
1401 }
1402 }
1403 else if (resultStatus == PGRES_COPY_OUT)
1404 {
1405 if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
1406 {
1407 /*
1408 * In protocol 3, we can get
out of a COPY OUT state: we just
1409 * switch back to BUSY and
allow the remaining COPY data to be
1410 * dropped on the floor.
1411 */
1412 conn->asyncStatus = PGASYNC_BUSY;
1413 /* keep waiting to swallow the
copy's completion message */
1414 }
1415 else
1416 {
1417 /* In older protocols we have
to punt */
1418
printfPQExpBuffer(&conn->errorMessage,
1419 libpq_gettext("COPY OUT state
must be terminated first\n"));
1420 return false;
1421 }
1422 }
1423 /* check for loss of connection, too */
1424 if (conn->status == CONNECTION_BAD)
1425 return false;
1426 }
1427
1428 /* OK to send a command */
1429 return true;
1430 }

Sorry for the confusion from the shortened form.

Tom Lane wrote:
> "Boris" <admin(at)nyc(dot)yamaha(dot)com> writes:
>> while ((result = PQgetResult(conn)) != NULL){
>> ExecStatusType resultStatus = result->resultStatus;
>> PQclear(result); /* only need its status */
>> /* check for loss of connection, too */
>> if (result->resultStatus == PGRES_COPY_IN ||
>> result->resultStatus == PGRES_COPY_OUT ||
>> conn->status == CONNECTION_BAD)
>> break;
>> }
>
> This code is broken: once you've done PQclear() it's unsafe to access
> the PGresult. I think you meant just "resultStatus" not
> "result->resultStatus" in the if().
>
> regards, tom lane
>

--
Boris Bondarenko -:- bbondarenko(at)nyc(dot)yamaha(dot)com
Yamaha Music Interactive Inc.

YMIA

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2010-10-07 15:58:08 Re: BUG #5697: Infinite loop inside PQexecStart function
Previous Message Tom Lane 2010-10-07 15:44:26 Re: BUG #5697: Infinite loop inside PQexecStart function