postgres.git / summary / log / commit / refs

commit    6c4ffab76320d492cfd262efdef1776c50787176
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Fri Jul 26 16:45:32 2019 +0000
First released in: 13.0, 9.4.24, 9.5.19, 9.6.15, 10.10, 11.5, 12.0

    Avoid choosing "localtime" or "posixrules" as TimeZone during initdb.
    
    Some platforms create a file named "localtime" in the system
    timezone directory, making it a copy or link to the active time
    zone file.  If Postgres is built with --with-system-tzdata, initdb
    will see that file as an exact match to localtime(3)'s behavior,
    and it may decide that "localtime" is the most preferred spelling of
    the active zone.  That's a very bad choice though, because it's
    neither informative, nor portable, nor stable if someone changes
    the system timezone setting.  Extend the preference logic added by
    commit e3846a00c so that we will prefer any other zone file that
    matches localtime's behavior over "localtime".
    
    On the same logic, also discriminate against "posixrules", which
    is another not-really-a-zone file that is often present in the
    timezone directory.  (Since we install "posixrules" but not
    "localtime", this change can affect the behavior of Postgres
    with or without --with-system-tzdata.)
    
    Note that this change doesn't prevent anyone from choosing these
    pseudo-zones if they really want to (i.e., by setting TZ for initdb,
    or modifying the timezone GUC later on).  It just prevents initdb
    from preferring these zone names when there are multiple matches to
    localtime's behavior.
    
    Since we generally prefer to keep timezone-related behavior the
    same in all branches, and since this is arguably a bug fix,
    back-patch to all supported branches.
    
    Discussion: https://postgr.es/m/CADT4RqCCnj6FKLisvT8tTPfTP4azPhhDFJqDF1JfBbOH5w4oyQ@mail.gmail.com
    Discussion: https://postgr.es/m/27991.1560984458@sss.pgh.pa.us


src/bin/initdb/findtimezone.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/bin/initdb/findtimezone.c b/src/bin/initdb/findtimezone.c index 420906e676c..ebb2992c2a4 100644 --- a/src/bin/initdb/findtimezone.c +++ b/src/bin/initdb/findtimezone.c @@ -608,22 +608,28 @@ check_system_link_file(const char *linkname, struct tztry *tt, /* * Given a timezone name, determine whether it should be preferred over other * names which are equally good matches. The output is arbitrary but we will - * use 0 for "neutral" default preference. - * - * Ideally we'd prefer the zone.tab/zone1970.tab names, since in general those - * are the ones offered to the user to select from. But for the moment, to - * minimize changes in behaviour, simply prefer UTC over alternative spellings - * such as UCT that otherwise cause confusion. The existing "shortest first" - * rule would prefer "UTC" over "Etc/UTC" so keep that the same way (while - * still preferring Etc/UTC over Etc/UCT). + * use 0 for "neutral" default preference; larger values are more preferred. */ static int zone_name_pref(const char *zonename) { + /* + * Prefer UTC over alternatives such as UCT. Also prefer Etc/UTC over + * Etc/UCT; but UTC is preferred to Etc/UTC. + */ if (strcmp(zonename, "UTC") == 0) return 50; if (strcmp(zonename, "Etc/UTC") == 0) return 40; + + /* + * We don't want to pick "localtime" or "posixrules", unless we can find + * no other name for the prevailing zone. Those aren't real zone names. + */ + if (strcmp(zonename, "localtime") == 0 || + strcmp(zonename, "posixrules") == 0) + return -50; + return 0; } [parent: 81b29c87114c]