|
@@ -1,12 +1,13 @@
|
1
|
|
-
|
2
|
1
|
Add support for use of the system timezone database, rather
|
3
|
2
|
than embedding a copy. Discussed upstream but was not desired.
|
4
|
3
|
|
5
|
4
|
History:
|
6
|
|
-r9: fix another compile error without --with-system-tzdata configured
|
|
5
|
+r11: adopted to php 5.6.9
|
|
6
|
+r10: make timezone case insensitive
|
|
7
|
+r9: fix another compile error without --with-system-tzdata configured (Michael Heimpold)
|
7
|
8
|
r8: fix compile error without --with-system-tzdata configured
|
8
|
9
|
r7: improve check for valid timezone id to exclude directories
|
9
|
|
-r6: fix fd leak in r5, fix country code/BC flag use in
|
|
10
|
+r6: fix fd leak in r5, fix country code/BC flag use in.
|
10
|
11
|
timezone_identifiers_list() using system db,
|
11
|
12
|
fix use of PECL timezonedb to override system db,
|
12
|
13
|
r5: reverts addition of "System/Localtime" fake tzname.
|
|
@@ -17,10 +18,17 @@ r3: fix a crash if /usr/share/zoneinfo doesn't exist (Raphael Geissert)
|
17
|
18
|
r2: add filesystem trawl to set up name alias index
|
18
|
19
|
r1: initial revision
|
19
|
20
|
|
20
|
|
---- a/ext/date/lib/parse_tz.c
|
21
|
|
-+++ b/ext/date/lib/parse_tz.c
|
22
|
|
-@@ -20,6 +20,16 @@
|
|
21
|
+diff -Naur php-5.6.9.orig/ext/date/lib/parse_tz.c php-5.6.9/ext/date/lib/parse_tz.c
|
|
22
|
+--- php-5.6.9.orig/ext/date/lib/parse_tz.c 2015-05-14 01:13:33.000000000 +0200
|
|
23
|
++++ php-5.6.9/ext/date/lib/parse_tz.c 2015-05-18 22:40:55.000000000 +0200
|
|
24
|
+@@ -18,8 +18,22 @@
|
|
25
|
+
|
|
26
|
+ /* $Id$ */
|
23
|
27
|
|
|
28
|
++#ifndef PATH_MAX
|
|
29
|
++#define PATH_MAX 4096
|
|
30
|
++#endif
|
|
31
|
++
|
24
|
32
|
#include "timelib.h"
|
25
|
33
|
|
26
|
34
|
+#ifdef HAVE_SYSTEM_TZDATA
|
|
@@ -36,7 +44,7 @@ r1: initial revision
|
36
|
44
|
#include <stdio.h>
|
37
|
45
|
|
38
|
46
|
#ifdef HAVE_LOCALE_H
|
39
|
|
-@@ -31,7 +41,12 @@
|
|
47
|
+@@ -31,7 +45,12 @@
|
40
|
48
|
#else
|
41
|
49
|
#include <strings.h>
|
42
|
50
|
#endif
|
|
@@ -49,25 +57,19 @@ r1: initial revision
|
49
|
57
|
|
50
|
58
|
#if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
|
51
|
59
|
# if defined(__LITTLE_ENDIAN__)
|
52
|
|
-@@ -51,9 +66,14 @@
|
53
|
|
-
|
54
|
|
- static void read_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
|
|
60
|
+@@ -53,6 +72,11 @@
|
55
|
61
|
{
|
56
|
|
-- /* skip ID */
|
57
|
|
-- *tzf += 4;
|
58
|
|
--
|
59
|
|
-+ if (memcmp(tzf, "TZif", 4) == 0) {
|
60
|
|
-+ *tzf += 20;
|
61
|
|
-+ return;
|
62
|
|
-+ }
|
63
|
|
-+
|
64
|
|
-+ /* skip ID */
|
65
|
|
-+ *tzf += 4;
|
66
|
|
-+
|
67
|
|
- /* read BC flag */
|
68
|
|
- tz->bc = (**tzf == '\1');
|
69
|
|
- *tzf += 1;
|
70
|
|
-@@ -256,7 +276,397 @@ void timelib_dump_tzinfo(timelib_tzinfo
|
|
62
|
+ uint32_t version;
|
|
63
|
+
|
|
64
|
++ if (memcmp(tzf, "TZif", 4) == 0) {
|
|
65
|
++ *tzf += 20;
|
|
66
|
++ return -1;
|
|
67
|
++ }
|
|
68
|
++
|
|
69
|
+ /* read ID */
|
|
70
|
+ version = (*tzf)[3] - '0';
|
|
71
|
+ *tzf += 4;
|
|
72
|
+@@ -296,7 +320,406 @@
|
71
|
73
|
}
|
72
|
74
|
}
|
73
|
75
|
|
|
@@ -81,7 +83,7 @@ r1: initial revision
|
81
|
83
|
+#endif
|
82
|
84
|
+
|
83
|
85
|
+/* System timezone database pointer. */
|
84
|
|
-+static const timelib_tzdb *timezonedb_system = NULL;
|
|
86
|
++static const timelib_tzdb *timezonedb_system;
|
85
|
87
|
+
|
86
|
88
|
+/* Hash table entry for the cache of the zone.tab mapping table. */
|
87
|
89
|
+struct location_info {
|
|
@@ -99,13 +101,14 @@ r1: initial revision
|
99
|
101
|
+ * prevent too many collisions. */
|
100
|
102
|
+#define LOCINFO_HASH_SIZE (1021)
|
101
|
103
|
+
|
|
104
|
++/* Compute a case insensitive hash of str */
|
102
|
105
|
+static uint32_t tz_hash(const char *str)
|
103
|
106
|
+{
|
104
|
107
|
+ const unsigned char *p = (const unsigned char *)str;
|
105
|
108
|
+ uint32_t hash = 5381;
|
106
|
109
|
+ int c;
|
107
|
110
|
+
|
108
|
|
-+ while ((c = *p++) != '\0') {
|
|
111
|
++ while ((c = tolower(*p++)) != '\0') {
|
109
|
112
|
+ hash = (hash << 5) ^ hash ^ c;
|
110
|
113
|
+ }
|
111
|
114
|
+
|
|
@@ -201,10 +204,10 @@ r1: initial revision
|
201
|
204
|
+
|
202
|
205
|
+ if (*p == '#' || *p == '\0' || *p == '\n')
|
203
|
206
|
+ continue;
|
204
|
|
-+
|
|
207
|
++
|
205
|
208
|
+ if (!isalpha(p[0]) || !isalpha(p[1]) || p[2] != '\t')
|
206
|
209
|
+ continue;
|
207
|
|
-+
|
|
210
|
++
|
208
|
211
|
+ /* code => AA */
|
209
|
212
|
+ code = p;
|
210
|
213
|
+ p[2] = 0;
|
|
@@ -238,7 +241,7 @@ r1: initial revision
|
238
|
241
|
+
|
239
|
242
|
+ if (*p == '\n' || *p == '\t')
|
240
|
243
|
+ *p = '\0';
|
241
|
|
-+
|
|
244
|
++
|
242
|
245
|
+ hash = tz_hash(name);
|
243
|
246
|
+ i = malloc(sizeof *i);
|
244
|
247
|
+ memcpy(i->code, code, 2);
|
|
@@ -274,7 +277,7 @@ r1: initial revision
|
274
|
277
|
+ }
|
275
|
278
|
+
|
276
|
279
|
+ return NULL;
|
277
|
|
-+}
|
|
280
|
++}
|
278
|
281
|
+
|
279
|
282
|
+/* Filter out some non-tzdata files and the posix/right databases, if
|
280
|
283
|
+ * present. */
|
|
@@ -443,6 +446,14 @@ r1: initial revision
|
443
|
446
|
+ return NULL;
|
444
|
447
|
+ }
|
445
|
448
|
+
|
|
449
|
++ if (system_location_table) {
|
|
450
|
++ const struct location_info *li;
|
|
451
|
++ if ((li = find_zone_info(system_location_table, timezone)) != NULL) {
|
|
452
|
++ /* Use the stored name to avoid case issue */
|
|
453
|
++ timezone = li->name;
|
|
454
|
++ }
|
|
455
|
++ }
|
|
456
|
++
|
446
|
457
|
+ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", timezone);
|
447
|
458
|
+
|
448
|
459
|
+ fd = open(fname, O_RDONLY);
|
|
@@ -466,11 +477,11 @@ r1: initial revision
|
466
|
477
|
{
|
467
|
478
|
int left = 0, right = tzdb->index_size - 1;
|
468
|
479
|
#ifdef HAVE_SETLOCALE
|
469
|
|
-@@ -295,36 +705,128 @@ static int seek_to_tz_position(const uns
|
|
480
|
+@@ -335,21 +758,90 @@
|
470
|
481
|
return 0;
|
471
|
482
|
}
|
472
|
483
|
|
473
|
|
-+static int seek_to_tz_position(const unsigned char **tzf, char *timezone,
|
|
484
|
++static int seek_to_tz_position(const unsigned char **tzf, char *timezone,
|
474
|
485
|
+ char **map, size_t *maplen,
|
475
|
486
|
+ const timelib_tzdb *tzdb)
|
476
|
487
|
+{
|
|
@@ -483,14 +494,14 @@ r1: initial revision
|
483
|
494
|
+ return 0;
|
484
|
495
|
+ }
|
485
|
496
|
+
|
486
|
|
-+ (*tzf) = (unsigned char *)orig ;
|
|
497
|
++ (*tzf) = (unsigned char *)orig;
|
487
|
498
|
+ *map = orig;
|
488
|
|
-+
|
489
|
|
-+ return 1;
|
|
499
|
++
|
|
500
|
++ return 1;
|
490
|
501
|
+ }
|
491
|
|
-+ else
|
|
502
|
++ else
|
492
|
503
|
+#endif
|
493
|
|
-+ {
|
|
504
|
++ {
|
494
|
505
|
+ return inmem_seek_to_tz_position(tzf, timezone, tzdb);
|
495
|
506
|
+ }
|
496
|
507
|
+}
|
|
@@ -505,7 +516,7 @@ r1: initial revision
|
505
|
516
|
+ tmp->data = NULL;
|
506
|
517
|
+ create_zone_index(tmp);
|
507
|
518
|
+ system_location_table = create_location_table();
|
508
|
|
-+ fake_data_segment(tmp, system_location_table);
|
|
519
|
++ fake_data_segment(tmp, system_location_table);
|
509
|
520
|
+ timezonedb_system = tmp;
|
510
|
521
|
+ }
|
511
|
522
|
+
|
|
@@ -533,38 +544,49 @@ r1: initial revision
|
533
|
544
|
- return (seek_to_tz_position(&tzf, timezone, tzdb));
|
534
|
545
|
+
|
535
|
546
|
+#ifdef HAVE_SYSTEM_TZDATA
|
536
|
|
-+ if (tzdb == timezonedb_system) {
|
537
|
|
-+ char fname[PATH_MAX];
|
538
|
|
-+ struct stat st;
|
539
|
|
-+
|
540
|
|
-+ if (timezone[0] == '\0' || strstr(timezone, "..") != NULL) {
|
541
|
|
-+ return 0;
|
542
|
|
-+ }
|
543
|
|
-+
|
544
|
|
-+ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", timezone);
|
545
|
|
-+
|
546
|
|
-+ return stat(fname, &st) == 0 && is_valid_tzfile(&st);
|
547
|
|
-+ }
|
|
547
|
++ if (tzdb == timezonedb_system) {
|
|
548
|
++ char fname[PATH_MAX];
|
|
549
|
++ struct stat st;
|
|
550
|
++
|
|
551
|
++ if (timezone[0] == '\0' || strstr(timezone, "..") != NULL) {
|
|
552
|
++ return 0;
|
|
553
|
++ }
|
|
554
|
++
|
|
555
|
++ if (system_location_table) {
|
|
556
|
++ if (find_zone_info(system_location_table, timezone) != NULL) {
|
|
557
|
++ /* found in cache */
|
|
558
|
++ return 1;
|
|
559
|
++ }
|
|
560
|
++ }
|
|
561
|
++
|
|
562
|
++ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", timezone);
|
|
563
|
++
|
|
564
|
++ return stat(fname, &st) == 0 && is_valid_tzfile(&st);
|
|
565
|
++ }
|
548
|
566
|
+#endif
|
549
|
567
|
+
|
550
|
568
|
+ return (inmem_seek_to_tz_position(&tzf, timezone, tzdb));
|
551
|
569
|
}
|
552
|
570
|
|
|
571
|
+ static void skip_64bit_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
|
|
572
|
+@@ -374,10 +866,12 @@
|
553
|
573
|
timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb)
|
554
|
574
|
{
|
555
|
575
|
const unsigned char *tzf;
|
556
|
576
|
+ char *memmap = NULL;
|
557
|
577
|
+ size_t maplen;
|
558
|
578
|
timelib_tzinfo *tmp;
|
|
579
|
+ int version;
|
559
|
580
|
|
560
|
581
|
- if (seek_to_tz_position(&tzf, timezone, tzdb)) {
|
561
|
582
|
+ if (seek_to_tz_position(&tzf, timezone, &memmap, &maplen, tzdb)) {
|
562
|
583
|
tmp = timelib_tzinfo_ctor(timezone);
|
563
|
584
|
|
564
|
|
- read_preamble(&tzf, tmp);
|
565
|
|
- read_header(&tzf, tmp);
|
566
|
|
- read_transistions(&tzf, tmp);
|
567
|
|
- read_types(&tzf, tmp);
|
|
585
|
+ version = read_preamble(&tzf, tmp);
|
|
586
|
+@@ -391,7 +885,34 @@
|
|
587
|
+ skip_64bit_types(&tzf, tmp);
|
|
588
|
+ skip_posix_string(&tzf, tmp);
|
|
589
|
+ }
|
568
|
590
|
- read_location(&tzf, tmp);
|
569
|
591
|
+
|
570
|
592
|
+#ifdef HAVE_SYSTEM_TZDATA
|
|
@@ -576,12 +598,11 @@ r1: initial revision
|
576
|
598
|
+
|
577
|
599
|
+ if ((li = find_zone_info(system_location_table, timezone)) != NULL) {
|
578
|
600
|
+ tmp->location.comments = strdup(li->comment);
|
579
|
|
-+ strncpy(tmp->location.country_code, li->code, 2);
|
|
601
|
++ strncpy(tmp->location.country_code, li->code, 2);
|
580
|
602
|
+ tmp->location.longitude = li->longitude;
|
581
|
603
|
+ tmp->location.latitude = li->latitude;
|
582
|
604
|
+ tmp->bc = 1;
|
583
|
|
-+ }
|
584
|
|
-+ else {
|
|
605
|
++ } else {
|
585
|
606
|
+ strcpy(tmp->location.country_code, "??");
|
586
|
607
|
+ tmp->bc = 0;
|
587
|
608
|
+ tmp->location.comments = strdup("");
|
|
@@ -598,9 +619,10 @@ r1: initial revision
|
598
|
619
|
} else {
|
599
|
620
|
tmp = NULL;
|
600
|
621
|
}
|
601
|
|
---- a/ext/date/lib/timelib.m4
|
602
|
|
-+++ b/ext/date/lib/timelib.m4
|
603
|
|
-@@ -78,3 +78,17 @@ stdlib.h
|
|
622
|
+diff -Naur php-5.6.9.orig/ext/date/lib/timelib.m4 php-5.6.9/ext/date/lib/timelib.m4
|
|
623
|
+--- php-5.6.9.orig/ext/date/lib/timelib.m4 2015-05-14 01:13:33.000000000 +0200
|
|
624
|
++++ php-5.6.9/ext/date/lib/timelib.m4 2015-05-18 22:31:36.000000000 +0200
|
|
625
|
+@@ -78,3 +78,17 @@
|
604
|
626
|
|
605
|
627
|
dnl Check for strtoll, atoll
|
606
|
628
|
AC_CHECK_FUNCS(strtoll atoll strftime)
|