Skip to content

Commit 66b0d17

Browse files
committed
Merge branch 'PHP-5.5' into PHP-5.6
2 parents 2cb0e1e + 5f09944 commit 66b0d17

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

ext/date/php_date.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,12 +1989,25 @@ zend_object_iterator *date_object_period_get_iterator(zend_class_entry *ce, zval
19891989
return (zend_object_iterator*)iterator;
19901990
}
19911991

1992+
static int implement_date_interface_handler(zend_class_entry *interface, zend_class_entry *implementor TSRMLS_DC)
1993+
{
1994+
if (implementor->type == ZEND_USER_CLASS &&
1995+
!instanceof_function(implementor, date_ce_date TSRMLS_CC) &&
1996+
!instanceof_function(implementor, date_ce_immutable TSRMLS_CC)
1997+
) {
1998+
zend_error(E_ERROR, "DateTimeInterface can't be implemented by user classes");
1999+
}
2000+
2001+
return SUCCESS;
2002+
}
2003+
19922004
static void date_register_classes(TSRMLS_D)
19932005
{
19942006
zend_class_entry ce_date, ce_immutable, ce_timezone, ce_interval, ce_period, ce_interface;
19952007

19962008
INIT_CLASS_ENTRY(ce_interface, "DateTimeInterface", date_funcs_interface);
19972009
date_ce_interface = zend_register_internal_interface(&ce_interface TSRMLS_CC);
2010+
date_ce_interface->interface_gets_implemented = implement_date_interface_handler;
19982011

19992012
INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
20002013
ce_date.create_object = date_object_new_date;
@@ -3612,13 +3625,13 @@ PHP_FUNCTION(date_diff)
36123625
php_interval_obj *interval;
36133626
long absolute = 0;
36143627

3615-
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &object1, date_ce_date, &object2, date_ce_date, &absolute) == FAILURE) {
3628+
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &object1, date_ce_interface, &object2, date_ce_interface, &absolute) == FAILURE) {
36163629
RETURN_FALSE;
36173630
}
36183631
dateobj1 = (php_date_obj *) zend_object_store_get_object(object1 TSRMLS_CC);
36193632
dateobj2 = (php_date_obj *) zend_object_store_get_object(object2 TSRMLS_CC);
3620-
DATE_CHECK_INITIALIZED(dateobj1->time, DateTime);
3621-
DATE_CHECK_INITIALIZED(dateobj2->time, DateTime);
3633+
DATE_CHECK_INITIALIZED(dateobj1->time, DateTimeInterface);
3634+
DATE_CHECK_INITIALIZED(dateobj2->time, DateTimeInterface);
36223635
timelib_update_ts(dateobj1->time, NULL);
36233636
timelib_update_ts(dateobj2->time, NULL);
36243637

@@ -4396,7 +4409,7 @@ PHP_METHOD(DatePeriod, __construct)
43964409

43974410
zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
43984411
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOl|l", &start, date_ce_interface, &interval, date_ce_interval, &recurrences, &options) == FAILURE) {
4399-
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_date, &options) == FAILURE) {
4412+
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_interface, &options) == FAILURE) {
44004413
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &isostr, &isostr_len, &options) == FAILURE) {
44014414
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments.");
44024415
zend_restore_error_handling(&error_handling TSRMLS_CC);

tests/classes/bug65768.phpt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Bug #65768: date_diff accepts only DateTime instance even though docs say about DateTimeInterface
3+
--INI--
4+
date.timezone=Europe/London
5+
--FILE--
6+
<?php
7+
8+
$dt1 = new DateTime("2010-10-20");
9+
$dti1 = new DateTimeImmutable("2010-10-25");
10+
$dti2 = new DateTimeImmutable("2010-10-28");
11+
12+
$diff1 = $dt1->diff($dti1);
13+
echo $diff1->y, " ", $diff1->m, " ", $diff1->d, " ",
14+
$diff1->h, " ", $diff1->i, " ", $diff1->s, "\n";
15+
16+
$diff2 = $dti1->diff($dti2);
17+
echo $diff2->y, " ", $diff2->m, " ", $diff2->d, " ",
18+
$diff2->h, " ", $diff2->i, " ", $diff2->s, "\n";
19+
20+
$diff3 = date_diff($dt1, $dti2);
21+
echo $diff3->y, " ", $diff3->m, " ", $diff3->d, " ",
22+
$diff3->h, " ", $diff3->i, " ", $diff3->s, "\n";
23+
24+
class cdt1 extends DateTime implements DateTimeInterface {}
25+
26+
class cdt2 extends DateTimeImmutable implements DateTimeInterface {}
27+
28+
class cdt3 implements DateTimeInterface {}
29+
30+
?>
31+
--EXPECTF--
32+
0 0 5 0 0 0
33+
0 0 3 0 0 0
34+
0 0 8 0 0 0
35+
36+
Fatal error: DateTimeInterface can't be implemented by user classes in %sbug65768.php on line %d

0 commit comments

Comments
 (0)