Issues

ZF-9263: Auto-loading stopped working as before in 1.10.1

Issue Type: Bug Created: 2010-02-25T06:58:27.000+0000 Last Updated: 2010-11-25T12:16:22.000+0000 Status: Resolved Fix version(s): - 1.10.4 (28/Apr/10)

Reporter: Cristian Bichis (avantis) Assignee: Matthew Weier O'Phinney (matthew) Tags: - Zend_Loader

Related issues: - ZF-9166

Attachments:

Description

I was working on a ZF application based on ZF 1.10.0. Then env is: WinXP, Apache 2.2.11, PHP 5.3.1, MySQL.

I made one very small change: replaced the 1.10.0 with 1.10.1 (or 1.10.2 the same effect) and no any other change and all over the application are errors because some resources doesn't seems to be auto-loaded properly.

Here is my include_path:

set_include_path(implode(PATH_SEPARATOR, array(
    ZF_LIBRARY_PATH,
    BASE_PATH . '/library',
    get_include_path()
)));

I tried to switch all the application resources to use absolute path but errors again....

Sample for Application Resources...

Warning: is_readable() [<function.is-readable>]: open_basedir restriction in effect. File(C:\php5\pear/ZendX/Application/Resource/Log.php) is not within the allowed path(s): (D:_Work\;D:\wamp\;C:\Windows\Temp\;c:\php\pear) in D:\wamp\frameworks\ZendFramework-1.10.1\Zend\Loader.php on line 190

Warning: is_readable() [<function.is-readable>]: open_basedir restriction in effect. File(C:\php5\pear/Application/Application/Resource/Log.php) is not within the allowed path(s): (D:_Work\;D:\wamp\;C:\Windows\Temp\;c:\php\pear) in D:\wamp\frameworks\ZendFramework-1.10.1\Zend\Loader.php on line 190

Warning: is_readable() [<function.is-readable>]: open_basedir restriction in effect. File(C:\php5\pear/Imagis/Application/Resource/Log.php) is not within the allowed path(s): (D:_Work\;D:\wamp\;C:\Windows\Temp\;c:\php\pear) in D:\wamp\frameworks\ZendFramework-1.10.1\Zend\Loader.php on line 190

Sample for view helpers:

Warning: is_readable() [<function.is-readable>]: open_basedir restriction in effect. File(C:\php5\pear/D:/_Work/vxwiki2/application/modules/default/views\helpers/Partial.php) is not within the allowed path(s): (D:_Work\;D:\wamp\;C:\Windows\Temp\;c:\php\pear) in D:\wamp\frameworks\ZendFramework-1.10.1\Zend\Loader.php on line 190

As i repeat: there is no other application or WAMP environment change than changing the ZF version from 1.10.0 to .1/.2

Comments

Posted by Matthew Weier O'Phinney (matthew) on 2010-02-25T07:35:08.000+0000

It's clear you're using open_basedir, which places filesystem access restrictions. Prior to 1.10.1, we were using a hack that utilized some functionality in fopen() -- basically, fopen() allows a flag that will allow it to search for the file specified on the include_path. Unfortunately, due to the way it worked, we had to use the error suppression operator to eliminate notices, it would not work with stream wrappers, and it circumvented the open_basedir settings. We've moved to a solution that iterates over the include_path and calls is_readable() instead, which solves all three issues.

The obvious downside, of course, is if you had an open_basedir setting, and had files that lived outside that path. This was something we had not anticipated with the change, and which we didn't discover until after the release.

The solution is to ensure that all files used by your application live within the tree specified by open_basedir. This may require copying trees (versus symlinking them) into your project directory. Better yet, don't use open_basedir, as it's a setting that's easily circumvented (as our fopen() hack proved) and which provides very limited security benefits.

Posted by Cristian Bichis (avantis) on 2010-02-25T08:17:34.000+0000

Thanks Matthew!

I partially fixed the problems, still fixed the rest.

I am not sure if on documentation is mentioned this change as might be important for many...

Posted by Cristian Bichis (avantis) on 2010-02-25T08:44:23.000+0000

I also noticed some related weird behavior as:

