Various Coverity-spotted fixes

A number of issues were identified by the Coverity scanner and are
addressed in this patch.  None of these appear to be security issues
and many are mostly cosmetic changes.

Short comments for each of the changes follows.

Correct the semi-colon placement in be-secure.c regarding SSL retries.
Remove a useless comparison-to-NULL in proc.c (value is dereferenced
  prior to this check and therefore can't be NULL).
Add checking of chmod() return values to initdb.
Fix a couple minor memory leaks in initdb.
Fix memory leak in pg_ctl- involves free'ing the config file contents.
Use an int to capture fgetc() return instead of an enum in pg_dump.
Fix minor memory leaks in pg_dump.
  (note minor change to convertOperatorReference()'s API)
Check fclose()/remove() return codes in psql.
Check fstat(), find_my_exec() return codes in psql.
Various ECPG memory leak fixes.
Check find_my_exec() return in ECPG.
Explicitly ignore pqFlush return in libpq error-path.
Change PQfnumber() to avoid doing an strdup() when no changes required.
Remove a few useless check-against-NULL's (value deref'd beforehand).
Check rmtree(), malloc() results in pg_regress.
Also check get_alternative_expectfile() return in pg_regress.
This commit is contained in:
Stephen Frost 2014-03-01 22:14:14 -05:00
parent 9662143f0c
commit b1aebbb6a8
16 changed files with 290 additions and 73 deletions

View File

@ -371,7 +371,7 @@ secure_write(Port *port, void *ptr, size_t len)
* A handshake can fail, so be prepared to retry it, but only * A handshake can fail, so be prepared to retry it, but only
* a few times. * a few times.
*/ */
for (retries = 0; retries++;) for (retries = 0;; retries++)
{ {
if (SSL_do_handshake(port->ssl) > 0) if (SSL_do_handshake(port->ssl) > 0)
break; /* done */ break; /* done */

View File

@ -1158,8 +1158,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
* Only do it if the worker is not working to protect against Xid * Only do it if the worker is not working to protect against Xid
* wraparound. * wraparound.
*/ */
if ((autovac != NULL) && if ((autovac_pgxact->vacuumFlags & PROC_IS_AUTOVACUUM) &&
(autovac_pgxact->vacuumFlags & PROC_IS_AUTOVACUUM) &&
!(autovac_pgxact->vacuumFlags & PROC_VACUUM_FOR_WRAPAROUND)) !(autovac_pgxact->vacuumFlags & PROC_VACUUM_FOR_WRAPAROUND))
{ {
int pid = autovac->pid; int pid = autovac->pid;

View File

@ -1293,7 +1293,12 @@ setup_config(void)
snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data); snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
writefile(path, conflines); writefile(path, conflines);
chmod(path, S_IRUSR | S_IWUSR); if (chmod(path, S_IRUSR | S_IWUSR) != 0)
{
fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
progname, path, strerror(errno));
exit_nicely();
}
/* /*
* create the automatic configuration file to store the configuration * create the automatic configuration file to store the configuration
@ -1308,7 +1313,12 @@ setup_config(void)
sprintf(path, "%s/%s", pg_data, PG_AUTOCONF_FILENAME); sprintf(path, "%s/%s", pg_data, PG_AUTOCONF_FILENAME);
writefile(path, autoconflines); writefile(path, autoconflines);
chmod(path, S_IRUSR | S_IWUSR); if (chmod(path, S_IRUSR | S_IWUSR) != 0)
{
fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
progname, path, strerror(errno));
exit_nicely();
}
free(conflines); free(conflines);
@ -1387,7 +1397,12 @@ setup_config(void)
snprintf(path, sizeof(path), "%s/pg_hba.conf", pg_data); snprintf(path, sizeof(path), "%s/pg_hba.conf", pg_data);
writefile(path, conflines); writefile(path, conflines);
chmod(path, S_IRUSR | S_IWUSR); if (chmod(path, S_IRUSR | S_IWUSR) != 0)
{
fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
progname, path, strerror(errno));
exit_nicely();
}
free(conflines); free(conflines);
@ -1398,7 +1413,12 @@ setup_config(void)
snprintf(path, sizeof(path), "%s/pg_ident.conf", pg_data); snprintf(path, sizeof(path), "%s/pg_ident.conf", pg_data);
writefile(path, conflines); writefile(path, conflines);
chmod(path, S_IRUSR | S_IWUSR); if (chmod(path, S_IRUSR | S_IWUSR) != 0)
{
fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
progname, path, strerror(errno));
exit_nicely();
}
free(conflines); free(conflines);
@ -1957,8 +1977,14 @@ setup_collation(void)
* only, so this doesn't clash with "en_US" for LATIN1, say. * only, so this doesn't clash with "en_US" for LATIN1, say.
*/ */
if (normalize_locale_name(alias, localebuf)) if (normalize_locale_name(alias, localebuf))
{
char *quoted_alias = escape_quotes(alias);
PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n", PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n",
escape_quotes(alias), quoted_locale, enc); quoted_alias, quoted_locale, enc);
free(quoted_alias);
}
free(quoted_locale);
} }
/* Add an SQL-standard name */ /* Add an SQL-standard name */

