Avoid null pointer dereference if error result lacks SQLSTATE.

Although error results received from the backend should always have
a SQLSTATE field, ones generated by libpq won't, making this code
vulnerable to a crash after, say, untimely loss of connection.
Noted by Coverity.

Oversight in commit 403a3d91c.  Back-patch to 9.5, as that was.
This commit is contained in:
Tom Lane 2020-11-01 11:26:16 -05:00
parent bb62df46bc
commit 0041941f5b

View File

@ -541,9 +541,9 @@ bool
IsLockTableGeneric(Archive *AHX) IsLockTableGeneric(Archive *AHX)
{ {
ArchiveHandle *AH = (ArchiveHandle *) AHX; ArchiveHandle *AH = (ArchiveHandle *) AHX;
PGresult *res; PGresult *res;
char *sqlstate; char *sqlstate;
bool retval; bool retval;
if (AHX->remoteVersion >= 140000) if (AHX->remoteVersion >= 140000)
return true; return true;
@ -570,13 +570,15 @@ IsLockTableGeneric(Archive *AHX)
break; break;
case PGRES_FATAL_ERROR: case PGRES_FATAL_ERROR:
sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE); sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
if (strcmp(sqlstate, ERRCODE_WRONG_OBJECT_TYPE) == 0) if (sqlstate &&
strcmp(sqlstate, ERRCODE_WRONG_OBJECT_TYPE) == 0)
{ {
retval = false; retval = false;
break; break;
} }
else if (strcmp(sqlstate, ERRCODE_LOCK_NOT_AVAILABLE) == 0 || else if (sqlstate &&
strcmp(sqlstate, ERRCODE_INSUFFICIENT_PRIVILEGE) == 0) (strcmp(sqlstate, ERRCODE_LOCK_NOT_AVAILABLE) == 0 ||
strcmp(sqlstate, ERRCODE_INSUFFICIENT_PRIVILEGE) == 0))
{ {
retval = true; retval = true;
break; break;