1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
From 957aa220aa175a874f429f97701eede0f1ef14d3 Mon Sep 17 00:00:00 2001
From: Derick Rethans <github@derickrethans.nl>
Date: Sun, 26 Apr 2015 11:04:16 +0100
Subject: [PATCH] Fixed location reading due to file format changes
---
ext/date/lib/parse_tz.c | 61 ++-
ext/date/lib/timezonedb.h | 1166 ++++++++++++++++++++++-----------------------
2 files changed, 640 insertions(+), 587 deletions(-)
diff --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c
index ec7c6d3..89b8af7 100644
--- a/ext/date/lib/parse_tz.c
+++ b/ext/date/lib/parse_tz.c
@@ -49,9 +49,12 @@
#define timelib_conv_int(l) ((l & 0x000000ff) << 24) + ((l & 0x0000ff00) << 8) + ((l & 0x00ff0000) >> 8) + ((l & 0xff000000) >> 24)
#endif
-static void read_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
+static int read_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
{
- /* skip ID */
+ uint32_t version;
+
+ /* read ID */
+ version = (*tzf)[3] - '0';
*tzf += 4;
/* read BC flag */
@@ -63,8 +66,10 @@ static void read_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
tz->location.country_code[2] = '\0';
*tzf += 2;
- /* skip read of preamble */
+ /* skip rest of preamble */
*tzf += 13;
+
+ return version;
}
static void read_header(const unsigned char **tzf, timelib_tzinfo *tz)
@@ -81,6 +86,14 @@ static void read_header(const unsigned char **tzf, timelib_tzinfo *tz)
*tzf += sizeof(buffer);
}
+static void skip_transistions_64bit(const unsigned char **tzf, timelib_tzinfo *tz)
+{
+ if (tz->timecnt) {
+ *tzf += (sizeof(int64_t) * (tz->timecnt + 1));
+ *tzf += (sizeof(unsigned char) * (tz->timecnt + 1));
+ }
+}
+
static void read_transistions(const unsigned char **tzf, timelib_tzinfo *tz)
{
int32_t *buffer = NULL;
@@ -111,6 +124,21 @@ static void read_transistions(const unsigned char **tzf, timelib_tzinfo *tz)
tz->trans_idx = cbuffer;
}
+static void skip_types_64bit(const unsigned char **tzf, timelib_tzinfo *tz)
+{
+ *tzf += sizeof(unsigned char) * 6 * tz->typecnt;
+ *tzf += sizeof(char) * tz->charcnt;
+ if (tz->leapcnt) {
+ *tzf += sizeof(int64_t) * tz->leapcnt * 2;
+ }
+ if (tz->ttisstdcnt) {
+ *tzf += sizeof(unsigned char) * tz->ttisstdcnt;
+ }
+ if (tz->ttisgmtcnt) {
+ *tzf += sizeof(unsigned char) * tz->ttisgmtcnt;
+ }
+}
+
static void read_types(const unsigned char **tzf, timelib_tzinfo *tz)
{
unsigned char *buffer;
@@ -194,6 +222,18 @@ static void read_types(const unsigned char **tzf, timelib_tzinfo *tz)
}
}
+static void skip_posix_string(const unsigned char **tzf, timelib_tzinfo *tz)
+{
+ int n_count = 0;
+
+ do {
+ if (*tzf[0] == '\n') {
+ n_count++;
+ }
+ (*tzf)++;
+ } while (n_count < 2);
+}
+
static void read_location(const unsigned char **tzf, timelib_tzinfo *tz)
{
uint32_t buffer[3];
@@ -312,18 +352,31 @@ int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb)
return (seek_to_tz_position(&tzf, timezone, tzdb));
}
+static void skip_2nd_header_and_data(const unsigned char **tzf, timelib_tzinfo *tz)
+{
+ *tzf += 20; /* skip 2nd header (preamble) */
+ *tzf += sizeof(int32_t) * 6; /* Counts */
+}
+
timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb)
{
const unsigned char *tzf;
timelib_tzinfo *tmp;
+ int version;
if (seek_to_tz_position(&tzf, timezone, tzdb)) {
tmp = timelib_tzinfo_ctor(timezone);
- read_preamble(&tzf, tmp);
+ version = read_preamble(&tzf, tmp);
read_header(&tzf, tmp);
read_transistions(&tzf, tmp);
read_types(&tzf, tmp);
+ if (version == 2) {
+ skip_2nd_header_and_data(&tzf, tmp);
+ skip_transistions_64bit(&tzf, tmp);
+ skip_types_64bit(&tzf, tmp);
+ skip_posix_string(&tzf, tmp);
+ }
read_location(&tzf, tmp);
} else {
tmp = NULL;
--
2.1.4
From b5e5098c50397ed910a79ac1d64b7d0fff2c02e1 Mon Sep 17 00:00:00 2001
From: Matteo Beccati <mbeccati@php.net>
Date: Tue, 28 Apr 2015 10:57:18 +0200
Subject: [PATCH] Fix segfault in ext/date since 957aa2
---
ext/date/lib/parse_tz.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c
index 89b8af7..32ed639 100644
--- a/ext/date/lib/parse_tz.c
+++ b/ext/date/lib/parse_tz.c
@@ -89,8 +89,8 @@ static void read_header(const unsigned char **tzf, timelib_tzinfo *tz)
static void skip_transistions_64bit(const unsigned char **tzf, timelib_tzinfo *tz)
{
if (tz->timecnt) {
- *tzf += (sizeof(int64_t) * (tz->timecnt + 1));
- *tzf += (sizeof(unsigned char) * (tz->timecnt + 1));
+ *tzf += (sizeof(int64_t) * (tz->timecnt));
+ *tzf += (sizeof(unsigned char) * (tz->timecnt));
}
}
--
2.1.4
|