View File

@ -154,6 +154,7 @@ static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo,
static pgpid_t get_pgpid(void); static pgpid_t get_pgpid(void);
static char **readfile(const char *path); static char **readfile(const char *path);
static void free_readfile(char **optlines);
static int start_postmaster(void); static int start_postmaster(void);
static void read_post_opts(void); static void read_post_opts(void);
@ -369,6 +370,24 @@ readfile(const char *path)
} }
/*
* Free memory allocated for optlines through readfile()
*/
void
free_readfile(char **optlines)
{
int i = 0;
if (!optlines)
return;
while (optlines[i++])
free(optlines[i]);
free(optlines);
return;
}
/* /*
* start/test/stop routines * start/test/stop routines
@ -572,6 +591,13 @@ test_postmaster_connection(bool do_checkpoint)
} }
} }
} }
/*
* Free the results of readfile.
*
* This is safe to call even if optlines is NULL.
*/
free_readfile(optlines);
} }
/* If we have a connection string, ping the server */ /* If we have a connection string, ping the server */
@ -708,6 +734,9 @@ read_post_opts(void)
if (exec_path == NULL) if (exec_path == NULL)
exec_path = optline; exec_path = optline;
} }
/* Free the results of readfile. */
free_readfile(optlines);
} }
} }
} }
@ -1201,8 +1230,13 @@ do_status(void)
optlines = readfile(postopts_file); optlines = readfile(postopts_file);
if (optlines != NULL) if (optlines != NULL)
{
for (; *optlines != NULL; optlines++) for (; *optlines != NULL; optlines++)
fputs(*optlines, stdout); fputs(*optlines, stdout);
/* Free the results of readfile */
free_readfile(optlines);
}
return; return;
} }
} }

View File

@ -1947,8 +1947,10 @@ _discoverArchiveFormat(ArchiveHandle *AH)
else else
AH->offSize = AH->intSize; AH->offSize = AH->intSize;
if ((AH->format = fgetc(fh)) == EOF) if ((byteread = fgetc(fh)) == EOF)
exit_horribly(modulename, "could not read input file: %s\n", strerror(errno)); exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
AH->format = byteread;
AH->lookahead[AH->lookaheadLen++] = AH->format; AH->lookahead[AH->lookaheadLen++] = AH->format;
} }
else else

View File

