Bug #652: Wrong results and sideeffects of filetype()
| From: | fritz at wuemaus dot franken dot de | Date: | Thu, 13 Aug 1998 16:52:48 +0000 |
| Subject: | Bug #652: Wrong results and sideeffects of filetype() | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-136@lists.php.net to get a copy of this message | ||
From: fritz@wuemaus.franken.de
Operating system: Any (tested only on Linux)
PHP version: 3.0.2a
PHP Bug Type: Misbehaving function
Bug description:
I just found a bug in functions/filestat.c which causes
two types of wrong behavior when using the filetype() function:
a) The type of a symlink is only returned correctly, if the link
points to a regular file. In real life, symlinks can point
to anything.
b) (even worse). Calling filetype() overwrites the permisssions
in the global stat cache (IMHO _unwanted_ side-effect).
EXAMPLE:
Situation in real life:
ls -l /tmp
lrwxrwxrwx 1 root root 4 Aug 13 16:58 dusel -> /usr
-rw-r--r-- 1 root root 0 May 4 00:53 mysqlaccess.log
lrwxrwxrwx 1 root root 15 Aug 13 16:57 wusel -> mysqlaccess.log
Script:
clearstatcache();
echo filetype("/tmp/dusel") . "<BR>\n";
echo sprintf("%08o", fileperms("/tmp/wusel")) . "<BR>\n";
echo filetype("/tmp/wusel") . "<BR>\n";
echo sprintf("%08o", fileperms("/tmp/wusel")) . "<BR>\n";
Result:
dir
00100644
link
00120777
FIX:
The reason for the above behaviour is in functions/filestat.c, where
a) lstat() is called only for regular files.
b) when calling lstat(), a GLOBAL stbuf is used.
The following patch solves both problems by
a) calling lstat() unconditionally.
b) using a local struct stbuf.
--- functions/filestat.c.orig Thu Aug 13 17:22:17 1998
+++ functions/filestat.c Thu Aug 13 17:29:10 1998
@@ -429,6 +429,12 @@
RETURN_LONG((long)GLOBAL(sb).st_ctime);
break;
case 8: /* filetype */
+ {
+ struct stat lsb;
+ lstat(GLOBAL(CurrentStatFile),&lsb);
+ if ((lsb.st_mode&S_IFMT) == S_IFLNK) {
+ RETURN_STRING("link",1);
+ }
switch(GLOBAL(sb).st_mode&S_IFMT) {
case S_IFIFO:
RETURN_STRING("fifo",1);
@@ -443,17 +449,13 @@
RETURN_STRING("block",1);
break;
case S_IFREG:
- lstat(GLOBAL(CurrentStatFile),&GLOBAL(sb));
- if ((GLOBAL(sb).st_mode&S_IFMT) == S_IFLNK) {
- RETURN_STRING("link",1);
- } else {
RETURN_STRING("file",1);
- }
break;
default:
php3_error(E_WARNING,"Unknown file type
(%d)",GLOBAL(sb).st_mode&S_IF
MT);
RETURN_STRING("unknown",1);
break;
+ }
}
break;
case 9: /*is writable*/
--
PHP Development Mailing List http://www.php.net/
To unsubscribe send an empty message to php-dev-unsubscribe@lists.php.net
For help: php-dev-help@lists.php.net