Skip to content

Commit 0747616

Browse files
committed
Fixed GH-11368: Date modify returns invalid datetime
1 parent f160eff commit 0747616

File tree

4 files changed

+50
-14
lines changed

4 files changed

+50
-14
lines changed

NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.1.22
44

5+
- Date:
6+
. Fixed bug GH-11368 (Date modify returns invalid datetime). (Derick)
7+
58
- PCRE:
69
. Mangle PCRE regex cache key with JIT option. (mvorisek)
710

ext/date/lib/timelib.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ typedef struct _timelib_tzdb {
378378
#define TIMELIB_OVERRIDE_TIME 0x01
379379
#define TIMELIB_NO_CLONE 0x02
380380

381-
#define TIMELIB_UNSET -99999
381+
#define TIMELIB_UNSET -9999999
382382

383383
/* An entry for each of these error codes is also in the
384384
* timelib_error_messages array in timelib.c.

ext/date/php_date.c

+13-13
Original file line numberDiff line numberDiff line change
@@ -2100,7 +2100,7 @@ static HashTable *date_object_get_properties_interval(zend_object *object) /* {{
21002100
PHP_DATE_INTERVAL_ADD_PROPERTY("weekday_behavior", weekday_behavior);
21012101
PHP_DATE_INTERVAL_ADD_PROPERTY("first_last_day_of", first_last_day_of);
21022102
PHP_DATE_INTERVAL_ADD_PROPERTY("invert", invert);
2103-
if (intervalobj->diff->days != -99999) {
2103+
if (intervalobj->diff->days != TIMELIB_UNSET) {
21042104
PHP_DATE_INTERVAL_ADD_PROPERTY("days", days);
21052105
} else {
21062106
ZVAL_FALSE(&zv);
@@ -2733,7 +2733,7 @@ void php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAMETERS, timelib_time *
27332733

27342734
array_init(return_value);
27352735
#define PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(name, elem) \
2736-
if (parsed_time->elem == -99999) { \
2736+
if (parsed_time->elem == TIMELIB_UNSET) { \
27372737
add_assoc_bool(return_value, #name, 0); \
27382738
} else { \
27392739
add_assoc_long(return_value, #name, parsed_time->elem); \
@@ -2745,7 +2745,7 @@ void php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAMETERS, timelib_time *
27452745
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(minute, i);
27462746
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(second, s);
27472747

2748-
if (parsed_time->us == -99999) {
2748+
if (parsed_time->us == TIMELIB_UNSET) {
27492749
add_assoc_bool(return_value, "fraction", 0);
27502750
} else {
27512751
add_assoc_double(return_value, "fraction", (double)parsed_time->us / 1000000.0);
@@ -2880,21 +2880,21 @@ static int php_date_modify(zval *object, char *modify, size_t modify_len) /* {{{
28802880
dateobj->time->have_relative = tmp_time->have_relative;
28812881
dateobj->time->sse_uptodate = 0;
28822882

2883-
if (tmp_time->y != -99999) {
2883+
if (tmp_time->y != TIMELIB_UNSET) {
28842884
dateobj->time->y = tmp_time->y;
28852885
}
2886-
if (tmp_time->m != -99999) {
2886+
if (tmp_time->m != TIMELIB_UNSET) {
28872887
dateobj->time->m = tmp_time->m;
28882888
}
2889-
if (tmp_time->d != -99999) {
2889+
if (tmp_time->d != TIMELIB_UNSET) {
28902890
dateobj->time->d = tmp_time->d;
28912891
}
28922892

2893-
if (tmp_time->h != -99999) {
2893+
if (tmp_time->h != TIMELIB_UNSET) {
28942894
dateobj->time->h = tmp_time->h;
2895-
if (tmp_time->i != -99999) {
2895+
if (tmp_time->i != TIMELIB_UNSET) {
28962896
dateobj->time->i = tmp_time->i;
2897-
if (tmp_time->s != -99999) {
2897+
if (tmp_time->s != TIMELIB_UNSET) {
28982898
dateobj->time->s = tmp_time->s;
28992899
} else {
29002900
dateobj->time->s = 0;
@@ -2905,7 +2905,7 @@ static int php_date_modify(zval *object, char *modify, size_t modify_len) /* {{{
29052905
}
29062906
}
29072907

2908-
if (tmp_time->us != -99999) {
2908+
if (tmp_time->us != TIMELIB_UNSET) {
29092909
dateobj->time->us = tmp_time->us;
29102910
}
29112911

@@ -3914,7 +3914,7 @@ static zval *date_interval_read_property(zend_object *object, zend_string *name,
39143914

39153915
if (fvalue != -1) {
39163916
ZVAL_DOUBLE(retval, fvalue);
3917-
} else if (value != -99999) {
3917+
} else if (value != TIMELIB_UNSET) {
39183918
ZVAL_LONG(retval, value);
39193919
} else {
39203920
ZVAL_FALSE(retval);
@@ -4039,7 +4039,7 @@ static int php_date_interval_initialize_from_hash(zval **return_value, php_inter
40394039
do { \
40404040
zval *z_arg = zend_hash_str_find(myht, "days", sizeof("days") - 1); \
40414041
if (z_arg && Z_TYPE_P(z_arg) == IS_FALSE) { \
4042-
(*intobj)->diff->member = -99999; \
4042+
(*intobj)->diff->member = TIMELIB_UNSET; \
40434043
} else if (z_arg && Z_TYPE_P(z_arg) <= IS_STRING) { \
40444044
zend_string *str = zval_get_string(z_arg); \
40454045
DATE_A64I((*intobj)->diff->member, ZSTR_VAL(str)); \
@@ -4199,7 +4199,7 @@ static zend_string *date_interval_format(char *format, size_t format_len, timeli
41994199
case 'f': length = slprintf(buffer, sizeof(buffer), ZEND_LONG_FMT, (zend_long) t->us); break;
42004200

42014201
case 'a': {
4202-
if ((int) t->days != -99999) {
4202+
if ((int) t->days != TIMELIB_UNSET) {
42034203
length = slprintf(buffer, sizeof(buffer), "%d", (int) t->days);
42044204
} else {
42054205
length = slprintf(buffer, sizeof(buffer), "(unknown)");

ext/date/tests/bug-gh11368.phpt

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug GH-11368: Date modify returns invalid datetime
3+
--INI--
4+
date.timezone=UTC
5+
--FILE--
6+
<?php
7+
8+
$datetime = date_create('2023-06-04');
9+
10+
$datetime->setTime(1,1,1,1 /* If set to any other number, it works fine */);
11+
var_dump($datetime);
12+
13+
$datetime->modify('-100 ms');
14+
var_dump($datetime);
15+
16+
?>
17+
--EXPECTF--
18+
object(DateTime)#1 (3) {
19+
["date"]=>
20+
string(26) "2023-06-04 01:01:01.000001"
21+
["timezone_type"]=>
22+
int(3)
23+
["timezone"]=>
24+
string(3) "UTC"
25+
}
26+
object(DateTime)#1 (3) {
27+
["date"]=>
28+
string(26) "2023-06-04 01:01:00.900001"
29+
["timezone_type"]=>
30+
int(3)
31+
["timezone"]=>
32+
string(3) "UTC"
33+
}

0 commit comments

Comments
 (0)