@ -234,9 +234,9 @@ static char *format_function_arguments_old(Archive *fout,
char **argnames); char **argnames);
static char *format_function_signature(Archive *fout, static char *format_function_signature(Archive *fout,
FuncInfo *finfo, bool honor_quotes); FuncInfo *finfo, bool honor_quotes);
static const char *convertRegProcReference(Archive *fout, static char *convertRegProcReference(Archive *fout,
const char *proc); const char *proc);
static const char *convertOperatorReference(Archive *fout, const char *opr); static char *convertOperatorReference(Archive *fout, const char *opr);
static const char *convertTSFunction(Archive *fout, Oid funcOid); static const char *convertTSFunction(Archive *fout, Oid funcOid);
static Oid findLastBuiltinOid_V71(Archive *fout, const char *); static Oid findLastBuiltinOid_V71(Archive *fout, const char *);
static Oid findLastBuiltinOid_V70(Archive *fout); static Oid findLastBuiltinOid_V70(Archive *fout);
@ -10246,6 +10246,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
char *oprjoin; char *oprjoin;
char *oprcanmerge; char *oprcanmerge;
char *oprcanhash; char *oprcanhash;
char *oprregproc;
char *oprref;
/* Skip if not to be dumped */ /* Skip if not to be dumped */
if (!oprinfo->dobj.dump || dataOnly) if (!oprinfo->dobj.dump || dataOnly)
@ -10352,8 +10354,12 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge); oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
oprcanhash = PQgetvalue(res, 0, i_oprcanhash); oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
appendPQExpBuffer(details, " PROCEDURE = %s", oprregproc = convertRegProcReference(fout, oprcode);
convertRegProcReference(fout, oprcode)); if (oprregproc)
{
appendPQExpBuffer(details, " PROCEDURE = %s", oprregproc);
free(oprregproc);
}
appendPQExpBuffer(oprid, "%s (", appendPQExpBuffer(oprid, "%s (",
oprinfo->dobj.name); oprinfo->dobj.name);
@ -10388,13 +10394,19 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
else else
appendPQExpBufferStr(oprid, ", NONE)"); appendPQExpBufferStr(oprid, ", NONE)");
name = convertOperatorReference(fout, oprcom); oprref = convertOperatorReference(fout, oprcom);
if (name) if (oprref)
appendPQExpBuffer(details, ",\n COMMUTATOR = %s", name); {
appendPQExpBuffer(details, ",\n COMMUTATOR = %s", oprref);
free(oprref);
}
name = convertOperatorReference(fout, oprnegate); oprref = convertOperatorReference(fout, oprnegate);
if (name) if (oprref)
appendPQExpBuffer(details, ",\n NEGATOR = %s", name); {
appendPQExpBuffer(details, ",\n NEGATOR = %s", oprref);
free(oprref);
}
if (strcmp(oprcanmerge, "t") == 0) if (strcmp(oprcanmerge, "t") == 0)
appendPQExpBufferStr(details, ",\n MERGES"); appendPQExpBufferStr(details, ",\n MERGES");
@ -10402,13 +10414,19 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
if (strcmp(oprcanhash, "t") == 0) if (strcmp(oprcanhash, "t") == 0)
appendPQExpBufferStr(details, ",\n HASHES"); appendPQExpBufferStr(details, ",\n HASHES");
name = convertRegProcReference(fout, oprrest); oprregproc = convertRegProcReference(fout, oprrest);
if (name) if (oprregproc)
appendPQExpBuffer(details, ",\n RESTRICT = %s", name); {
appendPQExpBuffer(details, ",\n RESTRICT = %s", oprregproc);
free(oprregproc);
}
name = convertRegProcReference(fout, oprjoin); oprregproc = convertRegProcReference(fout, oprjoin);
if (name) if (oprregproc)
appendPQExpBuffer(details, ",\n JOIN = %s", name); {
appendPQExpBuffer(details, ",\n JOIN = %s", oprregproc);
free(oprregproc);
}
/* /*
* DROP must be fully qualified in case same name appears in pg_catalog * DROP must be fully qualified in case same name appears in pg_catalog
@ -10453,12 +10471,13 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
/* /*
* Convert a function reference obtained from pg_operator * Convert a function reference obtained from pg_operator
* *
* Returns what to print, or NULL if function references is InvalidOid * Returns allocated string of what to print, or NULL if function references
* is InvalidOid. Returned string is expected to be free'd by the caller.
* *
* In 7.3 the input is a REGPROCEDURE display; we have to strip the * In 7.3 the input is a REGPROCEDURE display; we have to strip the
* argument-types part. In prior versions, the input is a REGPROC display. * argument-types part. In prior versions, the input is a REGPROC display.
*/ */
static const char * static char *
convertRegProcReference(Archive *fout, const char *proc) convertRegProcReference(Archive *fout, const char *proc)
{ {
/* In all cases "-" means a null reference */ /* In all cases "-" means a null reference */
@ -10488,20 +10507,21 @@ convertRegProcReference(Archive *fout, const char *proc)
} }
/* REGPROC before 7.3 does not quote its result */ /* REGPROC before 7.3 does not quote its result */
return fmtId(proc); return pg_strdup(fmtId(proc));
} }
/* /*
* Convert an operator cross-reference obtained from pg_operator * Convert an operator cross-reference obtained from pg_operator
* *
* Returns what to print, or NULL to print nothing * Returns an allocated string of what to print, or NULL to print nothing.
* Caller is responsible for free'ing result string.
* *
* In 7.3 and up the input is a REGOPERATOR display; we have to strip the * In 7.3 and up the input is a REGOPERATOR display; we have to strip the
* argument-types part, and add OPERATOR() decoration if the name is * argument-types part, and add OPERATOR() decoration if the name is
* schema-qualified. In older versions, the input is just a numeric OID, * schema-qualified. In older versions, the input is just a numeric OID,
* which we search our operator list for. * which we search our operator list for.
*/ */
static const char * static char *
convertOperatorReference(Archive *fout, const char *opr) convertOperatorReference(Archive *fout, const char *opr)
{ {
OprInfo *oprInfo; OprInfo *oprInfo;
@ -10549,7 +10569,7 @@ convertOperatorReference(Archive *fout, const char *opr)
opr); opr);
return NULL; return NULL;
} }
return oprInfo->dobj.name; return pg_strdup(oprInfo->dobj.name);
} }
/* /*
@ -11522,6 +11542,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
const char *aggtransfn; const char *aggtransfn;
const char *aggfinalfn; const char *aggfinalfn;
const char *aggsortop; const char *aggsortop;
char *aggsortconvop;
bool hypothetical; bool hypothetical;
const char *aggtranstype; const char *aggtranstype;
const char *aggtransspace; const char *aggtransspace;
@ -11665,6 +11686,12 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
{ {
write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n", write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
aggsig); aggsig);
if (aggfullsig)
free(aggfullsig);
free(aggsig);
return; return;
} }
@ -11709,11 +11736,12 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
aggfinalfn); aggfinalfn);
} }
aggsortop = convertOperatorReference(fout, aggsortop); aggsortconvop = convertOperatorReference(fout, aggsortop);
if (aggsortop) if (aggsortconvop)
{ {
appendPQExpBuffer(details, ",\n SORTOP = %s", appendPQExpBuffer(details, ",\n SORTOP = %s",
aggsortop); aggsortconvop);
free(aggsortconvop);
} }
if (hypothetical) if (hypothetical)
@ -12413,6 +12441,7 @@ dumpUserMappings(Archive *fout,
destroyPQExpBuffer(query); destroyPQExpBuffer(query);
destroyPQExpBuffer(delq); destroyPQExpBuffer(delq);
destroyPQExpBuffer(tag);
destroyPQExpBuffer(q); destroyPQExpBuffer(q);
} }

View File

@ -2027,14 +2027,20 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf,
if (fwrite(query_buf->data, 1, ql, stream) != ql) if (fwrite(query_buf->data, 1, ql, stream) != ql)
{ {
psql_error("%s: %s\n", fname, strerror(errno)); psql_error("%s: %s\n", fname, strerror(errno));
fclose(stream);
remove(fname); if (fclose(stream) != 0)
psql_error("%s: %s\n", fname, strerror(errno));
if (remove(fname) != 0)
psql_error("%s: %s\n", fname, strerror(errno));
error = true; error = true;
} }
else if (fclose(stream) != 0) else if (fclose(stream) != 0)
{ {
psql_error("%s: %s\n", fname, strerror(errno)); psql_error("%s: %s\n", fname, strerror(errno));
remove(fname); if (remove(fname) != 0)
psql_error("%s: %s\n", fname, strerror(errno));
error = true; error = true;
} }
} }

View File

@ -345,13 +345,20 @@ do_copy(const char *args)
if (!options->program) if (!options->program)
{ {
int result;
/* make sure the specified file is not a directory */ /* make sure the specified file is not a directory */
fstat(fileno(copystream), &st); if ((result = fstat(fileno(copystream), &st)) < 0)
if (S_ISDIR(st.st_mode)) psql_error("could not stat file: %s\n",
{ strerror(errno));
fclose(copystream);
if (result == 0 && S_ISDIR(st.st_mode))
psql_error("%s: cannot copy from/to a directory\n", psql_error("%s: cannot copy from/to a directory\n",
options->file); options->file);
if (result < 0 || S_ISDIR(st.st_mode))
{
fclose(copystream);
free_copy_options(options); free_copy_options(options);
return false; return false;
} }

