Skip to content

Commit bc10219

Browse files
committed
Make pg_interpret_timezone_abbrev() check sp->defaulttype too.
This omission caused it to not recognize the furthest-back zone abbreviation when working with timezone data compiled with relatively recent zic (2018f or newer). Older versions of zic produced a dummy DST transition at the Big Bang, so that the oldest abbreviation could always be found in the sp->types[] array; but newer versions don't do that, so that we must examine defaulttype as well as the types[] array to be sure of seeing all the abbreviations. While this has been broken for six or so years, we'd managed not to notice for two reasons: (1) many platforms are still using ancient zic for compatibility reasons, so that the issue did not manifest in builds using --with-system-tzdata; (2) the oldest zone abbreviation is almost always "LMT", which we weren't supporting anyway (but an upcoming patch will accept that). While at it, update pg_next_dst_boundary() to use sp->defaulttype as the time type for non-DST zones and times before the oldest DST transition. The existing code there predates upstream's invention of the sp->defaulttype field, and its heuristic for finding the oldest time type has now been subsumed into the code that sets sp->defaulttype. Possibly this should be back-patched, but I'm not currently aware of any visible consequences of this bug in released branches. Per report from Aleksander Alekseev and additional investigation. Discussion: https://postgr.es/m/CAJ7c6TOATjJqvhnYsui0=CO5XFMF4dvTGH+skzB--jNhqSQu5g@mail.gmail.com
1 parent 901bd4a commit bc10219

File tree

1 file changed

+20
-20
lines changed

1 file changed

+20
-20
lines changed

src/timezone/localtime.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,15 +1624,8 @@ pg_next_dst_boundary(const pg_time_t *timep,
16241624
sp = &tz->state;
16251625
if (sp->timecnt == 0)
16261626
{
1627-
/* non-DST zone, use lowest-numbered standard type */
1628-
i = 0;
1629-
while (sp->ttis[i].tt_isdst)
1630-
if (++i >= sp->typecnt)
1631-
{
1632-
i = 0;
1633-
break;
1634-
}
1635-
ttisp = &sp->ttis[i];
1627+
/* non-DST zone, use the defaulttype */
1628+
ttisp = &sp->ttis[sp->defaulttype];
16361629
*before_gmtoff = ttisp->tt_utoff;
16371630
*before_isdst = ttisp->tt_isdst;
16381631
return 0;
@@ -1692,15 +1685,8 @@ pg_next_dst_boundary(const pg_time_t *timep,
16921685
}
16931686
if (t < sp->ats[0])
16941687
{
1695-
/* For "before", use lowest-numbered standard type */
1696-
i = 0;
1697-
while (sp->ttis[i].tt_isdst)
1698-
if (++i >= sp->typecnt)
1699-
{
1700-
i = 0;
1701-
break;
1702-
}
1703-
ttisp = &sp->ttis[i];
1688+
/* For "before", use the defaulttype */
1689+
ttisp = &sp->ttis[sp->defaulttype];
17041690
*before_gmtoff = ttisp->tt_utoff;
17051691
*before_isdst = ttisp->tt_isdst;
17061692
*boundary = sp->ats[0];
@@ -1793,7 +1779,9 @@ pg_interpret_timezone_abbrev(const char *abbrev,
17931779
* abbreviation should get us what we want, since extrapolation would just
17941780
* be repeating the newest or oldest meanings.
17951781
*
1796-
* Use binary search to locate the first transition > cutoff time.
1782+
* Use binary search to locate the first transition > cutoff time. (Note
1783+
* that sp->timecnt could be zero, in which case this loop does nothing
1784+
* and only the defaulttype entry will be checked.)
17971785
*/
17981786
{
17991787
int lo = 0;
@@ -1827,7 +1815,19 @@ pg_interpret_timezone_abbrev(const char *abbrev,
18271815
}
18281816

18291817
/*
1830-
* Not there, so scan forwards to find the first one after.
1818+
* Not found yet; check the defaulttype, which is notionally the era
1819+
* before any of the entries in sp->types[].
1820+
*/
1821+
ttisp = &sp->ttis[sp->defaulttype];
1822+
if (ttisp->tt_desigidx == abbrind)
1823+
{
1824+
*gmtoff = ttisp->tt_utoff;
1825+
*isdst = ttisp->tt_isdst;
1826+
return true;
1827+
}
1828+
1829+
/*
1830+
* Not there, so scan forwards to find the first one after the cutoff.
18311831
*/
18321832
for (i = cutoff; i < sp->timecnt; i++)
18331833
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy