From: Tom Lane Date: Mon, 27 Oct 2014 00:59:21 +0000 (-0400) Subject: Avoid unportable strftime() behavior in pg_dump/pg_dumpall. X-Git-Tag: REL9_5_ALPHA1~1299 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f455fcfdb8ca3b67373223a4e15648c35e2592a9;p=postgresql Avoid unportable strftime() behavior in pg_dump/pg_dumpall. Commit ad5d46a4494b0b480a3af246bb4227d9bdadca37 thought that we could get around the known portability issues of strftime's %Z specifier by using %z instead. However, that idea seems to have been innocent of any actual research, as it certainly missed the facts that (1) %z is not portable to pre-C99 systems, and (2) %z doesn't actually act differently from %Z on Windows anyway. Per failures on buildfarm member hamerkop. While at it, centralize the code defining what strftime format we want to use in pg_dump; three copies of that string seems a bit much. --- diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h index 688e9ca6b8..aaf4074852 100644 --- a/src/bin/pg_dump/dumputils.h +++ b/src/bin/pg_dump/dumputils.h @@ -49,6 +49,23 @@ typedef struct SimpleStringList #define atooid(x) ((Oid) strtoul((x), NULL, 10)) +/* + * Preferred strftime(3) format specifier for printing timestamps in pg_dump + * and friends. + * + * We don't print the timezone on Windows, because the names are long and + * localized, which means they may contain characters in various random + * encodings; this has been seen to cause encoding errors when reading the + * dump script. Think not to get around that by using %z, because + * (1) %z is not portable to pre-C99 systems, and + * (2) %z doesn't actually act differently from %Z on Windows anyway. + */ +#ifndef WIN32 +#define PGDUMP_STRFTIME_FMT "%Y-%m-%d %H:%M:%S %Z" +#else +#define PGDUMP_STRFTIME_FMT "%Y-%m-%d %H:%M:%S" +#endif + extern int quote_all_identifiers; extern PQExpBuffer (*getLocalPQExpBuffer) (void); diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index ed28d36e13..1a2ebcb1f4 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -1047,14 +1047,16 @@ PrintTOCSummary(Archive *AHX, RestoreOptions *ropt) teSection curSection; OutputContext sav; const char *fmtName; - struct tm *tm = localtime(&AH->createDate); char stamp_str[64]; sav = SaveOutput(AH); if (ropt->filename) SetOutput(AH, ropt->filename, 0 /* no compression */ ); - strftime(stamp_str, sizeof(stamp_str), "%Y-%m-%d %H:%M:%S %z", tm); + if (strftime(stamp_str, sizeof(stamp_str), PGDUMP_STRFTIME_FMT, + localtime(&AH->createDate)) == 0) + strcpy(stamp_str, "[unknown]"); + ahprintf(AH, ";\n; Archive created at %s\n", stamp_str); ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n", AH->archdbname, AH->tocCount, AH->compression); @@ -3544,7 +3546,7 @@ dumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim) { char buf[64]; - if (strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime(&tim)) != 0) + if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0) ahprintf(AH, "-- %s %s\n\n", msg, buf); } diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index dc8de69db1..23cb0b4da7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -48,7 +48,7 @@ static void makeAlterConfigCommand(PGconn *conn, const char *arrayitem, const char *type, const char *name, const char *type2, const char *name2); static void dumpDatabases(PGconn *conn); -static void dumpTimestamp(char *msg); +static void dumpTimestamp(const char *msg); static void doShellQuoting(PQExpBuffer buf, const char *str); static void doConnStrQuoting(PQExpBuffer buf, const char *str); @@ -2058,12 +2058,12 @@ executeCommand(PGconn *conn, const char *query) * dumpTimestamp */ static void -dumpTimestamp(char *msg) +dumpTimestamp(const char *msg) { char buf[64]; time_t now = time(NULL); - if (strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime(&now)) != 0) + if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&now)) != 0) fprintf(OPF, "-- %s %s\n\n", msg, buf); }