Skip to content

Fix GH-16228 overflow on easter_days/easter_date year argument. #16241

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

Closed
wants to merge 2 commits into from

Conversation

devnexen
Copy link
Member

@devnexen devnexen commented Oct 5, 2024

No description provided.

@devnexen devnexen linked an issue Oct 5, 2024 that may be closed by this pull request
@@ -48,6 +48,11 @@ static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm)
}
}

if (year < 0 || year > (ZEND_LONG_MAX - 1)) {
Copy link
Member

Choose a reason for hiding this comment

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

The computation dom = (year + (year/4) - (year/100) + (year/400)) % 7 can still overflow.
Also, year 0 does not exist.

@@ -28,6 +28,7 @@ static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm)
struct tm te;
zend_long year, golden, solar, lunar, pfm, dom, tmp, easter, result;
zend_long method = CAL_EASTER_DEFAULT;
const double max_year = (double)(ZEND_LONG_MAX / 1.25);
Copy link
Member

Choose a reason for hiding this comment

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

The double cast is not necessary.

Copy link
Member

Choose a reason for hiding this comment

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

How did you come to the conclusion to divide by 1.25?

Copy link
Member Author

Choose a reason for hiding this comment

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

because year + (year/4) = 1.25*year;

Copy link
Member

Choose a reason for hiding this comment

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

Ah, and because - (year/100) + (year/400) must be less than 0 this is indeed sufficient of course. This is right.

if (year < 0 || year > (ZEND_LONG_MAX - 1)) {
zend_argument_value_error(1, "must be between 0 and " ZEND_LONG_FMT, (ZEND_LONG_MAX - 1));
if (year <= 0 || (double)year > max_year) {
zend_argument_value_error(1, "must be between 1 and " ZEND_LONG_FMT, (zend_long)max_year);
Copy link
Member

Choose a reason for hiding this comment

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

(zend_long)max_year can also be UB because it's not necessarily representable?

Copy link
Member

Choose a reason for hiding this comment

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

Nvm this is not true.

@nielsdos
Copy link
Member

nielsdos commented Oct 5, 2024

@devnexen This patch will work, I just missed some details sorry. I think however it's nicer if we avoid the double and only use zend_long.

@devnexen devnexen closed this in a3ff092 Oct 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Signed integer overflow in ext/calendar/easter.c:94
2 participants