View File

@ -603,7 +603,12 @@ process_psqlrc(char *argv0)
char etc_path[MAXPGPATH]; char etc_path[MAXPGPATH];
char *envrc = getenv("PSQLRC"); char *envrc = getenv("PSQLRC");
find_my_exec(argv0, my_exec_path); if (find_my_exec(argv0, my_exec_path) < 0)
{
fprintf(stderr, _("%s: could not find own program executable\n"), argv0);
exit(EXIT_FAILURE);
}
get_etc_path(my_exec_path, etc_path); get_etc_path(my_exec_path, etc_path);
snprintf(rc_file, MAXPGPATH, "%s/%s", etc_path, SYSPSQLRC); snprintf(rc_file, MAXPGPATH, "%s/%s", etc_path, SYSPSQLRC);

View File

@ -855,14 +855,22 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
for (element = 0; element < var->arrsize; element++) for (element = 0; element < var->arrsize; element++)
{ {
int result;
nval = PGTYPESnumeric_new(); nval = PGTYPESnumeric_new();
if (!nval) if (!nval)
return false; return false;
if (var->type == ECPGt_numeric) if (var->type == ECPGt_numeric)
PGTYPESnumeric_copy((numeric *) ((var + var->offset * element)->value), nval); result = PGTYPESnumeric_copy((numeric *) ((var + var->offset * element)->value), nval);
else else
PGTYPESnumeric_from_decimal((decimal *) ((var + var->offset * element)->value), nval); result = PGTYPESnumeric_from_decimal((decimal *) ((var + var->offset * element)->value), nval);
if (result != 0)
{
PGTYPESnumeric_free(nval);
return false;
}
str = PGTYPESnumeric_to_asc(nval, nval->dscale); str = PGTYPESnumeric_to_asc(nval, nval->dscale);
slen = strlen(str); slen = strlen(str);
@ -882,14 +890,22 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
} }
else else
{ {
int result;
nval = PGTYPESnumeric_new(); nval = PGTYPESnumeric_new();
if (!nval) if (!nval)
return false; return false;
if (var->type == ECPGt_numeric) if (var->type == ECPGt_numeric)
PGTYPESnumeric_copy((numeric *) (var->value), nval); result = PGTYPESnumeric_copy((numeric *) (var->value), nval);
else else
PGTYPESnumeric_from_decimal((decimal *) (var->value), nval); result = PGTYPESnumeric_from_decimal((decimal *) (var->value), nval);
if (result != 0)
{
PGTYPESnumeric_free(nval);
return false;
}
str = PGTYPESnumeric_to_asc(nval, nval->dscale); str = PGTYPESnumeric_to_asc(nval, nval->dscale);
slen = strlen(str); slen = strlen(str);
@ -1026,7 +1042,10 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
{ {
str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) ((var + var->offset * element)->value)), quote, lineno); str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) ((var + var->offset * element)->value)), quote, lineno);
if (!str) if (!str)
{
ecpg_free(mallocedval);
return false; return false;
}
slen = strlen(str); slen = strlen(str);

