Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 12bfb77

Browse files
committed
Sync our copy of the timezone library with IANA release tzcode2018f.
About half of this is purely cosmetic changes to reduce the diff between our code and theirs, like inserting "const" markers where they have them. The other half is tracking actual code changes in zic.c and localtime.c. I don't think any of these represent near-term compatibility hazards, but it seems best to stay up to date. I also fixed longstanding bugs in our code for producing the known_abbrevs.txt list, which by chance hadn't been exposed before, but which resulted in some garbage output after applying the upstream changes in zic.c. Notably, because upstream removed their old phony transitions at the Big Bang, it's now necessary to cope with TZif files containing no DST transition times at all.
1 parent 13877d3 commit 12bfb77

File tree

7 files changed

+291
-197
lines changed

7 files changed

+291
-197
lines changed

src/timezone/README

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ match properly on the old version.
5555
Time Zone code
5656
==============
5757

58-
The code in this directory is currently synced with tzcode release 2018e.
58+
The code in this directory is currently synced with tzcode release 2018f.
5959
There are many cosmetic (and not so cosmetic) differences from the
6060
original tzcode library, but diffs in the upstream version should usually
6161
be propagated to our version. Here are some notes about that.

src/timezone/localtime.c

+87-39
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* Convert timestamp from pg_time_t to struct pg_tm. */
2+
13
/*
24
* This file is in the public domain, so clarified as of
35
* 1996-06-05 by Arthur David Olson.
@@ -117,7 +119,7 @@ init_ttinfo(struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
117119
}
118120

119121
static int32
120-
detzcode(const char *codep)
122+
detzcode(const char *const codep)
121123
{
122124
int32 result;
123125
int i;
@@ -143,7 +145,7 @@ detzcode(const char *codep)
143145
}
144146

145147
static int64
146-
detzcode64(const char *codep)
148+
detzcode64(const char *const codep)
147149
{
148150
uint64 result;
149151
int i;
@@ -258,8 +260,13 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
258260
int32 charcnt = detzcode(up->tzhead.tzh_charcnt);
259261
char const *p = up->buf + tzheadsize;
260262

263+
/*
264+
* Although tzfile(5) currently requires typecnt to be nonzero,
265+
* support future formats that may allow zero typecnt in files that
266+
* have a TZ string and no transitions.
267+
*/
261268
if (!(0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
262-
&& 0 < typecnt && typecnt < TZ_MAX_TYPES
269+
&& 0 <= typecnt && typecnt < TZ_MAX_TYPES
263270
&& 0 <= timecnt && timecnt < TZ_MAX_TIMES
264271
&& 0 <= charcnt && charcnt < TZ_MAX_CHARS
265272
&& (ttisstdcnt == typecnt || ttisstdcnt == 0)
@@ -416,8 +423,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
416423
struct state *ts = &lsp->u.st;
417424

418425
up->buf[nread - 1] = '\0';
419-
if (tzparse(&up->buf[1], ts, false)
420-
&& ts->typecnt == 2)
426+
if (tzparse(&up->buf[1], ts, false))
421427
{
422428
/*
423429
* Attempt to reuse existing abbreviations. Without this,
@@ -430,7 +436,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
430436
int gotabbr = 0;
431437
int charcnt = sp->charcnt;
432438

433-
for (i = 0; i < 2; i++)
439+
for (i = 0; i < ts->typecnt; i++)
434440
{
435441
char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
436442
int j;
@@ -455,7 +461,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
455461
}
456462
}
457463
}
458-
if (gotabbr == 2)
464+
if (gotabbr == ts->typecnt)
459465
{
460466
sp->charcnt = charcnt;
461467

@@ -470,7 +476,8 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
470476
sp->timecnt--;
471477

472478
for (i = 0; i < ts->timecnt; i++)
473-
if (sp->ats[sp->timecnt - 1] < ts->ats[i])
479+
if (sp->timecnt == 0
480+
|| sp->ats[sp->timecnt - 1] < ts->ats[i])
474481
break;
475482
while (i < ts->timecnt
476483
&& sp->timecnt < TZ_MAX_TIMES)
@@ -481,11 +488,13 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
481488
sp->timecnt++;
482489
i++;
483490
}
484-
sp->ttis[sp->typecnt++] = ts->ttis[0];
485-
sp->ttis[sp->typecnt++] = ts->ttis[1];
491+
for (i = 0; i < ts->typecnt; i++)
492+
sp->ttis[sp->typecnt++] = ts->ttis[i];
486493
}
487494
}
488495
}
496+
if (sp->typecnt == 0)
497+
return EINVAL;
489498
if (sp->timecnt > 1)
490499
{
491500
for (i = 1; i < sp->timecnt; ++i)
@@ -506,6 +515,18 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
506515
}
507516
}
508517

518+
/*
519+
* Infer sp->defaulttype from the data. Although this default type is
520+
* always zero for data from recent tzdb releases, things are trickier for
521+
* data from tzdb 2018e or earlier.
522+
*
523+
* The first set of heuristics work around bugs in 32-bit data generated
524+
* by tzdb 2013c or earlier. The workaround is for zones like
525+
* Australia/Macquarie where timestamps before the first transition have a
526+
* time type that is not the earliest standard-time type. See:
527+
* https://mm.icann.org/pipermail/tz/2013-May/019368.html
528+
*/
529+
509530
/*
510531
* If type 0 is unused in transitions, it's the type to use for early
511532
* times.
@@ -528,6 +549,11 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
528549
break;
529550
}
530551

552+
/*
553+
* The next heuristics are for data generated by tzdb 2018e or earlier,
554+
* for zones like EST5EDT where the first transition is to DST.
555+
*/
556+
531557
/*
532558
* If no result yet, find the first standard type. If there is none, punt
533559
* to type zero.
@@ -542,7 +568,14 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
542568
break;
543569
}
544570
}
571+
572+
/*
573+
* A simple 'sp->defaulttype = 0;' would suffice here if we didn't have to
574+
* worry about 2018e-or-earlier data. Even simpler would be to remove the
575+
* defaulttype member and just use 0 in its place.
576+
*/
545577
sp->defaulttype = i;
578+
546579
return 0;
547580
}
548581

@@ -601,10 +634,11 @@ static const int year_lengths[2] = {
601634
};
602635

603636
/*
604-
* Given a pointer into a time zone string, scan until a character that is not
605-
* a valid character in a zone name is found. Return a pointer to that
606-
* character.
637+
* Given a pointer into a timezone string, scan until a character that is not
638+
* a valid character in a time zone abbreviation is found.
639+
* Return a pointer to that character.
607640
*/
641+
608642
static const char *
609643
getzname(const char *strp)
610644
{
@@ -617,15 +651,17 @@ getzname(const char *strp)
617651
}
618652

619653
/*
620-
* Given a pointer into an extended time zone string, scan until the ending
621-
* delimiter of the zone name is located. Return a pointer to the delimiter.
654+
* Given a pointer into an extended timezone string, scan until the ending
655+
* delimiter of the time zone abbreviation is located.
656+
* Return a pointer to the delimiter.
622657
*
623658
* As with getzname above, the legal character set is actually quite
624659
* restricted, with other characters producing undefined results.
625660
* We don't do any checking here; checking is done later in common-case code.
626661
*/
662+
627663
static const char *
628-
getqzname(const char *strp, int delim)
664+
getqzname(const char *strp, const int delim)
629665
{
630666
int c;
631667

@@ -635,13 +671,14 @@ getqzname(const char *strp, int delim)
635671
}
636672

637673
/*
638-
* Given a pointer into a time zone string, extract a number from that string.
674+
* Given a pointer into a timezone string, extract a number from that string.
639675
* Check that the number is within a specified range; if it is not, return
640676
* NULL.
641677
* Otherwise, return a pointer to the first character not part of the number.
642678
*/
679+
643680
static const char *
644-
getnum(const char *strp, int *nump, int min, int max)
681+
getnum(const char *strp, int *const nump, const int min, const int max)
645682
{
646683
char c;
647684
int num;
@@ -663,14 +700,15 @@ getnum(const char *strp, int *nump, int min, int max)
663700
}
664701

665702
/*
666-
* Given a pointer into a time zone string, extract a number of seconds,
703+
* Given a pointer into a timezone string, extract a number of seconds,
667704
* in hh[:mm[:ss]] form, from the string.
668705
* If any error occurs, return NULL.
669706
* Otherwise, return a pointer to the first character not part of the number
670707
* of seconds.
671708
*/
709+
672710
static const char *
673-
getsecs(const char *strp, int32 *secsp)
711+
getsecs(const char *strp, int32 *const secsp)
674712
{
675713
int num;
676714

@@ -704,13 +742,14 @@ getsecs(const char *strp, int32 *secsp)
704742
}
705743

706744
/*
707-
* Given a pointer into a time zone string, extract an offset, in
745+
* Given a pointer into a timezone string, extract an offset, in
708746
* [+-]hh[:mm[:ss]] form, from the string.
709747
* If any error occurs, return NULL.
710748
* Otherwise, return a pointer to the first character not part of the time.
711749
*/
750+
712751
static const char *
713-
getoffset(const char *strp, int32 *offsetp)
752+
getoffset(const char *strp, int32 *const offsetp)
714753
{
715754
bool neg = false;
716755

@@ -730,13 +769,14 @@ getoffset(const char *strp, int32 *offsetp)
730769
}
731770

732771
/*
733-
* Given a pointer into a time zone string, extract a rule in the form
772+
* Given a pointer into a timezone string, extract a rule in the form
734773
* date[/time]. See POSIX section 8 for the format of "date" and "time".
735774
* If a valid rule is not found, return NULL.
736775
* Otherwise, return a pointer to the first character not part of the rule.
737776
*/
777+
738778
static const char *
739-
getrule(const char *strp, struct rule *rulep)
779+
getrule(const char *strp, struct rule *const rulep)
740780
{
741781
if (*strp == 'J')
742782
{
@@ -795,9 +835,10 @@ getrule(const char *strp, struct rule *rulep)
795835
* Given a year, a rule, and the offset from UT at the time that rule takes
796836
* effect, calculate the year-relative time that rule takes effect.
797837
*/
838+
798839
static int32
799-
transtime(int year, const struct rule *rulep,
800-
int32 offset)
840+
transtime(const int year, const struct rule *const rulep,
841+
const int32 offset)
801842
{
802843
bool leapyear;
803844
int32 value;
@@ -967,7 +1008,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
9671008
{
9681009
dstname = name;
9691010
name = getzname(name);
970-
dstlen = name - dstname; /* length of DST zone name */
1011+
dstlen = name - dstname; /* length of DST abbr. */
9711012
}
9721013
if (!dstlen)
9731014
return false;
@@ -1039,8 +1080,8 @@ tzparse(const char *name, struct state *sp, bool lastditch)
10391080
/*
10401081
* Two transitions per year, from EPOCH_YEAR forward.
10411082
*/
1042-
init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
1043-
init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
1083+
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1084+
init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
10441085
sp->defaulttype = 0;
10451086
timecnt = 0;
10461087
janfirst = 0;
@@ -1089,19 +1130,15 @@ tzparse(const char *name, struct state *sp, bool lastditch)
10891130
if (!increment_overflow_time
10901131
(&sp->ats[timecnt],
10911132
janoffset + starttime))
1092-
sp->types[timecnt++] = reversed;
1093-
else if (janoffset)
1094-
sp->defaulttype = reversed;
1133+
sp->types[timecnt++] = !reversed;
10951134
sp->ats[timecnt] = janfirst;
10961135
if (!increment_overflow_time
10971136
(&sp->ats[timecnt],
10981137
janoffset + endtime))
10991138
{
1100-
sp->types[timecnt++] = !reversed;
1139+
sp->types[timecnt++] = reversed;
11011140
yearlim = year + YEARSPERREPEAT + 1;
11021141
}
1103-
else if (janoffset)
1104-
sp->defaulttype = !reversed;
11051142
}
11061143
if (increment_overflow_time
11071144
(&janfirst, janoffset + yearsecs))
@@ -1110,7 +1147,10 @@ tzparse(const char *name, struct state *sp, bool lastditch)
11101147
}
11111148
sp->timecnt = timecnt;
11121149
if (!timecnt)
1150+
{
1151+
sp->ttis[0] = sp->ttis[1];
11131152
sp->typecnt = 1; /* Perpetual DST. */
1153+
}
11141154
else if (YEARSPERREPEAT < year - yearbeg)
11151155
sp->goback = sp->goahead = true;
11161156
}
@@ -1179,7 +1219,6 @@ tzparse(const char *name, struct state *sp, bool lastditch)
11791219
* otherwise, add the standard time offset to the
11801220
* transition time.
11811221
*/
1182-
11831222
/*
11841223
* Transitions from DST to DDST will effectively disappear
11851224
* since POSIX provides for only one DST offset.
@@ -1233,7 +1272,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
12331272
}
12341273

12351274
static void
1236-
gmtload(struct state *sp)
1275+
gmtload(struct state *const sp)
12371276
{
12381277
if (tzload(gmt, NULL, sp, true) != 0)
12391278
tzparse(gmt, sp, true);
@@ -1248,7 +1287,7 @@ gmtload(struct state *sp)
12481287
*/
12491288
static struct pg_tm *
12501289
localsub(struct state const *sp, pg_time_t const *timep,
1251-
struct pg_tm *tmp)
1290+
struct pg_tm *const tmp)
12521291
{
12531292
const struct ttinfo *ttisp;
12541293
int i;
@@ -1316,6 +1355,11 @@ localsub(struct state const *sp, pg_time_t const *timep,
13161355
}
13171356
ttisp = &sp->ttis[i];
13181357

1358+
/*
1359+
* To get (wrong) behavior that's compatible with System V Release 2.0
1360+
* you'd replace the statement below with t += ttisp->tt_gmtoff;
1361+
* timesub(&t, 0L, sp, tmp);
1362+
*/
13191363
result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
13201364
if (result)
13211365
{
@@ -1338,8 +1382,10 @@ pg_localtime(const pg_time_t *timep, const pg_tz *tz)
13381382
*
13391383
* Except we have a private "struct state" for GMT, so no sp is passed in.
13401384
*/
1385+
13411386
static struct pg_tm *
1342-
gmtsub(pg_time_t const *timep, int32 offset, struct pg_tm *tmp)
1387+
gmtsub(pg_time_t const *timep, int32 offset,
1388+
struct pg_tm *tmp)
13431389
{
13441390
struct pg_tm *result;
13451391

@@ -1354,6 +1400,7 @@ gmtsub(pg_time_t const *timep, int32 offset, struct pg_tm *tmp)
13541400
return NULL; /* errno should be set by malloc */
13551401
gmtload(gmtptr);
13561402
}
1403+
13571404
result = timesub(timep, offset, gmtptr, tmp);
13581405

13591406
/*
@@ -1378,6 +1425,7 @@ pg_gmtime(const pg_time_t *timep)
13781425
* Return the number of leap years through the end of the given year
13791426
* where, to make the math easy, the answer for year zero is defined as zero.
13801427
*/
1428+
13811429
static int
13821430
leaps_thru_end_of_nonneg(int y)
13831431
{

0 commit comments

Comments
 (0)