Custom file:// scheme stream wrapper and chdir() behavior

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Hi everyone,

I've written a file:// scheme stream wrapper that acts like chroot()
(but is more flexible, does not require root privileges and works on any
platform). Everything works just fine except that chdir() still stat()s
through the native PHP filesystem handler. This means that it is not
possible to chdir() to a "jailed" directory, except if by chance its
path also exists in the real local filesystem.

Imagine my file:// wrapper is set up to jail the script to

Works because '/etc' is present in the real local filesystem.

Is OK and actually opens up
'/srv/www/localhost/my-app/root/etc/file.dat' seamlessly.


Throws a warning and is ignored because '/test' does not exist in the
local filesystem even if '/srv/www/localhost/my-app/root/test' directory

Using chdir('/srv/www/localhost/my-app/root') does not help because even
if my custom wrapper is aware of that fixed prefix on all paths, getwd()
returns the jailed path and other stuffs like DOMDocument::load() get
broken when using relative paths.

The trick for now is to chdir('/'); as it is always valid in the jailed
AND local filesystems (on Unix systems at least).

Don't you think that chdir() should use the url_stat() function provided
by the registered file:// scheme stream wrapper class when possible (it
may be omitted on wrappers; in those cases PHP should continue using its
native stat() system). As far as I looked into this I think there is
something not consistent there. fopen() and many many other functions DO
use our custom wrappers but not something as basic as chdir() and getcwd().

Thank you!


Site Timeline