Warning: is_readable(): open_basedir restriction in effect. File(D:\wamp\frameworks\ZendFramework-1.10.2/D:_Work\myapp/application/modules\articles/views\helpers/HeadLink.php) is not within the allowed path(s): (D:_Work\;D:\wamp\;C:\Windows\Temp\;c:\php5\pear) in D:\wamp\frameworks\ZendFramework-1.10.2\Zend\Loader.php on line 190

So basically looking for the helpers is failing, as are checked the Zend_View_Helper into modules helpers paths, not into Zend/View/Helper.

This is NOT a open_basedir problem actually...

Posted by Cristian Bichis (avantis) on 2010-02-25T11:09:39.000+0000

So there is problem: all files reside under open_basedir paths but won't load. So that upgrade made on 1.10.1 is fine as long has a patch to solve the below problems (which probably is not impossible)...

Warning: is_readable(): open_basedir restriction in effect. File(D:\wamp\frameworks\ZendFramework-1.10.2/D:_Work\myapp/application/modules\articles/views\helpers/HeadLink.php) is not within the allowed path(s): (D:_Work\;D:\wamp\;C:\Windows\Temp\;c:\php5\pear) in D:\wamp\frameworks\ZendFramework-1.10.2\Zend\Loader.php on line 190

Posted by Cristian Bichis (avantis) on 2010-02-25T11:30:25.000+0000

I found a way to solve the problem. May not be the optimal way, but:

public static function isReadable($filename)
{
    if (is_readable($filename)) {
        // Return early if the filename is readable without needing the 
        // include_path
        return true;
    }

            //added the if, basically to skip any absolute filename path
    if(!is_readable(dirname($filename)))
        foreach (self::explodeIncludePath() as $path) {
            if ($path == '.') {
                if (is_readable($filename)) {
                    return true;
                }
                continue;
            }
            $file = $path . '/' . $filename;
            if (is_readable($file)) {
                return true;
            }
        }

    return false;
}

This would solve the problem of this raising a Warning.

Warning: is_readable(): open_basedir restriction in effect. File(D:\wamp\frameworks\ZendFramework-1.10.2/D:_Work\myapp/application/modules\articles/views\helpers/HeadLink.php) is not within the allowed path(s): (D:_Work\;D:\wamp\;C:\Windows\Temp\;c:\php5\pear) in D:\wamp\frameworks\ZendFramework-1.10.2\Zend\Loader.php on line 190

Posted by Christiaan Kras (htbaa) on 2010-03-26T04:12:31.000+0000

It would be nice if this issue could be fixed for those where open_basedir is force upon. It's a rather dirty solution to distribute the full ZF library with every app, so a shared directory would be preferred.

Posted by Cristian Bichis (avantis) on 2010-03-26T04:26:26.000+0000

As stated into last comment the problem itself has nothing to do directly with shared directory. The open_basedir warning is raised due to wrong isReadable implementation (and not due to using shared directory).

Anyway, using a shared directory with ZF would be possible again once this bug is fixed.

For now we are stuck at 1.10.0...

Posted by Christiaan Kras (htbaa) on 2010-03-26T11:21:38.000+0000

Unfortunately I can't use 1.10.0 either because of a bug in XCache. Which is resolved I believe in a recent update of XCache but Ubuntu 8.04 doesn't include that version.

Any chance the proposed code will get used in a next version?

Posted by Matthew Weier O'Phinney (matthew) on 2010-04-02T04:55:03.000+0000

@Christiaan Kras: The bug you're alluding to is fixed in 1.10.1 and up -- it had to do with Zend_Exception's definition, and we were able to find a solution that would work both with older versions of XCache as well as more recent versions.

Posted by Christiaan Kras (htbaa) on 2010-04-02T05:05:27.000+0000

@Matthew Weier O'Phinney: Yes I'm aware of that. The fact is that in 1.10.1 and up the way files are being checked for readability no longer works with open_basedir.

Posted by Cristian Bichis (avantis) on 2010-04-02T05:24:24.000+0000

Matthew, the problems started on 1.10.1 (so not fixed on 1.10.1) and is not fixed even on 1.10.3

