ID:               48746
 Comment by:       dr dot e dot sheppard at web dot de
 Reported By:      ddkees at illinois dot edu
 Status:           Open
 Bug Type:         *Directory/Filesystem functions
 Operating System: Windows Server 2003
 PHP Version:      5.3.0
 Assigned To:      pajoye
 New Comment:

This bug can easily be reproduced with the following scenario:

- change to a directory within your webserver's document root
- create a junction named "apps" pointing to the desired target within
the directory tree
- calling a php file (residing in parallel to the "apps" folder) with
the following code:

if(file_exists('./apps') === true){ 
   echo 'yes!';
} else {
   echo 'no!';
}

The result will be "no!".


Previous Comments:
------------------------------------------------------------------------

[2009-06-30 19:10:21] ddkees at illinois dot edu

The file structure looks like this.  Junction points are followed by an
asterisk; that asterisk is _not_ a part of the folder's name within the
filesystem.

/
/includes
/includes/classes*
/includes/classes/.SwiftMailer
/includes/classes/course_websites
/includes/classes/directory
/includes/classes/faculty_awards*
/includes/classes/FirePHP

There are more folders than what's listed above, but that's enough to
give you the idea, I hope.  If not, let me know.

As you can see from the code example above, we start the process in
/includes/classes and look for folders/files to identify class
definitions to include.  Using this code and 5.3.0 this morning, we
found that, using the above list, only the faculty_awards junction point
would be identified as a directory when using is_dir() and when using
DirectoryIterator::isDir().

Here's a script to show what fails:

function find_directories($directory) {
        $files = new DirectoryIterator($directory);
        foreach($files as $file) {
                if($file->isDot() || $file->getFilename()=="_notes") continue;
                
                echo "Analyzing: $file<br>";
                var_dump($file->isDir());
                echo "Analysis Complete.<br><br>";
        }
}

---

If we execute that function as follows:

   find_directories($_SERVER["DOCUMENT_ROOT"] . "/includes/classes");

We would expect that all of the information listed above would result
in true.  However, the actual results of that test were:

Analyzing: .SwiftMailer
bool(false) Analysis Complete

Analyzing: course_websites
bool(false) Analysis Complete

Analyzing: directories
bool(false) Analysis Complete

Analyzing: faculty_awards
bool(true) Analysis Complete

Analyzing: FirePHP
bool(false) Analysis Complete

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

[2009-06-30 17:58:46] paj...@php.net

Please provide a simple example to show what exactly does not work,
which function or method exactly and using which path:

- describe the directory tree you use and which parts of it are
junction
- provide a simple script to show which function(s) fail(s)



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

[2009-06-30 17:35:59] ddkees at illinois dot edu

It should be noted, that using 5.2.9-1 works exactly as expected.

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

[2009-06-30 17:19:27] ddkees at illinois dot edu

Description:
------------
After updating this morning (June 30) to 5.3.0, our __autoload()
function failed to identify any classes located in subfolders of the
windows Junction Point which contains our class files.  

Our __autoload() function is recursive, descending into the filesystem
looking for class files which match the one that we're trying to load. 
However, since the /includes/classes folder is a Junction Point, only
other Junction Points return true when we use both is_dir() and
DirectoryIterator::isDir() to try and identify folders from files. 
DirectoryIterator::isLink() also returns false.  

However, if we change our __autoloader() to include files from the
source of the Junction Point, it works as expected, but this is only a
solution for a sub-set of the sites that are available on our server.

Reproduce code:
---------------
function __autoload($class) {
        if(!function_exists("find_file")) {
                function find_file($directory, $target) {
                        $dir = opendir($directory);
                        while(($file = readdir($dir))!==false) {
                                if($file == "_notes" || substr($file, 0, 
1)==".") continue;
                                if(is_dir($directory . "/" . $file)) 
find_file($directory . "/" .
$file, $target);
                                elseif(basename($file, ".php") == $target) {
require_once($directory . "/" . $file); return; }
                        }
                }
        }
                
        find_file($_SERVER['DOCUMENT_ROOT'] . "includes/classes",
strtolower($class));
}

Expected result:
----------------
The expected result is that starting from $_SERVER["DOCUMENT_ROOt"] .
"/includes/classes" we identify folders and descend into them to look
for a file named $class.php where $class is the parameter sent to
__autoload().  When that file is found, it's included.

Actual result:
--------------
No folders are actually traversed, either when using the code above or
when altering it to use the DirectoryIteratory SPL object.  All
non-Junction Points return false from is_dir() and, as a result, they
are never traversed and the system will also attempt to include them as
files if the elseif-conditional evaluates to true.


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


-- 
Edit this bug report at http://bugs.php.net/?id=48746&edit=1

Reply via email to