View File

@ -138,7 +138,11 @@ main(int argc, char *const argv[])
progname = get_progname(argv[0]); progname = get_progname(argv[0]);
find_my_exec(argv[0], my_exec_path); if (find_my_exec(argv[0], my_exec_path) < 0)
{
fprintf(stderr, _("%s: could not locate my own executable path\n"), argv[0]);
return (ILLEGAL_OPTION);
}
output_filename = NULL; output_filename = NULL;
while ((c = getopt_long(argc, argv, "vcio:I:tD:dC:r:h?", ecpg_options, NULL)) != -1) while ((c = getopt_long(argc, argv, "vcio:I:tD:dC:r:h?", ecpg_options, NULL)) != -1)

View File

@ -308,7 +308,11 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type, const int bra
if (ind_type != NULL) if (ind_type != NULL)
{ {
if (ind_type->type == ECPGt_NO_INDICATOR) if (ind_type->type == ECPGt_NO_INDICATOR)
ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, mm_strdup("-1"), NULL, ind_prefix, 0); {
char *str_neg_one = mm_strdup("-1");
ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, str_neg_one, NULL, ind_prefix, 0);
free(str_neg_one);
}
else else
{ {
ECPGdump_a_simple(o, ind_name, ind_type->u.element->type, ECPGdump_a_simple(o, ind_name, ind_type->u.element->type,
@ -318,37 +322,71 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type, const int bra
} }
break; break;
case ECPGt_struct: case ECPGt_struct:
if (indicator_set && ind_type->type != ECPGt_struct) {
mmfatal(INDICATOR_NOT_STRUCT, "indicator for struct has to be a struct"); char *str_one = mm_strdup("1");
ECPGdump_a_struct(o, name, ind_name, mm_strdup("1"), type, ind_type, prefix, ind_prefix); if (indicator_set && ind_type->type != ECPGt_struct)
mmfatal(INDICATOR_NOT_STRUCT, "indicator for struct has to be a struct");
ECPGdump_a_struct(o, name, ind_name, str_one, type, ind_type, prefix, ind_prefix);
free(str_one);
}
break; break;
case ECPGt_union: /* cannot dump a complete union */ case ECPGt_union: /* cannot dump a complete union */
base_yyerror("type of union has to be specified"); base_yyerror("type of union has to be specified");
break; break;
case ECPGt_char_variable: case ECPGt_char_variable:
if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array)) {
mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple"); /* Allocate for each, as there are code-paths where the values get stomped on. */
char *str_varchar_one = mm_strdup("1");
char *str_arr_one = mm_strdup("1");
char *str_neg_one = mm_strdup("-1");
ECPGdump_a_simple(o, name, type->type, mm_strdup("1"), (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : mm_strdup("1"), struct_sizeof, prefix, 0); if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
if (ind_type != NULL) mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple");
ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : mm_strdup("-1"), ind_struct_sizeof, ind_prefix, 0);
ECPGdump_a_simple(o, name, type->type, str_varchar_one, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : str_arr_one, struct_sizeof, prefix, 0);
if (ind_type != NULL)
ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : str_neg_one, ind_struct_sizeof, ind_prefix, 0);
free(str_varchar_one);
free(str_arr_one);
free(str_neg_one);
}
break; break;
case ECPGt_descriptor: case ECPGt_descriptor:
if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array)) {
mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple"); /* Allocate for each, as there are code-paths where the values get stomped on. */
char *str_neg_one = mm_strdup("-1");
char *ind_type_neg_one = mm_strdup("-1");
ECPGdump_a_simple(o, name, type->type, NULL, mm_strdup("-1"), NULL, prefix, 0); if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
if (ind_type != NULL) mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple");
ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, mm_strdup("-1"), NULL, ind_prefix, 0);
ECPGdump_a_simple(o, name, type->type, NULL, str_neg_one, NULL, prefix, 0);
if (ind_type != NULL)
ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, ind_type_neg_one, NULL, ind_prefix, 0);
free(str_neg_one);
free(ind_type_neg_one);
}
break; break;
default: default:
if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array)) {
mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple"); /* Allocate for each, as there are code-paths where the values get stomped on. */
char *str_neg_one = mm_strdup("-1");
char *ind_type_neg_one = mm_strdup("-1");
ECPGdump_a_simple(o, name, type->type, type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : mm_strdup("-1"), struct_sizeof, prefix, type->counter); if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
if (ind_type != NULL) mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple");
ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : mm_strdup("-1"), ind_struct_sizeof, ind_prefix, 0);
ECPGdump_a_simple(o, name, type->type, type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : str_neg_one, struct_sizeof, prefix, type->counter);
if (ind_type != NULL)
ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_siz && strcmp(arr_str_siz, "0") != 0) ? arr_str_siz : ind_type_neg_one, ind_struct_sizeof, ind_prefix, 0);
free(str_neg_one);
free(ind_type_neg_one);
}
break; break;
} }
} }