Posted by Matthew Weier O'Phinney (matthew) on 2010-04-02T05:54:34.000+0000

@Christiaan: I was simply responding to your previous comment, which noted issues with XCache; the way the comment was worded, it was not clear if you were also experiencing the issue reported here.

@Christian: I'm quite aware it's not fixed in 1.10.3. As noted on the mailing list, I need a reproduce case. Current versions work fine in Windows, Linux, and Mac using a stock PHP; I need to know if the only variable here is open_basedir, or if there are additional factors.

Posted by Cristian Bichis (avantis) on 2010-04-02T05:58:34.000+0000

Ok, i will check and post back. Thanks.

Posted by Cristian Bichis (avantis) on 2010-04-02T06:04:33.000+0000

I tested on Windows.

If open_basedir is On then warnings are triggered.

If open_basedir is Off then no warnings are triggered.

I had to say again, all the open_basedir are properly set and also include_paths...

Posted by Cristian Bichis (avantis) on 2010-04-02T06:06:42.000+0000

I can test on a BSD environment if needed. Will post back this results also.

Posted by Cristian Bichis (avantis) on 2010-04-02T06:33:00.000+0000

OK, i tested on a production server, on BSD and WITH open_basedir in effect all works properly on 1.10.2 (i guess same on .1 and .3).

So for now i am experiencing the problem only on: - Windows - open_basedir been enabled

Posted by Matthew Weier O'Phinney (matthew) on 2010-04-02T06:47:57.000+0000

@Christian Thanks -- that will help us isolate the issue.

Posted by Cristian Bichis (avantis) on 2010-04-02T07:01:10.000+0000

I tested on Windows again, now with xDebug disabled (i have xDebug also), and same results. So is not an xDebug issue.

So same conclusion: on Windows with open_basedir enabled -> warning. Any other config ->ok.

Posted by Christiaan Kras (htbaa) on 2010-04-02T07:32:05.000+0000

@Matthew Weier O'Phinney: Sorry for not being clear. I'm not a native English speaker. I was just referring to the fact that I can't use 1.10.0 because of the XDebug bug, and can't use anything newer than that because of this auto-loading bug.

For me the open_basedir problem happens on Ubuntu 8.04.

Posted by Matthew Weier O'Phinney (matthew) on 2010-04-02T07:51:34.000+0000

@Chrstiaan: what version of PHP?

Posted by Christiaan Kras (htbaa) on 2010-04-02T07:55:39.000+0000

5.2.4, just the standard one that comes with Ubuntu 8.04. They do have it patched with the Suhosin patch. Further more safe-mode is on as well.

Posted by Cristian Bichis (avantis) on 2010-04-02T08:06:57.000+0000

Matthew, i have PHP 5.3.1 on WinXP for dev environment which got me the warning...

Posted by Cristian Bichis (avantis) on 2010-04-02T08:46:53.000+0000

So, for me works even with open_basedir enabled on a FreeBSD system having PHP 5.2.13

Posted by Andrew Ballard (aballard) on 2010-04-08T06:02:47.000+0000

I think it is exclusively a Windows issue due to the fact that Windows uses drive letters and *nix does not. If you concatenate two Linux absolute paths, the result is still a valid path even if it does not point to an actual file. If you concatenate a Windows absolute path to the end of any other path (relative OR absolute), the result IS NOT a valid path.

For example:

<pre class="literal">
include_path = /home/www/site/zendframework/library

openbase_dir = /home/www/site

$loader->isReadable('/home/www/site/application/controllers/helpers/Redirector.php');

Inside the isReadable method, it would eventually test this path:

<pre class="literal">

Even though the path does not point to a valid file, the path itself is still valid and it meets the condition specified in openbase_dir.

On Windows, however it looks like this:

include_path = C:\www\site\zendframework\library

openbase_dir = C:\www\site

$loader->isReadable('C:\www\site\application\controllers\helpers\Redirector.php');

<pre class="literal">

Inside the isReadable method, it would eventually test this path:

The drive letter specification inside the path is not valid, and PHP issues the warning.

