Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 44 additions & 27 deletions ext/date/php_date.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -550,7 +550,7 @@ PHPAPI timelib_tzinfo *get_timezone_info(void)
tz = guess_timezone(DATE_TIMEZONEDB);
tzi = php_date_parse_tzfile(tz, DATE_TIMEZONEDB);
if (! tzi) {
php_error_docref(NULL, E_ERROR, "Timezone database is corrupt - this should *never* happen!");
zend_throw_error(NULL, "Timezone database is corrupt. Please file a bug report as this should never happen");
}
return tzi;
}
Expand DownExpand Up@@ -961,7 +961,7 @@ PHP_FUNCTION(idate)

ret = php_idate(ZSTR_VAL(format)[0], ts, 0);
if (ret == -1) {
php_error_docref(NULL, E_WARNING, "Unrecognized date format token.");
php_error_docref(NULL, E_WARNING, "Unrecognized date format token");
RETURN_FALSE;
}
RETURN_LONG(ret);
Expand DownExpand Up@@ -1009,7 +1009,7 @@ PHPAPI zend_long php_parse_date(const char *string, zend_long *now)
PHP_FUNCTION(strtotime)
{
zend_string *times;
int error1, error2;
int parse_error, epoch_does_not_fit_in_zend_long;
timelib_error_container *error;
zend_long preset_ts, ts;
zend_bool preset_ts_is_null = 1;
Expand All@@ -1022,6 +1022,11 @@ PHP_FUNCTION(strtotime)
Z_PARAM_LONG_OR_NULL(preset_ts, preset_ts_is_null)
ZEND_PARSE_PARAMETERS_END();

/* timelib_strtotime() expects the string to not be empty */
if (ZSTR_LEN(times) == 0) {
RETURN_FALSE;
}

tzi = get_timezone_info();

now = timelib_time_ctor();
Expand All@@ -1032,20 +1037,27 @@ PHP_FUNCTION(strtotime)

t = timelib_strtotime(ZSTR_VAL(times), ZSTR_LEN(times), &error,
DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
error1 = error->error_count;
parse_error = error->error_count;
timelib_error_container_dtor(error);
if (parse_error) {
timelib_time_dtor(now);
timelib_time_dtor(t);
RETURN_FALSE;
}

timelib_fill_holes(t, now, TIMELIB_NO_CLONE);
timelib_update_ts(t, tzi);
ts = timelib_date_to_int(t, &error2);
ts = timelib_date_to_int(t, &epoch_does_not_fit_in_zend_long);

timelib_time_dtor(now);
timelib_time_dtor(t);

if (error1 || error2) {
if (epoch_does_not_fit_in_zend_long) {
php_error_docref(NULL, E_WARNING, "Epoch doesn't fit in a PHP integer");
RETURN_FALSE;
} else {
RETURN_LONG(ts);
}

RETURN_LONG(ts);
}
/* }}} */

Expand All@@ -1057,7 +1069,7 @@ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
timelib_time *now;
timelib_tzinfo *tzi = NULL;
zend_long ts, adjust_seconds = 0;
int error;
int epoch_does_not_fit_in_zend_long;

ZEND_PARSE_PARAMETERS_START(1, 6)
Z_PARAM_LONG(hou)
Expand DownExpand Up@@ -1115,15 +1127,18 @@ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
}

/* Clean up and return */
ts = timelib_date_to_int(now, &error);
ts += adjust_seconds;
timelib_time_dtor(now);
ts = timelib_date_to_int(now, &epoch_does_not_fit_in_zend_long);

if (error) {
if (epoch_does_not_fit_in_zend_long) {
timelib_time_dtor(now);
php_error_docref(NULL, E_WARNING, "Epoch doesn't fit in a PHP integer");
RETURN_FALSE;
} else {
RETURN_LONG(ts);
}

ts += adjust_seconds;
timelib_time_dtor(now);

RETURN_LONG(ts);
}
/* }}} */

Expand DownExpand Up@@ -1224,7 +1239,6 @@ PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
ta.tm_zone = offset->abbr;
#endif
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: don't remove this empty line

/* VS2012 crt has a bug where strftime crash with %z and %Z format when the
initial buffer is too small. See
http://connect.microsoft.com/VisualStudio/feedback/details/759720/vs2012-strftime-crash-with-z-formatting-code */
Expand DownExpand Up@@ -2781,7 +2795,7 @@ static int php_date_modify(zval *object, char *modify, size_t modify_len) /* {{{
dateobj = Z_PHPDATE_P(object);

if (!(dateobj->time)) {
php_error_docref(NULL, E_WARNING, "The DateTime object has not been correctly initialized by its constructor");
zend_throw_error(NULL, "The DateTime object has not been correctly initialized by its constructor");
return 0;
}

Expand DownExpand Up@@ -3309,7 +3323,7 @@ PHP_FUNCTION(date_timestamp_get)
zval *object;
php_date_obj *dateobj;
zend_long timestamp;
int error;
int epoch_does_not_fit_in_zend_long;

if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &object, date_ce_interface) == FAILURE) {
RETURN_THROWS();
Expand All@@ -3318,12 +3332,14 @@ PHP_FUNCTION(date_timestamp_get)
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
timelib_update_ts(dateobj->time, NULL);

timestamp = timelib_date_to_int(dateobj->time, &error);
if (error) {
RETURN_FALSE;
} else {
RETVAL_LONG(timestamp);
timestamp = timelib_date_to_int(dateobj->time, &epoch_does_not_fit_in_zend_long);

if (epoch_does_not_fit_in_zend_long) {
zend_value_error("Epoch doesn't fit in a PHP integer");
RETURN_THROWS();
}

RETURN_LONG(timestamp);
Comment thread
derickr marked this conversation as resolved.
Outdated
}
/* }}} */

Expand DownExpand Up@@ -3387,7 +3403,7 @@ PHP_FUNCTION(timezone_open)
php_timezone_obj *tzobj;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STR(tz)
Z_PARAM_PATH_STR(tz) /* To prevent null bytes */
ZEND_PARSE_PARAMETERS_END();

tzobj = Z_PHPTIMEZONE_P(php_date_instantiate(date_ce_timezone, return_value));
Expand All@@ -3406,7 +3422,7 @@ PHP_METHOD(DateTimeZone, __construct)
zend_error_handling error_handling;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STR(tz)
Z_PARAM_PATH_STR(tz) /* To prevent null bytes */
ZEND_PARSE_PARAMETERS_END();

zend_replace_error_handling(EH_THROW, NULL, &error_handling);
Expand DownExpand Up@@ -4336,8 +4352,9 @@ PHP_FUNCTION(timezone_identifiers_list)

/* Extra validation */
if (what == PHP_DATE_TIMEZONE_PER_COUNTRY && option_len != 2) {
php_error_docref(NULL, E_NOTICE, "A two-letter ISO 3166-1 compatible country code is expected");
RETURN_FALSE;
zend_argument_value_error(2, "must be a two-letter ISO 3166-1 compatible country code "
"when argument #1 ($timezoneGroup) is DateTimeZone::PER_COUNTRY");
RETURN_THROWS();
}

tzdb = DATE_TIMEZONEDB;
Expand Down
8 changes: 4 additions & 4 deletions ext/date/php_date.stub.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,7 @@ function date_isodate_set(DateTime $object, int $year, int $week, int $day = 1):

function date_timestamp_set(DateTime $object, int $timestamp): DateTime {}

function date_timestamp_get(DateTimeInterface $object): int|false {}
function date_timestamp_get(DateTimeInterface $object): int {}
Comment thread
derickr marked this conversation as resolved.
Outdated

function timezone_open(string $timezone): DateTimeZone|false {}

Expand All@@ -88,7 +88,7 @@ function timezone_transitions_get(

function timezone_location_get(DateTimeZone $object): array|false {}

function timezone_identifiers_list(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array|false {}
function timezone_identifiers_list(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array {}

function timezone_abbreviations_list(): array {}

Expand DownExpand Up@@ -230,7 +230,7 @@ public function setISODate(int $year, int $week, int $dayOfWeek = 1) {}
public function setTimestamp(int $timestamp) {}

/**
* @return int|false
* @return int

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now it returns just an "int", can it not be set as a return type on the function (line 236) itself?

* @alias date_timestamp_get
*/
public function getTimestamp() {}
Expand DownExpand Up@@ -282,7 +282,7 @@ public function getTimezone() {}
public function getOffset() {}

/**
* @return int|false
* @return int

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

* @alias date_timestamp_get
*/
public function getTimestamp() {}
Expand Down
8 changes: 3 additions & 5 deletions ext/date/php_date_arginfo.h
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: fee95924adec03c89fdd677ec26bb6eea34d4b3c */
* Stub hash: cb1532309655d85eb2644cdcfbf23063dfa1ddaf */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0)
Expand DownExpand Up@@ -151,9 +151,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_date_timestamp_set, 0, 2, DateTim
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_date_timestamp_get, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_OBJ_INFO(0, object, DateTimeInterface, 0)
ZEND_END_ARG_INFO()
#define arginfo_date_timestamp_get arginfo_date_offset_get
Comment thread
derickr marked this conversation as resolved.
Outdated

ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_timezone_open, 0, 1, DateTimeZone, MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, timezone, IS_STRING, 0)
Expand DownExpand Up@@ -184,7 +182,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_timezone_location_get, 0, 1, MAY
ZEND_ARG_OBJ_INFO(0, object, DateTimeZone, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_timezone_identifiers_list, 0, 0, MAY_BE_ARRAY|MAY_BE_FALSE)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_timezone_identifiers_list, 0, 0, IS_ARRAY, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timezoneGroup, IS_LONG, 0, "DateTimeZone::ALL")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, countryCode, IS_STRING, 1, "null")
ZEND_END_ARG_INFO()
Expand Down
9 changes: 4 additions & 5 deletions ext/date/tests/005.phpt
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,27 +9,26 @@ $t = mktime(0,0,0, 6, 27, 2006);
var_dump(idate(1,1));
var_dump(idate(""));
var_dump(idate(0));

