-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix bug #75851: Year component overflow with date formats c, o, r and y #3028
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
ext/date/php_date.c
Outdated
@@ -1143,7 +1143,7 @@ static zend_string *date_format(char *format, size_t format_len, timelib_time *t | |||
length = slprintf(buffer, 32, "%02d", (int) isoweek); break; /* iso weeknr */ | |||
case 'o': | |||
if(!weekYearSet) { timelib_isoweek_from_date(t->y, t->m, t->d, &isoweek, &isoyear); weekYearSet = 1; } | |||
length = slprintf(buffer, 32, "%d", (int) isoyear); break; /* iso year */ | |||
length = slprintf(buffer, 32, "%lld", (zend_long) isoyear); break; /* iso year */ |
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 think you can just use %lld
as I believe that doesn't work on Windows. PHP defines a few constants for this, such as ZEND_LONG_FMT_SPEC
, used somewhere else in this file: https://github.com/php/php-src/blob/master/ext/date/php_date.c#L4451
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.
@derickr I tested this on Windows - I actually only tested it on W10 x64 as it was the nearest working build env I had - and it works fine there, but it's possible it doesn't work on 32-bit Windows (which is exactly why I opened the PR rather than just merging, I felt this needed review from someone more experienced). I had been hoping that Travis/Appveyor would provide some wider test feedback, but both envs failed for reasons unrelated to the content of the PR :-/
The choice of %lld
was based on https://github.com/DaveRandom/php-src/blob/caed4b0387e95215817e6a5aea558bf6f985580a/ext/date/php_date.c#L1233, does this need migrating as well or is there something I'm missing?
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 is printing a timelib_sll, which uses %lld
. Here you are using a zend_long
, which uses ZEND_LONG_FMT
.
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.
As both are, afaict, essentially aliases of the same type (64-bit signed integer) after a lot of tapdancing, would you mind explaining the functional difference here? I'm sure you're right, I'd just like to understand why
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.
timelib_sll is int64_t, zend_long is int64_t or int32_t, depending on platform.
ext/date/php_date.c
Outdated
@@ -1154,7 +1154,7 @@ static zend_string *date_format(char *format, size_t format_len, timelib_time *t | |||
|
|||
/* year */ | |||
case 'L': length = slprintf(buffer, 32, "%d", timelib_is_leap((int) t->y)); break; | |||
case 'y': length = slprintf(buffer, 32, "%02d", (int) t->y % 100); break; | |||
case 'y': length = slprintf(buffer, 32, "%02lld", (zend_long) t->y % 100); break; |
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.
Printing a 2-digit number as long long doesn't make sense. Maybe you're looking to change the precedence of the cast? (int) (t->y % 100)
.
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.
You're absolutely right, will do that instead
caed4b0
to
8ba07f0
Compare
--TEST-- | ||
Test for bug #75851: Year component overflow with date formats "c", "o", "r" and "y" | ||
--INI-- | ||
date.timezone = UTC |
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 test needs a SKIPIF for 32-bit, like in the other test you modified.
Closed in favour of #3380 |
No description provided.