I think the solution to this problem would be check for a drive letter at the beginning of the path to be tested if the OS is Windows, and if a drive letter is found it is clearly an absolute path that cannot be appended to any of the paths found in include_path. I'm not sure if the PHP_OS test below is totally correct, but I think the solution is to change Zend_Loader::isReadable() to look like this:

<pre class="highlight">
    public static function isReadable($filename)
    {
        if (is_readable($filename)) {
            // Return early if the filename is readable without needing the 
            // include_path
            return true;
        }

        if (PHP_OS == 'WINNT' && preg_match('/^[A-Z]:/i', $file)) {
            // This is an absolute path for a Windows system. We already tried
            // is_readable on the path and it failed, so return false
            return false;
        }
        
        foreach (self::explodeIncludePath() as $path) {
            if ($path == '.') {
                if (is_readable($filename)) {
                    return true;
                }
                continue;
            }
            $file = $path . '/' . $filename;
            if (is_readable($file)) {
                return true;
            }
        }
        return false;
    }

Posted by Christiaan Kras (htbaa) on 2010-04-09T11:18:02.000+0000

@Andrew Ballard: Like I said, it also happens for me on Linux (Ubuntu 8.04, PHP 5.2.4 with suhosin patch, open_basedir and safe_mode in effect).

Posted by Cristian Bichis (avantis) on 2010-04-18T00:20:42.000+0000

Started to happen for me on another FreeBSD server, so somehow is happening also on *Nix.

Posted by Matthew Weier O'Phinney (matthew) on 2010-04-27T09:38:28.000+0000

Andrew -- thanks for the analysis! I noticed the same issue about the full path being added in, and that clearly represents an issue. I was initially worried about the usage of PCRE, but realized that it would only kick in on Windows, and only if the initial test failed. The performance hit should hopefully be fairly minimal, and restricted to Windows environments.

I've added a test and patched the code in trunk and the 1.10 release branch; the fix should be released in 1.10.4.

Posted by Christiaan Kras (htbaa) on 2010-04-29T00:22:05.000+0000

I'm sorry but this bug still isn't resolved on Linux (Ubuntu 8.04, suhosin patch, safe_mode on and open_basedir in effect).

I followed your suggestion in ZF-9166 made sure all paths were absolute. Which then led to an issue of not being able to include a file that was symlinked. So instead of symlinking I copied it to the same directory, made sure permissions were correct and included the file. Right after that all the include errors popped up again.

Below is on of the messages I'm getting, amongst many other failed attempts to load other plugins.

<pre class="highlight">
Warning: is_readable() [function.is-readable]: open_basedir restriction in effect. File(/lib/include/KD/View/Helper/HeadTitle.php) is not within the allowed path(s): (/var/www/www_domain_com/www:/tmp:/usr/local/share/ZendFramework:/usr/share/php) in /usr/local/share/ZendFramework/1.10.4/library/Zend/Loader.php on line 198

Warning: is_readable() [function.is-readable]: open_basedir restriction in effect. File(/usr/share/pear/lib/include/KD/View/Helper/HeadTitle.php) is not within the allowed path(s): (/var/www/www_domain_com/www:/tmp:/usr/local/share/ZendFramework:/usr/share/php) in /usr/local/share/ZendFramework/1.10.4/library/Zend/Loader.php on line 198

Warning: is_readable() [function.is-readable]: open_basedir restriction in effect. File(/lib/modules/default/views/helpers/Helper/HeadTitle.php) is not within the allowed path(s): (/var/www/www_domain_com/www:/tmp:/usr/local/share/ZendFramework:/usr/share/php) in /usr/local/share/ZendFramework/1.10.4/library/Zend/Loader.php on line 198

Warning: is_readable() [function.is-readable]: open_basedir restriction in effect. File(/usr/share/pear/lib/modules/default/views/helpers/Helper/HeadTitle.php) is not within the allowed path(s): (/var/www/www_domain_com/www:/tmp:/usr/local/share/ZendFramework:/usr/share/php) in /usr/local/share/ZendFramework/1.10.4/library/Zend/Loader.php on line 198