var_dump(idate("B", $t));
var_dump(idate("[", $t));
var_dump(idate("'"));

echo "Done\n";
?>
--EXPECTF--
Warning: idate(): Unrecognized date format token. in %s on line %d
Warning: idate(): Unrecognized date format token in %s on line %d
bool(false)

Warning: idate(): idate format is one char in %s on line %d
bool(false)

Warning: idate(): Unrecognized date format token. in %s on line %d
Warning: idate(): Unrecognized date format token in %s on line %d
bool(false)
int(41)

Warning: idate(): Unrecognized date format token. in %s on line %d
Warning: idate(): Unrecognized date format token in %s on line %d
bool(false)

Warning: idate(): Unrecognized date format token. in %s on line %d
Warning: idate(): Unrecognized date format token in %s on line %d
bool(false)
Done
4 changes: 3 additions & 1 deletion ext/date/tests/bug41523.phpt
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,7 +12,7 @@ var_dump( $dt = new DateTime('0000-00-00 00:00:00') );
echo $dt->format( DateTime::ISO8601 ), "\n";

?>
--EXPECT--
--EXPECTF--
array(12) {
["year"]=>
int(0)
Expand DownExpand Up@@ -43,6 +43,8 @@ array(12) {
["is_localtime"]=>
bool(false)
}

Warning: strtotime(): Epoch doesn't fit in a PHP integer in %s on line %d
bool(false)
object(DateTime)#1 (3) {
["date"]=>
Expand Down
16 changes: 12 additions & 4 deletions ext/date/tests/bug52062.phpt
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,11 @@ date.timezone=UTC
<?php
$d = new DateTime('@100000000000');
var_dump($d->format('Y-m-d H:i:s U'));
var_dump($d->getTimestamp());
try {
var_dump($d->getTimestamp());
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
var_dump($d->format('U'));

try {
Expand All@@ -19,16 +23,20 @@ try {
echo $e->getMessage(), "\n";
}
var_dump($d->format('Y-m-d H:i:s U'));
var_dump($d->getTimestamp());
try {
var_dump($d->getTimestamp());
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}

$i = new DateInterval('PT100000000000S');
var_dump($i->format('%s'));
?>
--EXPECT--
string(32) "5138-11-16 09:46:40 100000000000"
bool(false)
Epoch doesn't fit in a PHP integer
string(12) "100000000000"
DateTime::setTimestamp(): Argument #1 ($timestamp) must be of type int, float given
string(32) "5138-11-16 09:46:40 100000000000"
bool(false)
Epoch doesn't fit in a PHP integer
string(10) "1215752192"
24 changes: 13 additions & 11 deletions ext/date/tests/bug70277.phpt
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,15 +3,17 @@ Bug #70277 (new DateTimeZone($foo) is ignoring text after null byte)
--FILE--
<?php
$timezone = "Europe/Zurich\0Foo";
var_dump(timezone_open($timezone));
var_dump(new DateTimeZone($timezone));
try {
var_dump(timezone_open($timezone));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
try {
var_dump(new DateTimeZone($timezone));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
?>
--EXPECTF--
Warning: timezone_open(): Timezone must not contain null bytes in %sbug70277.php on line %d
bool(false)

Fatal error: Uncaught Exception: DateTimeZone::__construct(): Timezone must not contain null bytes in %sbug70277.php:%d
Stack trace:
#0 %sbug70277.php(%d): DateTimeZone->__construct('Europe/Zurich\x00F...')
#1 {main}
thrown in %sbug70277.php on line %d
--EXPECT--
timezone_open(): Argument #1 ($timezone) must not contain any null bytes
DateTimeZone::__construct(): Argument #1 ($timezone) must not contain any null bytes
Loading