-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix GH-14709 overflow on recurrences for DatePeriod::__construct #14710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Note : apparently needs adaptation with higher branches. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is more or less right: recurrences is an int in _php_period_obj
so we can't store a higher number. The issue isn't fully solved though because if include_start_date and include_end_date are set then you still get an integer overflow because you can add 2 to INT_MAX.
From a technical PoV this is right and stops the undefined behaviour. |
in fact I tried to separate to let know of the second edge case separately but yes it s not so urgent anyway we ll see :). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm with @nielsdos here — capping it at INT_MAX - 8
(in case we get further options), seems perfectly cromulent.
ext/date/php_date.c
Outdated
zend_string *func = get_active_function_or_method_name(); | ||
zend_throw_exception_ex(NULL, 0, "%s(): Recurrence count must be greater than 0", ZSTR_VAL(func)); | ||
zend_throw_exception_ex(NULL, 0, "%s(): Recurrence count must be between 1 and %d", ZSTR_VAL(func), INT_MAX); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
between 1
is ambiguous between > 1
or >= 1
. Please be precise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's standard wording (and always refers to the closed interval). cc @Girgias
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have always used it to mean an inclusive range AFAIK.
Might help to have helper functions for this, similar to what I did for ValueErrors which are empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should I revert back to the previous wording ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe wait a while on @derickr's opinion.
ext/date/tests/gh14709.phpt
Outdated
Bug GH-14709 overflow on reccurences parameter | ||
--SKIPIF-- | ||
<?php | ||
if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is superfluous. Doesn't the test run fine on 32bit platforms, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not recall why, usually I do not disable for 32 bits just like this. I ll give it a go in a bit later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems working indeed, might had been just a case I forgot to remove after code changes.
This should not be applied to PHP-8.2 any longer. |
Ah good point, time flies :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks OK as is, but please squash the commits first, and rebase for PHP 8.3.
ext/date/php_date.c
Outdated
zend_string *func = get_active_function_or_method_name(); | ||
zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): Recurrence count must be greater than 0", ZSTR_VAL(func)); | ||
zend_throw_exception_ex(NULL, 0, "%s(): Recurrence count must be greater or equal to 1 and lower than " ZEND_LONG_FMT, ZSTR_VAL(func), max_recurrences + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why you removed the specific extension here? We had an RFC for this:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/extension/exception ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok I see, going to fix these..
ext/date/php_date.c
Outdated
zend_string_release(func); | ||
return false; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: No need to add empty lines
ext/date/php_date.c
Outdated
|
||
if (UNEXPECTED(recurrences > max_recurrences)) { | ||
zend_string *func = get_active_function_or_method_name(); | ||
zend_throw_exception_ex(NULL, 0, "%s(): Recurrence count must be greater or equal to 1 and lower than " ZEND_LONG_FMT " (including options)", ZSTR_VAL(func), max_recurrences + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also use the specific extension here again.
ext/date/tests/gh14709.phpt
Outdated
try { | ||
new DatePeriod($start, $interval, 2147483640); | ||
} catch (Exception $e) { | ||
echo $e->getMessage() . PHP_EOL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the exception class, like in the other tests, by using:
echo $e::class, ': ', echo $e->getMessage() . PHP_EOL;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but please address my last nit. And then also please squash before merging.
Exception: DatePeriod::createFromISO8601String(): Recurrence count must be greater or equal to 1 and lower than %d | ||
DateMalformedPeriodStringException: DatePeriod::__construct(): Recurrence count must be greater or equal to 1 and lower than %d | ||
DateMalformedPeriodStringException: DatePeriod::createFromISO8601String(): Recurrence count must be greater or equal to 1 and lower than %d | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extraneous line at end of file
No description provided.