View File

@ -437,6 +437,7 @@ remove_variable_from_list(struct arguments ** list, struct variable * var)
void void
dump_variables(struct arguments * list, int mode) dump_variables(struct arguments * list, int mode)
{ {
char *str_zero = mm_strdup("0");
if (list == NULL) if (list == NULL)
return; return;
@ -450,11 +451,13 @@ dump_variables(struct arguments * list, int mode)
/* Then the current element and its indicator */ /* Then the current element and its indicator */
ECPGdump_a_type(yyout, list->variable->name, list->variable->type, list->variable->brace_level, ECPGdump_a_type(yyout, list->variable->name, list->variable->type, list->variable->brace_level,
list->indicator->name, list->indicator->type, list->indicator->brace_level, list->indicator->name, list->indicator->type, list->indicator->brace_level,
NULL, NULL, mm_strdup("0"), NULL, NULL); NULL, NULL, str_zero, NULL, NULL);
/* Then release the list element. */ /* Then release the list element. */
if (mode != 0) if (mode != 0)
free(list); free(list);
free(str_zero);
} }
void void

View File

@ -2876,7 +2876,7 @@ closePGconn(PGconn *conn)
*/ */
pqPutMsgStart('X', false, conn); pqPutMsgStart('X', false, conn);
pqPutMsgEnd(conn); pqPutMsgEnd(conn);
pqFlush(conn); (void) pqFlush(conn);
} }
/* /*

View File

@ -2724,7 +2724,8 @@ PQfnumber(const PGresult *res, const char *field_name)
{ {
char *field_case; char *field_case;
bool in_quotes; bool in_quotes;
char *iptr; bool all_lower = true;
const char *iptr;
char *optr; char *optr;
int i; int i;
@ -2740,6 +2741,28 @@ PQfnumber(const PGresult *res, const char *field_name)
res->attDescs == NULL) res->attDescs == NULL)
return -1; return -1;
/*
* Check if we can avoid the strdup() and related work because the
* passed-in string wouldn't be changed before we do the check anyway.
*/
for (iptr = field_name; *iptr; iptr++)
{
char c = *iptr;
if (c == '"' || c != pg_tolower((unsigned char) c))
{
all_lower = false;
break;
}
}
if (all_lower)
for (i = 0; i < res->numAttributes; i++)
if (strcmp(field_name, res->attDescs[i].name) == 0)
return i;
/* Fall through to the normal check if that didn't work out. */
/* /*
* Note: this code will not reject partially quoted strings, eg * Note: this code will not reject partially quoted strings, eg
* foo"BAR"foo will become fooBARfoo when it probably ought to be an error * foo"BAR"foo will become fooBARfoo when it probably ought to be an error
@ -2883,7 +2906,7 @@ PQoidStatus(const PGresult *res)
size_t len; size_t len;
if (!res || !res->cmdStatus || strncmp(res->cmdStatus, "INSERT ", 7) != 0) if (!res || strncmp(res->cmdStatus, "INSERT ", 7) != 0)
return ""; return "";
len = strspn(res->cmdStatus + 7, "0123456789"); len = strspn(res->cmdStatus + 7, "0123456789");
@ -2907,7 +2930,6 @@ PQoidValue(const PGresult *res)
unsigned long result; unsigned long result;
if (!res || if (!res ||
!res->cmdStatus ||
strncmp(res->cmdStatus, "INSERT ", 7) != 0 || strncmp(res->cmdStatus, "INSERT ", 7) != 0 ||
res->cmdStatus[7] < '0' || res->cmdStatus[7] < '0' ||
res->cmdStatus[7] > '9') res->cmdStatus[7] > '9')

View File

@ -450,7 +450,12 @@ convert_sourcefiles_in(char *source_subdir, char *dest_dir, char *dest_subdir, c
* Windows. See pgsql-hackers discussion of 2008-01-18. * Windows. See pgsql-hackers discussion of 2008-01-18.
*/ */
if (directory_exists(testtablespace)) if (directory_exists(testtablespace))
rmtree(testtablespace, true); if (!rmtree(testtablespace, true))
{
fprintf(stderr, _("\n%s: could not remove test tablespace \"%s\": %s\n"),
progname, testtablespace, strerror(errno));
exit(2);
}
make_directory(testtablespace); make_directory(testtablespace);
#endif #endif
@ -1152,6 +1157,9 @@ get_alternative_expectfile(const char *expectfile, int i)
char *tmp = (char *) malloc(ssize); char *tmp = (char *) malloc(ssize);
char *s = (char *) malloc(ssize); char *s = (char *) malloc(ssize);
if (!tmp || !s)
return NULL;
strcpy(tmp, expectfile); strcpy(tmp, expectfile);
last_dot = strrchr(tmp, '.'); last_dot = strrchr(tmp, '.');
if (!last_dot) if (!last_dot)
@ -1258,8 +1266,18 @@ results_differ(const char *testname, const char *resultsfile, const char *defaul
char *alt_expectfile; char *alt_expectfile;
alt_expectfile = get_alternative_expectfile(expectfile, i); alt_expectfile = get_alternative_expectfile(expectfile, i);
if (!alt_expectfile)
{
fprintf(stderr, _("Unable to check secondary comparison files: %s\n"),
strerror(errno));
exit(2);
}
if (!file_exists(alt_expectfile)) if (!file_exists(alt_expectfile))
{
free(alt_expectfile);
continue; continue;
}
snprintf(cmd, sizeof(cmd), snprintf(cmd, sizeof(cmd),
SYSTEMQUOTE "diff %s \"%s\" \"%s\" > \"%s\"" SYSTEMQUOTE, SYSTEMQUOTE "diff %s \"%s\" \"%s\" > \"%s\"" SYSTEMQUOTE,
@ -1268,6 +1286,7 @@ results_differ(const char *testname, const char *resultsfile, const char *defaul
if (run_diff(cmd, diff) == 0) if (run_diff(cmd, diff) == 0)
{ {
unlink(diff); unlink(diff);
free(alt_expectfile);
return false; return false;
} }
@ -2105,7 +2124,11 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc
if (directory_exists(temp_install)) if (directory_exists(temp_install))
{ {
header(_("removing existing temp installation")); header(_("removing existing temp installation"));
rmtree(temp_install, true); if (!rmtree(temp_install, true))
{
fprintf(stderr, _("\n%s: could not remove temp installation \"%s\": %s\n"), progname, temp_install, strerror(errno));
exit(2);
}
} }
header(_("creating temporary installation")); header(_("creating temporary installation"));