Skip to content

Commit

Permalink
ext/intl: Call DateTimeInterface::getTimestamp() directly (#17487)
Browse files Browse the repository at this point in the history
  • Loading branch information
Girgias authored Jan 19, 2025
1 parent b8ee4c2 commit a100450
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 29 deletions.
39 changes: 19 additions & 20 deletions ext/intl/common/common_date.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,11 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type,
}
/* }}} */

U_CFUNC int intl_datetime_decompose(zval *z, double *millis, TimeZone **tz,
U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, TimeZone **tz,
intl_error *err, const char *func)
{
zval retval;
zval zfuncname;
char *message;
php_date_obj *datetime = php_date_obj_from_obj(obj);

if (err && U_FAILURE(err->code)) {
return FAILURE;
Expand All @@ -109,35 +108,35 @@ U_CFUNC int intl_datetime_decompose(zval *z, double *millis, TimeZone **tz,
*millis = ZEND_NAN;
}
if (tz) {
*tz = NULL;
*tz = nullptr;
}

if (millis) {
php_date_obj *datetime;

ZVAL_STRING(&zfuncname, "getTimestamp");
if (call_user_function(NULL, z, &zfuncname, &retval, 0, NULL)
!= SUCCESS || Z_TYPE(retval) != IS_LONG) {
spprintf(&message, 0, "%s: error calling ::getTimeStamp() on the "
"object", func);
intl_errors_set(err, U_INTERNAL_PROGRAM_ERROR,
message, 1);
auto getTimestampMethod = static_cast<zend_function *>(zend_hash_str_find_ptr(&obj->ce->function_table, ZEND_STRL("gettimestamp")));
zval retval;

ZEND_ASSERT(getTimestampMethod && "DateTimeInterface is sealed and thus must have this method");
zend_call_known_function(getTimestampMethod, obj, obj->ce, &retval, 0, nullptr, nullptr);

/* An exception has occurred */
if (Z_TYPE(retval) == IS_UNDEF) {
return FAILURE;
}
// TODO: Remove this when DateTimeInterface::getTimestamp() no longer has a tentative return type
if (Z_TYPE(retval) != IS_LONG) {
spprintf(&message, 0, "%s: %s::getTimestamp() did not return an int", func, ZSTR_VAL(obj->ce->name));
intl_errors_set(err, U_INTERNAL_PROGRAM_ERROR, message, 1);
efree(message);
zval_ptr_dtor(&zfuncname);
return FAILURE;
}

datetime = Z_PHPDATE_P(z);
*millis = U_MILLIS_PER_SECOND * (double)Z_LVAL(retval) + (datetime->time->us / 1000);
zval_ptr_dtor(&zfuncname);
}

if (tz) {
php_date_obj *datetime;
datetime = Z_PHPDATE_P(z);
if (!datetime->time) {
spprintf(&message, 0, "%s: the %s object is not properly "
"initialized", func, ZSTR_VAL(Z_OBJCE_P(z)->name));
"initialized", func, ZSTR_VAL(obj->ce->name));
intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
message, 1);
efree(message);
Expand Down Expand Up @@ -198,7 +197,7 @@ U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func)
break;
case IS_OBJECT:
if (instanceof_function(Z_OBJCE_P(z), php_date_get_interface_ce())) {
intl_datetime_decompose(z, &rv, NULL, err, func);
intl_datetime_decompose(Z_OBJ_P(z), &rv, nullptr, err, func);
} else if (instanceof_function(Z_OBJCE_P(z), Calendar_ce_ptr)) {
Calendar_object *co = Z_INTL_CALENDAR_P(z);
if (co->ucal == NULL) {
Expand Down
3 changes: 1 addition & 2 deletions ext/intl/common/common_date.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ U_CDECL_END
using icu::TimeZone;

U_CFUNC TimeZone *timezone_convert_datetimezone(int type, void *object, int is_datetime, intl_error *outside_error, const char *func);
U_CFUNC int intl_datetime_decompose(zval *z, double *millis, TimeZone **tz,
intl_error *err, const char *func);
U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, TimeZone **tz, intl_error *err, const char *func);

#endif

Expand Down
10 changes: 5 additions & 5 deletions ext/intl/dateformat/dateformat_format_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ static bool valid_format(zval *z) {

U_CFUNC PHP_FUNCTION(datefmt_format_object)
{
zval *object,
*format = NULL;
zend_object *object;
zval *format = NULL;
char *locale_str = NULL;
size_t locale_len;
bool pattern = false;
Expand All @@ -78,7 +78,7 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object)
timeStyle = DateFormat::kDefault;

ZEND_PARSE_PARAMETERS_START(1, 3)
Z_PARAM_OBJECT(object)
Z_PARAM_OBJ(object)
Z_PARAM_OPTIONAL
Z_PARAM_ZVAL(format)
Z_PARAM_STRING_OR_NULL(locale_str, locale_len)
Expand Down Expand Up @@ -149,9 +149,9 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object)
timeStyle = (DateFormat::EStyle)(timeStyle & ~DateFormat::kRelative);
}

zend_class_entry *instance_ce = Z_OBJCE_P(object);
zend_class_entry *instance_ce = object->ce;
if (instanceof_function(instance_ce, Calendar_ce_ptr)) {
Calendar *obj_cal = calendar_fetch_native_calendar(Z_OBJ_P(object));
Calendar *obj_cal = calendar_fetch_native_calendar(object);
if (obj_cal == NULL) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"datefmt_format_object: bad IntlCalendar instance: "
Expand Down
2 changes: 0 additions & 2 deletions ext/intl/tests/dateformat_formatObject_error.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ bool(false)

Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad IntlCalendar instance: not initialized properly in %s on line %d
bool(false)

Warning: IntlDateFormatter::formatObject(): datefmt_format_object: error calling ::getTimeStamp() on the object in %s on line %d
Object of type B (inheriting DateTime) has not been correctly initialized by calling parent::__construct() in its constructor

Warning: IntlDateFormatter::formatObject(): datefmt_format_object: the date/time format type is invalid in %s on line %d
Expand Down

0 comments on commit a100450

Please sign in to comment.