php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #17159 touch() is broken
Submitted: 2002-05-11 16:54 UTC Modified: 2002-05-13 14:40 UTC
From: sbriesen at gmx dot de Assigned:
Status: Closed Package: Reproducible crash
PHP Version: 4.2.0 OS: linux, kernel 2.4.18
Private report: No CVE-ID: None
 [2002-05-11 16:54 UTC] sbriesen at gmx dot de
In PHP 4.2.0 the touch() function seems to be broken!
When you use touch($filename) the mtime is a random value... if you use touch($filename,time()), anything works fine.

I checked the source and I think, I found the BUG!

[php-4.2.0/ext/standard/filestat.c # PHP_FUNCTION(touch)]

[..]
        struct utimbuf newtimebuf;
        struct utimbuf *newtime = &newtimebuf;
        int ac = ZEND_NUM_ARGS();

        if (ac == 1 && zend_get_parameters_ex(1, &filename) != FAILURE) {
#ifndef HAVE_UTIME_NULL
                newtime->modtime = newtime->actime = time(NULL);
#endif
        } else if (ac == 2 && zend_get_parameters_ex(2, &filename, &filetime) != FAILURE) {

[..]

have a look at the part with HAVE_UTIME_NULL. if HAVE_UTIME_NULL is *not* defined, it will be initialized with time(NULL). But if it is defined, newtime->modtime and newtime->actime will be *uninitialized*!!! There's no code to initialize both values with something like 0 or NULL. The struct newtime is on the stack and has random content!

HAVE_UTIME_NULL seems to be defined on my system and so touch() sets random values for modtime and actime.

Greetings from Germany,
Stefan Briesenick

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-05-11 16:55 UTC] derick@php.net
This bug has been fixed in CVS. You can grab a snapshot of the
CVS version at http://snaps.php.net/. In case this was a documentation 
problem, the fix will show up soon at http://www.php.net/manual/. 
Thank you for the report, and for helping us make PHP better.
 [2002-05-13 14:03 UTC] sbriesen at gmx dot de
ok, I downloaded the latest snapshot. It is *partly* fixed, but now, there's another BUG!

here the snippet:

PHP_FUNCTION(touch)
{
	pval **filename, **filetime, **fileatime;
	int ret;
	struct stat sb;
	FILE *file;
	struct utimbuf newtimebuf;
	struct utimbuf *newtime = NULL;
	int ac = ZEND_NUM_ARGS();

	if (ac == 1 && zend_get_parameters_ex(1, &filename) != FAILURE) {
#ifndef HAVE_UTIME_NULL
		newtime->modtime = newtime->actime = time(NULL);
#endif
	} else if (ac == 2 && zend_get_parameters_ex(2, &filename, &filetime) != FAILURE) {
		newtime = &newtimebuf;
		convert_to_long_ex(filetime);
		newtime->actime = time(NULL);
		newtime->modtime = newtime->actime = Z_LVAL_PP(filetime);
	} else if (ac == 3 && zend_get_parameters_ex(3, &filename, &filetime, &fileatime) != FAILURE) {
		newtime = &newtimebuf;
		convert_to_long_ex(fileatime);
		convert_to_long_ex(filetime);
		newtime->actime = Z_LVAL_PP(fileatime);
		newtime->modtime = Z_LVAL_PP(filetime);
	} else {
		WRONG_PARAM_COUNT;
	}
[..]

ok, lets see, what it do:

> struct utimbuf *newtime = NULL;

great! ;-)

with 2 or 3 parameters, the code do this:

> newtime = &newtimebuf;

great! ;-)

but with 1 parameter:

> #ifndef HAVE_UTIME_NULL
>   newtime->modtime = newtime->actime = >time(NULL);
> #endif

eh, if HAVE_UTIME_NULL is *not* defined, 'newtime' is stil NULL. hmmm, I think, it should be initialized with 'newtime = &newtimebuf;', shouldn't it? NULL->modtime => SEGV ;-)


Greetings from Germany,
Stefan Briesenick
 [2002-05-13 14:13 UTC] rasmus@php.net
Ok, really fixed in CVS
 [2002-05-13 14:31 UTC] sbriesen at gmx dot de
great! :-)

btw: your response time is really fast!

btw^2: the optional 3rd parameter (int actime) is not mentioned in the documentation. That should also be fixed... 


regards
Stefan Briesenick
 [2002-05-13 14:40 UTC] mfischer@php.net
Thanks for heads up, it's documented now and will show up in a few days.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat May 11 05:01:30 2024 UTC