Warning: is_readable() [function.is-readable]: open_basedir restriction in effect. File(/lib/include/DP/View/Helper/HeadTitle.php) is not within the allowed path(s): (/var/www/www_domain_com/www:/tmp:/usr/local/share/ZendFramework:/usr/share/php) in /usr/local/share/ZendFramework/1.10.4/library/Zend/Loader.php on line 198

Warning: is_readable() [function.is-readable]: open_basedir restriction in effect. File(/usr/share/pear/lib/include/DP/View/Helper/HeadTitle.php) is not within the allowed path(s): (/var/www/www_domain_com/www:/tmp:/usr/local/share/ZendFramework:/usr/share/php) in /usr/local/share/ZendFramework/1.10.4/library/Zend/Loader.php on line 198

Warning: is_readable() [function.is-readable]: open_basedir restriction in effect. File(/Zend/View/Helper/HeadTitle.php) is not within the allowed path(s): (/var/www/www_domain_com/www:/tmp:/usr/local/share/ZendFramework:/usr/share/php) in /usr/local/share/ZendFramework/1.10.4/library/Zend/Loader.php on line 198

Here's how I've set my include path:

<pre class="highlight">
set_include_path(
    PATH_SEPARATOR . '/usr/local/share/ZendFramework/1.10.4/library/' . 
    PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] . '/lib/modules/default/models/' .
    PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] . '/lib/modules/software/models/' .
    PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] . '/lib/modules/bijlage/models/' .
    PATH_SEPARATOR . $_SERVER['DOCUMENT_ROOT'] . '/lib/include/' .
    PATH_SEPARATOR . get_include_path()
);

By default my include_path contains :/usr/share/php:/usr/share/pear. After modifieng it it contains :/usr/local/share/ZendFramework/1.10.4/library/:/var/www/www_domain_com/app/current/www/lib/modules/default/models/:/var/www/www_domain_com/app/current/www/lib/modules/software/models/:/var/www/www_domain_com/app/current/www/lib/modules/bijlage/models/:/var/www/www_domain_com/app/current/www/lib/include/:.:/usr/share/php:/usr/share/pear.

My $_SERVER['DOCUMENT_ROOT'] points to /var/www/www_domain_com/app/current/www. All paths are correct, as well as any file permissions.

My Apache configuration:

<pre class="highlight">

    DocumentRoot /var/www/www_domain_com/app/current/www
    ServerName <a href="www.domain.com">www.domain.com</a>
    CustomLog /var/log/apache2/<a href="www.domain.com-access_log">www.domain.com-access_log</a> combined
    ErrorLog /var/log/apache2/<a href="www.domain.com-error_log">www.domain.com-error_log</a>
    php_admin_value open_basedir "/var/www/www_domain_com/www:/tmp:/usr/local/share/ZendFramework:/usr/share/php"

Output of php -v in case it's required:

<pre class="highlight">
PHP 5.2.4-2ubuntu5.10 with Suhosin-Patch 0.9.6.2 (cli) (built: Jan  6 2010 22:01:14)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
    with XCache v1.2.1, Copyright (c) 2005-2007, by mOo

Posted by Cristian Bichis (avantis) on 2010-04-29T00:45:37.000+0000

As i mentioned myself, i encountered the same problem on a BSD system. I had to disable open_basedir as a quick solution. Sorry, i can't provide now a sample myself.

Posted by Andrew Ballard (aballard) on 2010-04-29T07:50:45.000+0000

@Christiaan

I think your issue is slightly different. None of the paths in any of the warning messages you posted above are within your open_basedir restriction. The open_basedir restriction is doing what it was designed to do. If the warning were happening on line 176 (version 1.10.4) I could see an issue, but since it is happening on line 198 it means that your include paths are referring to paths that are not valid based on the open_basedir configured for your site.

One of your default include paths is /usr/share/pear, but that is not in your open_basedir restriction. Adding /usr/share/pear to your open_basedir should eliminate three (nearly half) of the warnings you listed.

Also, your include_path begins with a path separator, which means that when ZF tries resolving relative paths using your include_path setup, it will turn them into absolute paths.

