Skip to content

Commit 09340ea

Browse files
committed
Fixed bug #75577: DateTime::createFromFormat does not accept 'v' format specifier, by updating timelib to 2018.01alpha2
1 parent 3d4167c commit 09340ea

File tree

8 files changed

+812
-341
lines changed

8 files changed

+812
-341
lines changed

ext/date/lib/parse_date.c

Lines changed: 403 additions & 208 deletions
Large diffs are not rendered by default.

ext/date/lib/parse_date.re

Lines changed: 268 additions & 75 deletions
Large diffs are not rendered by default.

ext/date/lib/parse_iso_intervals.c

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/* Generated by re2c 0.15.3 on Wed Jan 31 11:51:44 2018 */
2-
#line 1 "ext/date/lib/parse_iso_intervals.re"
1+
/* Generated by re2c 0.15.3 on Tue Oct 9 10:50:29 2018 */
2+
#line 1 "parse_iso_intervals.re"
33
/*
44
* The MIT License (MIT)
55
*
@@ -176,7 +176,7 @@ static int scan(Scanner *s)
176176
std:
177177
s->tok = cursor;
178178
s->len = 0;
179-
#line 204 "ext/date/lib/parse_iso_intervals.re"
179+
#line 204 "parse_iso_intervals.re"
180180

181181

182182

@@ -185,38 +185,38 @@ static int scan(Scanner *s)
185185
YYCTYPE yych;
186186
unsigned int yyaccept = 0;
187187
static const unsigned char yybm[] = {
188-
0, 0, 0, 0, 0, 0, 0, 0,
189-
0, 0, 0, 0, 0, 0, 0, 0,
190-
0, 0, 0, 0, 0, 0, 0, 0,
191-
0, 0, 0, 0, 0, 0, 0, 0,
192-
0, 0, 0, 0, 0, 0, 0, 0,
193-
0, 0, 0, 0, 0, 0, 0, 0,
194-
128, 128, 128, 128, 128, 128, 128, 128,
195-
128, 128, 0, 0, 0, 0, 0, 0,
196-
0, 0, 0, 0, 0, 0, 0, 0,
197-
0, 0, 0, 0, 0, 0, 0, 0,
198-
0, 0, 0, 0, 0, 0, 0, 0,
199-
0, 0, 0, 0, 0, 0, 0, 0,
200-
0, 0, 0, 0, 0, 0, 0, 0,
201-
0, 0, 0, 0, 0, 0, 0, 0,
202-
0, 0, 0, 0, 0, 0, 0, 0,
203-
0, 0, 0, 0, 0, 0, 0, 0,
204-
0, 0, 0, 0, 0, 0, 0, 0,
205-
0, 0, 0, 0, 0, 0, 0, 0,
206-
0, 0, 0, 0, 0, 0, 0, 0,
207-
0, 0, 0, 0, 0, 0, 0, 0,
208-
0, 0, 0, 0, 0, 0, 0, 0,
209-
0, 0, 0, 0, 0, 0, 0, 0,
210-
0, 0, 0, 0, 0, 0, 0, 0,
211-
0, 0, 0, 0, 0, 0, 0, 0,
212-
0, 0, 0, 0, 0, 0, 0, 0,
213-
0, 0, 0, 0, 0, 0, 0, 0,
214-
0, 0, 0, 0, 0, 0, 0, 0,
215-
0, 0, 0, 0, 0, 0, 0, 0,
216-
0, 0, 0, 0, 0, 0, 0, 0,
217-
0, 0, 0, 0, 0, 0, 0, 0,
218-
0, 0, 0, 0, 0, 0, 0, 0,
219-
0, 0, 0, 0, 0, 0, 0, 0,
188+
0, 0, 0, 0, 0, 0, 0, 0,
189+
0, 0, 0, 0, 0, 0, 0, 0,
190+
0, 0, 0, 0, 0, 0, 0, 0,
191+
0, 0, 0, 0, 0, 0, 0, 0,
192+
0, 0, 0, 0, 0, 0, 0, 0,
193+
0, 0, 0, 0, 0, 0, 0, 0,
194+
128, 128, 128, 128, 128, 128, 128, 128,
195+
128, 128, 0, 0, 0, 0, 0, 0,
196+
0, 0, 0, 0, 0, 0, 0, 0,
197+
0, 0, 0, 0, 0, 0, 0, 0,
198+
0, 0, 0, 0, 0, 0, 0, 0,
199+
0, 0, 0, 0, 0, 0, 0, 0,
200+
0, 0, 0, 0, 0, 0, 0, 0,
201+
0, 0, 0, 0, 0, 0, 0, 0,
202+
0, 0, 0, 0, 0, 0, 0, 0,
203+
0, 0, 0, 0, 0, 0, 0, 0,
204+
0, 0, 0, 0, 0, 0, 0, 0,
205+
0, 0, 0, 0, 0, 0, 0, 0,
206+
0, 0, 0, 0, 0, 0, 0, 0,
207+
0, 0, 0, 0, 0, 0, 0, 0,
208+
0, 0, 0, 0, 0, 0, 0, 0,
209+
0, 0, 0, 0, 0, 0, 0, 0,
210+
0, 0, 0, 0, 0, 0, 0, 0,
211+
0, 0, 0, 0, 0, 0, 0, 0,
212+
0, 0, 0, 0, 0, 0, 0, 0,
213+
0, 0, 0, 0, 0, 0, 0, 0,
214+
0, 0, 0, 0, 0, 0, 0, 0,
215+
0, 0, 0, 0, 0, 0, 0, 0,
216+
0, 0, 0, 0, 0, 0, 0, 0,
217+
0, 0, 0, 0, 0, 0, 0, 0,
218+
0, 0, 0, 0, 0, 0, 0, 0,
219+
0, 0, 0, 0, 0, 0, 0, 0,
220220
};
221221
YYDEBUG(0, *YYCURSOR);
222222
if ((YYLIMIT - YYCURSOR) < 20) YYFILL(20);
@@ -249,7 +249,7 @@ static int scan(Scanner *s)
249249
if (yych <= '9') goto yy98;
250250
yy3:
251251
YYDEBUG(3, *YYCURSOR);
252-
#line 317 "ext/date/lib/parse_iso_intervals.re"
252+
#line 317 "parse_iso_intervals.re"
253253
{
254254
add_error(s, "Unexpected character");
255255
goto std;
@@ -271,7 +271,7 @@ static int scan(Scanner *s)
271271
if (yych == 'T') goto yy14;
272272
yy6:
273273
YYDEBUG(6, *YYCURSOR);
274-
#line 244 "ext/date/lib/parse_iso_intervals.re"
274+
#line 244 "parse_iso_intervals.re"
275275
{
276276
timelib_sll nr;
277277
int in_time = 0;
@@ -317,7 +317,7 @@ static int scan(Scanner *s)
317317
YYDEBUG(7, *YYCURSOR);
318318
++YYCURSOR;
319319
YYDEBUG(8, *YYCURSOR);
320-
#line 306 "ext/date/lib/parse_iso_intervals.re"
320+
#line 306 "parse_iso_intervals.re"
321321
{
322322
goto std;
323323
}
@@ -326,7 +326,7 @@ static int scan(Scanner *s)
326326
YYDEBUG(9, *YYCURSOR);
327327
++YYCURSOR;
328328
YYDEBUG(10, *YYCURSOR);
329-
#line 311 "ext/date/lib/parse_iso_intervals.re"
329+
#line 311 "parse_iso_intervals.re"
330330
{
331331
s->pos = cursor; s->line++;
332332
goto std;
@@ -661,7 +661,7 @@ static int scan(Scanner *s)
661661
YYDEBUG(57, *YYCURSOR);
662662
++YYCURSOR;
663663
YYDEBUG(58, *YYCURSOR);
664-
#line 286 "ext/date/lib/parse_iso_intervals.re"
664+
#line 286 "parse_iso_intervals.re"
665665
{
666666
DEBUG_OUTPUT("combinedrep");
667667
TIMELIB_INIT;
@@ -809,7 +809,7 @@ static int scan(Scanner *s)
809809
YYDEBUG(83, *YYCURSOR);
810810
++YYCURSOR;
811811
YYDEBUG(84, *YYCURSOR);
812-
#line 220 "ext/date/lib/parse_iso_intervals.re"
812+
#line 220 "parse_iso_intervals.re"
813813
{
814814
timelib_time *current;
815815

@@ -910,7 +910,7 @@ static int scan(Scanner *s)
910910
if (yych <= '9') goto yy98;
911911
yy100:
912912
YYDEBUG(100, *YYCURSOR);
913-
#line 209 "ext/date/lib/parse_iso_intervals.re"
913+
#line 209 "parse_iso_intervals.re"
914914
{
915915
DEBUG_OUTPUT("recurrences");
916916
TIMELIB_INIT;
@@ -922,7 +922,7 @@ static int scan(Scanner *s)
922922
}
923923
#line 924 "<stdout>"
924924
}
925-
#line 321 "ext/date/lib/parse_iso_intervals.re"
925+
#line 321 "parse_iso_intervals.re"
926926

927927
}
928928
#ifdef PHP_WIN32

ext/date/lib/parse_tz.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib
585585
return &(tz->type[tz->trans_idx[j]]);
586586
}
587587

588-
/* In all other cases we loop through the available transtion times to find
588+
/* In all other cases we loop through the available transition times to find
589589
* the correct entry */
590590
for (i = 0; i < tz->bit32.timecnt; i++) {
591591
if (ts < tz->trans[i]) {

ext/date/lib/timelib.h

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#endif
3131

3232
#include <stdlib.h>
33+
#include <stdbool.h>
3334
#include <limits.h>
3435
#include <inttypes.h>
3536

@@ -264,6 +265,16 @@ typedef struct _timelib_abbr_info {
264265
#define TIMELIB_ERR_WRONG_FORMAT_SEP 0x219
265266
#define TIMELIB_ERR_TRAILING_DATA 0x21a
266267
#define TIMELIB_ERR_DATA_MISSING 0x21b
268+
#define TIMELIB_ERR_NO_THREE_DIGIT_MILLISECOND 0x21c
269+
#define TIMELIB_ERR_NO_FOUR_DIGIT_YEAR_ISO 0x21d
270+
#define TIMELIB_ERR_NO_TWO_DIGIT_WEEK 0x21e
271+
#define TIMELIB_ERR_INVALID_WEEK 0x21f
272+
#define TIMELIB_ERR_NO_DAY_OF_WEEK 0x220
273+
#define TIMELIB_ERR_INVALID_DAY_OF_WEEK 0x221
274+
#define TIMELIB_ERR_INVALID_SPECIFIER 0x222
275+
#define TIMELIB_ERR_INVALID_TZ_OFFSET 0x223
276+
#define TIMELIB_ERR_FORMAT_LITERAL_MISMATCH 0x224
277+
#define TIMELIB_ERR_MIX_ISO_WITH_NATURAL 0x225
267278

268279
#define TIMELIB_ZONETYPE_OFFSET 1
269280
#define TIMELIB_ZONETYPE_ABBR 2
@@ -310,9 +321,9 @@ typedef struct _timelib_tzdb {
310321
# define timelib_free free
311322
#endif
312323

313-
#define TIMELIB_VERSION 201706
314-
#define TIMELIB_EXTENDED_VERSION 20170600
315-
#define TIMELIB_ASCII_VERSION "2017.06"
324+
#define TIMELIB_VERSION 201801
325+
#define TIMELIB_EXTENDED_VERSION 20180002
326+
#define TIMELIB_ASCII_VERSION "2018.01alpha2"
316327

317328
#define TIMELIB_NONE 0x00
318329
#define TIMELIB_OVERRIDE_TIME 0x01
@@ -334,6 +345,60 @@ typedef struct _timelib_tzdb {
334345
extern "C" {
335346
#endif
336347

348+
typedef enum _timelib_format_specifier_code {
349+
TIMELIB_FORMAT_ALLOW_EXTRA_CHARACTERS = 0,
350+
TIMELIB_FORMAT_ANY_SEPARATOR,
351+
TIMELIB_FORMAT_DAY_TWO_DIGIT,
352+
TIMELIB_FORMAT_DAY_TWO_DIGIT_PADDED,
353+
TIMELIB_FORMAT_DAY_OF_WEEK_ISO,
354+
TIMELIB_FORMAT_DAY_OF_WEEK,
355+
TIMELIB_FORMAT_DAY_OF_YEAR,
356+
TIMELIB_FORMAT_DAY_SUFFIX,
357+
TIMELIB_FORMAT_END,
358+
TIMELIB_FORMAT_EPOCH_SECONDS,
359+
TIMELIB_FORMAT_ESCAPE,
360+
TIMELIB_FORMAT_HOUR_TWO_DIGIT_12_MAX,
361+
TIMELIB_FORMAT_HOUR_TWO_DIGIT_12_MAX_PADDED,
362+
TIMELIB_FORMAT_HOUR_TWO_DIGIT_24_MAX,
363+
TIMELIB_FORMAT_HOUR_TWO_DIGIT_24_MAX_PADDED,
364+
TIMELIB_FORMAT_LITERAL,
365+
TIMELIB_FORMAT_MERIDIAN,
366+
TIMELIB_FORMAT_MICROSECOND_SIX_DIGIT,
367+
TIMELIB_FORMAT_MILLISECOND_THREE_DIGIT,
368+
TIMELIB_FORMAT_MINUTE_TWO_DIGIT,
369+
TIMELIB_FORMAT_MONTH_TWO_DIGIT,
370+
TIMELIB_FORMAT_MONTH_TWO_DIGIT_PADDED,
371+
TIMELIB_FORMAT_RANDOM_CHAR,
372+
TIMELIB_FORMAT_RESET_ALL,
373+
TIMELIB_FORMAT_RESET_ALL_WHEN_NOT_SET,
374+
TIMELIB_FORMAT_SECOND_TWO_DIGIT,
375+
TIMELIB_FORMAT_SEPARATOR,
376+
TIMELIB_FORMAT_SKIP_TO_SEPARATOR,
377+
TIMELIB_FORMAT_TEXTUAL_DAY_3_LETTER,
378+
TIMELIB_FORMAT_TEXTUAL_DAY_FULL,
379+
TIMELIB_FORMAT_TEXTUAL_MONTH_3_LETTER,
380+
TIMELIB_FORMAT_TEXTUAL_MONTH_FULL,
381+
TIMELIB_FORMAT_TIMEZONE_OFFSET,
382+
TIMELIB_FORMAT_TIMEZONE_OFFSET_MINUTES,
383+
TIMELIB_FORMAT_WEEK_OF_YEAR_ISO,
384+
TIMELIB_FORMAT_WEEK_OF_YEAR,
385+
TIMELIB_FORMAT_WHITESPACE,
386+
TIMELIB_FORMAT_YEAR_TWO_DIGIT,
387+
TIMELIB_FORMAT_YEAR_FOUR_DIGIT,
388+
TIMELIB_FORMAT_YEAR_ISO
389+
} timelib_format_specifier_code;
390+
391+
typedef struct _timelib_format_specifier {
392+
char specifier;
393+
timelib_format_specifier_code code;
394+
} timelib_format_specifier;
395+
396+
typedef struct _timelib_format_config {
397+
const timelib_format_specifier *format_map;
398+
/* Format speciifiers must be preceded by 'prefix_char' if not '\0'. */
399+
char prefix_char;
400+
} timelib_format_config;
401+
337402
/* Function pointers */
338403
typedef timelib_tzinfo* (*timelib_tz_get_wrapper)(char *tzname, const timelib_tzdb *tzdb, int *error_code);
339404

@@ -416,6 +481,20 @@ timelib_time *timelib_strtotime(char *s, size_t len, timelib_error_container **e
416481
*/
417482
timelib_time *timelib_parse_from_format(char *format, char *s, size_t len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper);
418483

484+
/* Parses the date/time string in 's' with length 'len' into the constituent
485+
* parts of timelib_time* according to the format in 'format' with format
486+
* specifier configuration 'format_config'.
487+
*
488+
* 'format_map' is an array of pairs, with the first element being the format
489+
* specifier as a character and the second element corresponds to the
490+
* representation of the specifier from the enum list
491+
* 'timelib_format_specifier_code'.
492+
*
493+
* Note: 'format_map' must be terminated with specifier '\0' to indicate to the
494+
* parser that there are no more format specifiers in the list.
495+
*/
496+
timelib_time *timelib_parse_from_format_with_map(char *format, char *s, size_t len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper, const timelib_format_config* format_config);
497+
419498
/* Fills the gaps in the parsed timelib_time with information from the reference date/time in 'now'
420499
*
421500
* If any of the 'parsed' y, m, d, h, i or s parameters is unset (TIMELIB_UNSET):
@@ -488,8 +567,8 @@ timelib_long timelib_parse_zone(char **ptr, int *dst, timelib_time *t, int *tz_n
488567
*/
489568
void timelib_strtointerval(char *s, size_t len,
490569
timelib_time **begin, timelib_time **end,
491-
timelib_rel_time **period, int *recurrences,
492-
timelib_error_container **errors);
570+
timelib_rel_time **period, int *recurrences,
571+
timelib_error_container **errors);
493572

494573

495574
/* From tm2unixtime.c */
@@ -630,7 +709,7 @@ int timelib_timestamp_is_in_dst(timelib_sll ts, timelib_tzinfo *tz);
630709
* The returned information contains: the offset in seconds East of UTC (in
631710
* 'offset'), whether DST is active ('is_dst'), what the current time zone
632711
* abbreviation is ('abbr') and the transition time that got to this state (in
633-
* 'transistion_time');
712+
* 'transition_time');
634713
*/
635714
timelib_time_offset *timelib_get_time_zone_info(timelib_sll ts, timelib_tzinfo *tz);
636715

ext/date/lib/timezonemap.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,9 @@
155155
{ "bmt", 0, 25632, "Asia/Jakarta" },
156156
{ "bmt", 0, 6264, "Europe/Bucharest" },
157157
{ "bmt", 0, 6264, "Europe/Chisinau" },
158-
{ "bost", 1, -12756, "America/La_Paz" },
159158
{ "bst", 1, 3600, "Europe/London" },
160159
{ "bst", 0, 3600, "Europe/London" },
160+
{ "bst", 1, -12756, "America/La_Paz" },
161161
{ "bst", 0, -39600, "America/Adak" },
162162
{ "bst", 0, -39600, "America/Atka" },
163163
{ "bst", 0, -39600, "America/Nome" },
@@ -672,6 +672,9 @@
672672
{ "gmt", 0, 0, "Europe/Jersey" },
673673
{ "gmt", 0, 0, "Europe/London" },
674674
{ "gmt", 0, 0, "GB" },
675+
{ "gmt", 1, 0, "Europe/Bratislava" },
676+
{ "gmt", 1, 0, "Europe/Dublin" },
677+
{ "gmt", 1, 0, "Europe/Prague" },
675678
{ "gst", 0, 36000, "Pacific/Guam" },
676679
{ "gst", 0, 36000, "Pacific/Saipan" },
677680
{ "hdt", 1, -34200, "Pacific/Honolulu" },
@@ -728,8 +731,8 @@
728731
{ "kdt", 1, 34200, "ROK" },
729732
{ "kdt", 1, 36000, "ROK" },
730733
{ "kmt", 0, 5736, "Europe/Vilnius" },
731-
{ "kmt", 0, -18431, "America/Grand_Turk" },
732-
{ "kmt", 0, -18431, "America/Jamaica" },
734+
{ "kmt", 0, -18430, "America/Grand_Turk" },
735+
{ "kmt", 0, -18430, "America/Jamaica" },
733736
{ "kmt", 0, 7324, "Europe/Kiev" },
734737
{ "kst", 0, 30600, "Asia/Seoul" },
735738
{ "kst", 0, 32400, "Asia/Pyongyang" },
@@ -764,7 +767,7 @@
764767
{ "mdt", 1, -21600, "Mexico/BajaSur" },
765768
{ "mmt", 0, 9017, "Europe/Moscow" },
766769
{ "mmt", 0, 9079, "Europe/Moscow" },
767-
{ "mmt", 0, -13484, "America/Montevideo" },
770+
{ "mmt", 0, -13491, "America/Montevideo" },
768771
{ "mmt", 0, -20712, "America/Managua" },
769772
{ "mmt", 0, -2588, "Africa/Monrovia" },
770773
{ "mmt", 0, -2670, "Africa/Monrovia" },
@@ -1042,7 +1045,8 @@
10421045
{ "wat", 0, 3600, "Africa/Ndjamena" },
10431046
{ "wat", 0, 3600, "Africa/Niamey" },
10441047
{ "wat", 0, 3600, "Africa/Porto-Novo" },
1045-
{ "wat", 0, 3600, "Africa/Windhoek" },
1048+
{ "wat", 0, 3600, "Africa/Sao_Tome" },
1049+
{ "wat", 1, 3600, "Africa/Windhoek" },
10461050
{ "wemt", 1, 7200, "Europe/Lisbon" },
10471051
{ "wemt", 1, 7200, "Europe/Madrid" },
10481052
{ "wemt", 1, 7200, "Europe/Monaco" },

ext/date/lib/tm2unixtime.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static void do_range_limit_fraction(timelib_sll *fraction, timelib_sll *seconds)
3939
*fraction += 1000000;
4040
*seconds -= 1;
4141
}
42-
if (*fraction > 1000000) {
42+
if (*fraction >= 1000000) {
4343
*fraction -= 1000000;
4444
*seconds += 1;
4545
}

ext/date/lib/unixtime2tm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ void timelib_unixtime2gmt(timelib_time* tm, timelib_sll ts)
9696
}
9797
TIMELIB_DEBUG(printf("A: ts=%lld, year=%lld, month=%lld, day=%lld,", ts, cur_year, i + 1, tmp_days - months[i]););
9898

99-
/* That was the date, now we do the tiiiime */
99+
/* That was the date, now we do the time */
100100
hours = remainder / 3600;
101101
minutes = (remainder - hours * 3600) / 60;
102102
seconds = remainder % 60;
@@ -251,7 +251,7 @@ void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz)
251251

252252
/* Converts the time stored in the struct to localtime if localtime = true,
253253
* otherwise it converts it to gmttime. This is only done when necessary
254-
* ofcourse. */
254+
* of course. */
255255
int timelib_apply_localtime(timelib_time *t, unsigned int localtime)
256256
{
257257
if (localtime) {

0 commit comments

Comments
 (0)