Bug #10686 Updated: Bug in "mktime()" on values out of bounds
| From: | dieter at fiebelkorn dot net | Date: | Mon, 14 May 2001 18:53:55 +0000 |
| Subject: | Bug #10686 Updated: Bug in "mktime()" on values out of bounds | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-55224@lists.php.net to get a copy of this message | ||
ID: 10686
User Update by: dieter@fiebelkorn.net
Status: Open
Bug Type: Date/time related
Operating system: MacOS X 10.0.2 (Darwin)
PHP Version: 4.0.5
Description: Bug in "mktime()" on values out of bounds
Yes, it is "Darwin" specific.
It is enough to use MacOS X 10.0.0 to 10.0.3 (MacOS X
Server is not need!)
OR
you can use Darwin/Intel (see: http://www.darwinfo.de), if
you don't have a Apple Macintosh.
I used this patch for some weeks and an more primitiv patch
some month. It works well and it can test on all other
platforms you have. I will made some more test with some
bigger values for each field...
Whats the problem? You are using an undocumented feature
and all other UNIX work in the same way. But it is not
safe!
Dieter
Previous Comments:
---------------------------------------------------------------------------
[2001-05-14 14:27:59] jmoore@php.net
MacOS specific. Not critical untill we can find some MacOS X servers for developers/QA Team to test
on.
- James
---------------------------------------------------------------------------
[2001-05-07 12:53:07] derick@php.net
Marking as fix before 4.0.6
---------------------------------------------------------------------------
[2001-05-05 17:19:37] dieter@fiebelkorn.net
see Bug id #8828, too!
On PHP documantation:
mktime(hour,min,sec, year,0,mon) refers the last day of month 'mon-1'. On MacOS X this
failed, there it refers the first day of month 'mon' and mktime(hour,min,sec,
year,-1,mon) refers the last day of month 'mon-1'.
On MacOS X 10.0.2 (Darwin 1.3):
02.03 --> 983487600 --> 02.03
01.03 --> 983401200 --> 01.03
00.03 --> 983401200 --> 01.03
-1.03 --> 983314800 --> 28.02
-2.03 --> 983228400 --> 27.02
i have check some UNIX-systems and i haven't found any man-page, where is describe what should
be happend on "tm_mday" <= 0. The problem is happend on all values out of bounds, when
using mktime()!
IMHO this is a undocumented feature, which is used by PHP.
man mktime (Linux 2.2.13)
tm_mday The day of the month, in the range 1 to 31.
Sun Release 4.1
int tm_mday; /* day of month (1 - 31) */
SunOS 5.5
int tm_mday; /* day of the month - [1, 31] */
HP-UX Release 10.20
int tm_mday; /* day of month - [1,31] */
HP-UX Release 11.00
int tm_mday; /* day of month - [1,31] */
AIX 4.3.2
int tm_mday; /* Day of month (1 - 31) */
Darwin 1.0.2
int tm_mday; /* day of month (1 - 31) */
I think i should by much better to check mktime() on configure and set a #define for compilation.
Only on "datetime.c" must be made a patch to support MacOS X's / Darwin's
mktime()-systemcall, i think!
Patch to make php_mktime() more compatible [i think it is not complete for the whole PHP4-project].
It includes a time correction for values less then 1 on "mday",
"hour", "min", "sec", "mon"!!
*** ext/standard/datetime.c.orig Fri Dec 8 12:38:02 2000
--- ext/standard/datetime.c Sun Apr 15 17:28:46 2001
***************
*** 81,87 ****
struct tm *ta, tmbuf;
time_t t;
int i, gmadjust, seconds, arg_count = ZEND_NUM_ARGS();
! int is_dst = -1;
if (arg_count > 7 ||
zend_get_parameters_array_ex(arg_count,arguments) ==
FAILURE) {
WRONG_PARAM_COUNT;
--- 81,87 ----
struct tm *ta, tmbuf;
time_t t;
int i, gmadjust, seconds, arg_count = ZEND_NUM_ARGS();
! int is_dst = -1, val, chgsecs = 0;
if (arg_count > 7 ||
zend_get_parameters_array_ex(arg_count,arguments) ==
FAILURE) {
WRONG_PARAM_COUNT;
***************
*** 148,172 ****
- (((*arguments[5])->value.lval > 1000) ? 1900 : 0);
/* fall-through */
case 5:
! ta->tm_mday = (*arguments[4])->value.lval;
/* fall-through */
case 4:
! ta->tm_mon = (*arguments[3])->value.lval - 1;
/* fall-through */
case 3:
! ta->tm_sec = (*arguments[2])->value.lval;
/* fall-through */
case 2:
! ta->tm_min = (*arguments[1])->value.lval;
/* fall-through */
case 1:
! ta->tm_hour = (*arguments[0])->value.lval;
/* fall-through */
case 0:
break;
}
! seconds = mktime(ta);
if (is_dst == -1)
is_dst = ta->tm_isdst;
--- 148,182 ----
- (((*arguments[5])->value.lval > 1000) ? 1900 : 0);
/* fall-through */
case 5:
! val = (*arguments[4])->value.lval;
! if (val < 1) { chgsecs += (1-val) * 60*60*24; val = 1;
}
! ta->tm_mday = val;
/* fall-through */
case 4:
! val = (*arguments[3])->value.lval - 1;
! while (val < 0) { val += 12; ta->tm_year--; }
! ta->tm_mon = val;
/* fall-through */
case 3:
! val = (*arguments[2])->value.lval;
! if (val < 1) { chgsecs += (1-val); val = 1; }
! ta->tm_sec = val;
/* fall-through */
case 2:
! val = (*arguments[1])->value.lval;
! if (val < 1) { chgsecs += (1-val) * 60; val = 1; }
! ta->tm_min = val;
/* fall-through */
case 1:
! val = (*arguments[0])->value.lval;
! if (val < 1) { chgsecs += (1-val) * 60*60; val = 1; }
! ta->tm_hour = val;
/* fall-through */
case 0:
break;
}
! seconds = mktime(ta) - chgsecs;
if (is_dst == -1)
is_dst = ta->tm_isdst;
---------------------------------------------------------------------------
Full Bug description available at: http://bugs.php.net/?id=10686