php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #10686 Bug in "mktime()" on values out of bounds
Submitted: 2001-05-05 17:19 UTC Modified: 2002-06-12 11:38 UTC
Votes:10
Avg. Score:4.0 ± 1.4
Reproduced:8 of 8 (100.0%)
Same Version:2 (25.0%)
Same OS:5 (62.5%)
From: dieter at fiebelkorn dot net Assigned: hholzgra (profile)
Status: Closed Package: Date/time related
PHP Version: 4.0.5 - 4.2.0 OS: MacOS X 10.0.2 - 10.1.4 (Darwin)
Private report: No CVE-ID: None
 [2001-05-05 17:19 UTC] dieter at fiebelkorn dot 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; 

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-05-07 12:53 UTC] derick@php.net
Marking as fix before 4.0.6
 [2001-05-14 14:27 UTC] 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-14 14:53 UTC] dieter at fiebelkorn dot net
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

 [2001-05-14 14:59 UTC] jmoore@php.net
Ill look into getting darwin x86 tomorrow.

- James
 [2001-06-09 07:38 UTC] dieter at fiebelkorn dot net
Von: Trevis Tagawa <trtagawa@ksbe.edu>
Datum: Sam, 09. Jun. 2001  01:12:46 Europe/Berlin
An: <dieter@fiebelkorn.net>
Betreff: Thanks!

just wanted to extend a thanks to you for posting the fix.  searched the net
high and low but found your fix on the php site.  aloha!  trevis.

-----------------------------

Trevis Tagawa
Instructional Systems Analyst
Kamehameha Schools
1887 Makuakane Street
Honolulu, HI  96817

 [2001-06-11 14:28 UTC] dieter at fiebelkorn dot net
> you can use Darwin/Intel (see: http://www.darwinfo.de), if  

Sorry. Informations about Darwin you can find on:
- http://www.darwinfo.org/
- http://www.apple.com/darwin/

Dieter

 [2001-08-18 21:30 UTC] kalowsky@php.net
i have a MacOSX box now so I'll test this out and submit it 
if it looks good...
 [2001-10-23 09:03 UTC] dieter at fiebelkorn dot net
Does it looks well? (Same in MacOS X 10.1 and Darwin 1.4.1)
 [2001-11-18 02:37 UTC] dieter at fiebelkorn dot net
From: "Abner Diaz" <abner@criticalnexus.com>

I can verify the behavior of PHP Bug ID 10686 (http://
bugs.php.net/bug.php?id=10686), regarding mktime 
malfunctions in OS X 10.1/Darwin 1.4.?? The fixes to 
datetime.c?posted by dieter@fiebelkorn.net worked well.? 
Thanks!
?
Sincerely,
Abner Diaz

 [2002-01-08 16:06 UTC] derick@php.net
This is reported fixed.
 [2002-03-14 17:01 UTC] dieter at fiebelkorn dot net
I cannot see it fixed in 4.1.2. Try my fix ... that works!

01.02.2000 --> 949402800 --> 01.02.2000 12:00:00
00.02.2000 --> 949316400 --> 31.01.2000 12:00:00
-1.02.2000 --> 949230000 --> 30.01.2000 12:00:00
01.03.2000 --> 951908400 --> 01.03.2000 12:00:00
00.03.2000 --> 951735600 --> 28.02.2000 12:00:00
-1.03.2000 --> 951649200 --> 27.02.2000 12:00:00
01.04.2000 --> 954583200 --> 01.04.2000 12:00:00
00.04.2000 --> 954410400 --> 30.03.2000 12:00:00
-1.04.2000 --> 954324000 --> 29.03.2000 12:00:00
01.05.2000 --> 957175200 --> 01.05.2000 12:00:00
00.05.2000 --> 957002400 --> 29.04.2000 12:00:00
-1.05.2000 --> 956916000 --> 28.04.2000 12:00:00
01.06.2000 --> 959853600 --> 01.06.2000 12:00:00
00.06.2000 --> 959680800 --> 30.05.2000 12:00:00
-1.06.2000 --> 959594400 --> 29.05.2000 12:00:00

<?
$tm_sec=0; $tm_min=0; $tm_hour=0; $tm_year=100;
$tm_wday=0; $tm_yday=0; $tm_isdst=0; $tm_gmtoff=0;
$tm_zone=0;
for ($j=2; $j<=6; $j++) {
        for ($i=1; $i>=-1; $i--) {
                $tm_mday=$i;
                $tm_mon=$j;
                printf ("%02d.%02d.%04d", $tm_mday, 
$tm_mon,1900+$tm_year);
                $tm = mktime(12,0,0,$tm_mon,$tm_mday,1900+
$tm_year);
                echo " --> $tm";
                echo " --> ".date("d.m.Y H:i:s", $tm);
                echo "<br>";
        }
}
?>
 [2002-03-14 17:03 UTC] dieter at fiebelkorn dot net
Happen on MacOS X 10.0.0 up to 10.1.3:

Darwin localhost 5.3 Darwin Kernel Version 5.3: Thu Jan 24 
22:06:02 PST 2002; root:xnu/xnu-201.19.obj~1/RELEASE_PPC  
Power Macintosh powerpc
 [2002-04-02 13:43 UTC] sander@php.net
It was probably fixed in 4.2.0. Can you try 4.2.0RC1 from www.php.net/~derick ?
 [2002-05-03 00:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2002-05-03 02:02 UTC] dieter at fiebelkorn dot net
I'm unable to compile PHP 4.2 on MacOS X 10.1.4 (Darwin 5.4). But i haven't seen a patch, which solved the described problem! mktime() will used with numbers out of range!

Dieter

-----

/Users/dieter/Desktop/php-4.2.0/libtool: parse error: condition expected: xno = [3147]
/usr/bin/libtool: file: stub.lo is not an object file (not allowed in a library)
 [2002-05-03 02:04 UTC] dieter at fiebelkorn dot net
*****************************************************
no FIX was provided for this bug for over a year, so it is
being ignoring automatically.
*****************************************************
 [2002-05-03 02:07 UTC] dieter at fiebelkorn dot net
Cannot change to "OPEN"!
 [2002-05-03 03:38 UTC] sander@php.net
Yes you can, using the 'edit submission' button.
 [2002-06-12 09:05 UTC] hholzgra@php.net
the patch included in this report is almost fine,
but it doesn't take in account that the date passed
to libc mktime() and the final result with offset
applied may be on opposite sides of a DST boundary ...
 [2002-06-12 11:38 UTC] hholzgra@php.net
fixed in latest CVS, should work on all OS/libc versions now
as negative offsets are now taken care of internaly so libc mktime()
won't receive any negative (or 0 for tm_mday) values anymore (see also #8828)


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 17:01:31 2024 UTC