For example, when attempting to locate Zend_View_Helper_HeadTitle, the Zend_Loader instance will call $this->isReadable('Zend/View/Helper/HeadTitle.php'). When it does, the first iteration of the loop inside the method will look like this:

<pre class="highlight">
190:        foreach (self::explodeIncludePath() as $path) { // $path = '', $filename = 'Zend/View/Helper/HeadTitle.php'
191:            if ($path == '.') {                         // false; skip this block; go to line 197
192:                if (is_readable($filename)) {
193:                    return true;
194:                }
195:                continue;
196:            }
197:            $file = $path . '/' . $filename;            // $file = '' . '/' . 'Zend/View/Helper/HeadTitle.php';
198:            if (is_readable($file)) {                   // is_readable('/Zend/View/Helper/HeadTitle.php') ---> WARNING!!!!
199:                return true;
200:            }
201:        }

{panel:title=Warning|borderStyle=solid|borderColor=#ccc|titleBGColor=#F7D6C1|bgColor=#FFFFCE}Warning: is_readable() [function.is-readable]: open_basedir restriction in effect. File(/Zend/View/Helper/HeadTitle.php) is not within the allowed path(s): (/var/www/www_domain_com/www:/tmp:/usr/local/share/ZendFramework:/usr/share/php) in /usr/local/share/ZendFramework/1.10.4/library/Zend/Loader.php on line 198{panel}

I'm not sure about the three remaining paths it is testing:

<pre class="literal">
/lib/include/KD/View/Helper/HeadTitle.php
/lib/modules/default/views/helpers/Helper/HeadTitle.php
/lib/include/DP/View/Helper/HeadTitle.php

However, I suspect these are also warnings that result from trying to locate relative paths ( KD/View/Helper/HeadTitle.php, default/views/helpers/Helper/HeadTitle.php, and DP/View/Helper/HeadTitle.php ) that get converted to absolute paths as demonstrated above.

I think if you do three things:

  1. Set your default include path to /usr/share/php:/usr/share/pear instead of :/usr/share/php:/usr/share/pear 2) Set php_admin_value open_basedir "/var/www/www_domain_com/www:/tmp:/usr/local/share/ZendFramework:/usr/share/php:/usr/share/pear" in your VirtualHost config 3) Change this block so that your include_path does not begin with an empty path:
<pre class="highlight">
set_include_path(
    '/usr/local/share/ZendFramework/1.10.4/library/' . PATH_SEPARATOR . 
    $_SERVER['DOCUMENT_ROOT'] . '/lib/modules/default/models/' . PATH_SEPARATOR . 
    $_SERVER['DOCUMENT_ROOT'] . '/lib/modules/software/models/' . PATH_SEPARATOR . 
    $_SERVER['DOCUMENT_ROOT'] . '/lib/modules/bijlage/models/' . PATH_SEPARATOR . 
    $_SERVER['DOCUMENT_ROOT'] . '/lib/include/' . PATH_SEPARATOR . 
    get_include_path()  // this works as long as your default include_path is not empty
);

most (if not all?) of these warnings will go away.

Or you could (as Matthew originally suggested, and Christian most recently mentioned) simply remove the open_basedir requirement.

Posted by Christiaan Kras (htbaa) on 2010-05-02T23:40:30.000+0000

Thanks a bunch! After changing all paths to their absolute value all problems were solved.

Posted by dvdgssm (d10a) on 2010-11-25T12:02:01.000+0000

I have found another issue to this problem (it seems to be the same but shorter).

Just replace ZF default paths configuration in your index.php file by :

set_include_path( APPLICATION_PATH.'/../library'.PATH_SEPARATOR. APPLICATION_PATH.'/../library/Zend' );

Now the path to application/Zend/Views/Helpers... is readable!

Posted by Marc Hodgins (mjh_ca) on 2010-11-25T12:16:22.000+0000

@dvdgssm The default include path generated by Zend_Tool (zf) should be sufficient. Adding library/Zend to the include path doesn't make sense. Anyway, please open a new ticket instead of commenting in a resolved ticket if you think this is a bug that needs to be fixed. Thanks

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts