mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fixed bug #65768: DateTimeImmutable::diff does not work
This commit also prevents user classes from directly implementing DateTimeInterface, because ext/date relies on classes implementing it to support certain internal structures.
This commit is contained in:
parent
967abd6153
commit
5f09944662
3 changed files with 54 additions and 4 deletions
1
NEWS
1
NEWS
|
@ -7,6 +7,7 @@ PHP NEWS
|
||||||
|
|
||||||
- Date:
|
- Date:
|
||||||
. Fixed bug #66060 (Heap buffer over-read in DateInterval). (Remi)
|
. Fixed bug #66060 (Heap buffer over-read in DateInterval). (Remi)
|
||||||
|
. Fixed bug #65768 (DateTimeImmutable::diff does not work). (Nikita Nefedov)
|
||||||
|
|
||||||
?? ??? 2013, PHP 5.5.7
|
?? ??? 2013, PHP 5.5.7
|
||||||
|
|
||||||
|
|
|
@ -1989,12 +1989,25 @@ zend_object_iterator *date_object_period_get_iterator(zend_class_entry *ce, zval
|
||||||
return (zend_object_iterator*)iterator;
|
return (zend_object_iterator*)iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int implement_date_interface_handler(zend_class_entry *interface, zend_class_entry *implementor TSRMLS_DC)
|
||||||
|
{
|
||||||
|
if (implementor->type == ZEND_USER_CLASS &&
|
||||||
|
!instanceof_function(implementor, date_ce_date TSRMLS_CC) &&
|
||||||
|
!instanceof_function(implementor, date_ce_immutable TSRMLS_CC)
|
||||||
|
) {
|
||||||
|
zend_error(E_ERROR, "DateTimeInterface can't be implemented by user classes");
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static void date_register_classes(TSRMLS_D)
|
static void date_register_classes(TSRMLS_D)
|
||||||
{
|
{
|
||||||
zend_class_entry ce_date, ce_immutable, ce_timezone, ce_interval, ce_period, ce_interface;
|
zend_class_entry ce_date, ce_immutable, ce_timezone, ce_interval, ce_period, ce_interface;
|
||||||
|
|
||||||
INIT_CLASS_ENTRY(ce_interface, "DateTimeInterface", date_funcs_interface);
|
INIT_CLASS_ENTRY(ce_interface, "DateTimeInterface", date_funcs_interface);
|
||||||
date_ce_interface = zend_register_internal_interface(&ce_interface TSRMLS_CC);
|
date_ce_interface = zend_register_internal_interface(&ce_interface TSRMLS_CC);
|
||||||
|
date_ce_interface->interface_gets_implemented = implement_date_interface_handler;
|
||||||
|
|
||||||
INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
|
INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
|
||||||
ce_date.create_object = date_object_new_date;
|
ce_date.create_object = date_object_new_date;
|
||||||
|
@ -3612,13 +3625,13 @@ PHP_FUNCTION(date_diff)
|
||||||
php_interval_obj *interval;
|
php_interval_obj *interval;
|
||||||
long absolute = 0;
|
long absolute = 0;
|
||||||
|
|
||||||
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &object1, date_ce_date, &object2, date_ce_date, &absolute) == FAILURE) {
|
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &object1, date_ce_interface, &object2, date_ce_interface, &absolute) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
dateobj1 = (php_date_obj *) zend_object_store_get_object(object1 TSRMLS_CC);
|
dateobj1 = (php_date_obj *) zend_object_store_get_object(object1 TSRMLS_CC);
|
||||||
dateobj2 = (php_date_obj *) zend_object_store_get_object(object2 TSRMLS_CC);
|
dateobj2 = (php_date_obj *) zend_object_store_get_object(object2 TSRMLS_CC);
|
||||||
DATE_CHECK_INITIALIZED(dateobj1->time, DateTime);
|
DATE_CHECK_INITIALIZED(dateobj1->time, DateTimeInterface);
|
||||||
DATE_CHECK_INITIALIZED(dateobj2->time, DateTime);
|
DATE_CHECK_INITIALIZED(dateobj2->time, DateTimeInterface);
|
||||||
timelib_update_ts(dateobj1->time, NULL);
|
timelib_update_ts(dateobj1->time, NULL);
|
||||||
timelib_update_ts(dateobj2->time, NULL);
|
timelib_update_ts(dateobj2->time, NULL);
|
||||||
|
|
||||||
|
@ -4396,7 +4409,7 @@ PHP_METHOD(DatePeriod, __construct)
|
||||||
|
|
||||||
zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
|
zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
|
||||||
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) {
|
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) {
|
||||||
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) {
|
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) {
|
||||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &isostr, &isostr_len, &options) == FAILURE) {
|
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &isostr, &isostr_len, &options) == FAILURE) {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments.");
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments.");
|
||||||
zend_restore_error_handling(&error_handling TSRMLS_CC);
|
zend_restore_error_handling(&error_handling TSRMLS_CC);
|
||||||
|
|
36
tests/classes/bug65768.phpt
Normal file
36
tests/classes/bug65768.phpt
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #65768: date_diff accepts only DateTime instance even though docs say about DateTimeInterface
|
||||||
|
--INI--
|
||||||
|
date.timezone=Europe/London
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$dt1 = new DateTime("2010-10-20");
|
||||||
|
$dti1 = new DateTimeImmutable("2010-10-25");
|
||||||
|
$dti2 = new DateTimeImmutable("2010-10-28");
|
||||||
|
|
||||||
|
$diff1 = $dt1->diff($dti1);
|
||||||
|
echo $diff1->y, " ", $diff1->m, " ", $diff1->d, " ",
|
||||||
|
$diff1->h, " ", $diff1->i, " ", $diff1->s, "\n";
|
||||||
|
|
||||||
|
$diff2 = $dti1->diff($dti2);
|
||||||
|
echo $diff2->y, " ", $diff2->m, " ", $diff2->d, " ",
|
||||||
|
$diff2->h, " ", $diff2->i, " ", $diff2->s, "\n";
|
||||||
|
|
||||||
|
$diff3 = date_diff($dt1, $dti2);
|
||||||
|
echo $diff3->y, " ", $diff3->m, " ", $diff3->d, " ",
|
||||||
|
$diff3->h, " ", $diff3->i, " ", $diff3->s, "\n";
|
||||||
|
|
||||||
|
class cdt1 extends DateTime implements DateTimeInterface {}
|
||||||
|
|
||||||
|
class cdt2 extends DateTimeImmutable implements DateTimeInterface {}
|
||||||
|
|
||||||
|
class cdt3 implements DateTimeInterface {}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
0 0 5 0 0 0
|
||||||
|
0 0 3 0 0 0
|
||||||
|
0 0 8 0 0 0
|
||||||
|
|
||||||
|
Fatal error: DateTimeInterface can't be implemented by user classes in %sbug65768.php on line %d
|
Loading…
Add table
Add a link
Reference in a new issue