49
49
#define timelib_conv_int (l ) ((l & 0x000000ff) << 24) + ((l & 0x0000ff00) << 8) + ((l & 0x00ff0000) >> 8) + ((l & 0xff000000) >> 24)
50
50
#endif
51
51
52
- static void read_preamble (const unsigned char * * tzf , timelib_tzinfo * tz )
52
+ static int read_preamble (const unsigned char * * tzf , timelib_tzinfo * tz )
53
53
{
54
- /* skip ID */
54
+ uint32_t version ;
55
+
56
+ /* read ID */
57
+ version = (* tzf )[3 ] - '0' ;
55
58
* tzf += 4 ;
56
59
57
60
/* read BC flag */
@@ -63,8 +66,10 @@ static void read_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
63
66
tz -> location .country_code [2 ] = '\0' ;
64
67
* tzf += 2 ;
65
68
66
- /* skip read of preamble */
69
+ /* skip rest of preamble */
67
70
* tzf += 13 ;
71
+
72
+ return version ;
68
73
}
69
74
70
75
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)
81
86
* tzf += sizeof (buffer );
82
87
}
83
88
89
+ static void skip_transistions_64bit (const unsigned char * * tzf , timelib_tzinfo * tz )
90
+ {
91
+ if (tz -> timecnt ) {
92
+ * tzf += (sizeof (int64_t ) * (tz -> timecnt + 1 ));
93
+ * tzf += (sizeof (unsigned char ) * (tz -> timecnt + 1 ));
94
+ }
95
+ }
96
+
84
97
static void read_transistions (const unsigned char * * tzf , timelib_tzinfo * tz )
85
98
{
86
99
int32_t * buffer = NULL ;
@@ -111,6 +124,21 @@ static void read_transistions(const unsigned char **tzf, timelib_tzinfo *tz)
111
124
tz -> trans_idx = cbuffer ;
112
125
}
113
126
127
+ static void skip_types_64bit (const unsigned char * * tzf , timelib_tzinfo * tz )
128
+ {
129
+ * tzf += sizeof (unsigned char ) * 6 * tz -> typecnt ;
130
+ * tzf += sizeof (char ) * tz -> charcnt ;
131
+ if (tz -> leapcnt ) {
132
+ * tzf += sizeof (int64_t ) * tz -> leapcnt * 2 ;
133
+ }
134
+ if (tz -> ttisstdcnt ) {
135
+ * tzf += sizeof (unsigned char ) * tz -> ttisstdcnt ;
136
+ }
137
+ if (tz -> ttisgmtcnt ) {
138
+ * tzf += sizeof (unsigned char ) * tz -> ttisgmtcnt ;
139
+ }
140
+ }
141
+
114
142
static void read_types (const unsigned char * * tzf , timelib_tzinfo * tz )
115
143
{
116
144
unsigned char * buffer ;
@@ -194,6 +222,18 @@ static void read_types(const unsigned char **tzf, timelib_tzinfo *tz)
194
222
}
195
223
}
196
224
225
+ static void skip_posix_string (const unsigned char * * tzf , timelib_tzinfo * tz )
226
+ {
227
+ int n_count = 0 ;
228
+
229
+ do {
230
+ if (* tzf [0 ] == '\n' ) {
231
+ n_count ++ ;
232
+ }
233
+ (* tzf )++ ;
234
+ } while (n_count < 2 );
235
+ }
236
+
197
237
static void read_location (const unsigned char * * tzf , timelib_tzinfo * tz )
198
238
{
199
239
uint32_t buffer [3 ];
@@ -312,18 +352,31 @@ int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb)
312
352
return (seek_to_tz_position (& tzf , timezone , tzdb ));
313
353
}
314
354
355
+ static void skip_2nd_header_and_data (const unsigned char * * tzf , timelib_tzinfo * tz )
356
+ {
357
+ * tzf += 20 ; /* skip 2nd header (preamble) */
358
+ * tzf += sizeof (int32_t ) * 6 ; /* Counts */
359
+ }
360
+
315
361
timelib_tzinfo * timelib_parse_tzfile (char * timezone , const timelib_tzdb * tzdb )
316
362
{
317
363
const unsigned char * tzf ;
318
364
timelib_tzinfo * tmp ;
365
+ int version ;
319
366
320
367
if (seek_to_tz_position (& tzf , timezone , tzdb )) {
321
368
tmp = timelib_tzinfo_ctor (timezone );
322
369
323
- read_preamble (& tzf , tmp );
370
+ version = read_preamble (& tzf , tmp );
324
371
read_header (& tzf , tmp );
325
372
read_transistions (& tzf , tmp );
326
373
read_types (& tzf , tmp );
374
+ if (version == 2 ) {
375
+ skip_2nd_header_and_data (& tzf , tmp );
376
+ skip_transistions_64bit (& tzf , tmp );
377
+ skip_types_64bit (& tzf , tmp );
378
+ skip_posix_string (& tzf , tmp );
379
+ }
327
380
read_location (& tzf , tmp );
328
381
} else {
329
382
tmp = NULL ;
0 commit comments