php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #42198 SCRIPT_NAME and PHP_SELF truncated when inside a userdir and using PATH_INFO
Submitted: 2007-08-03 10:24 UTC Modified: 2007-08-08 13:03 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: hans at parse dot nl Assigned: dmitry
Status: Closed Package: CGI/CLI related
PHP Version: 5.2.4RC1 OS: Linux
Private report: No CVE-ID:
 [2007-08-03 10:24 UTC] hans at parse dot nl
Description:
------------
Problem is as described in Lighttpd ticket #405 at http://trac.lighttpd.net/trac/ticket/405

Using Lighttpd with PHP-5.2.4RC1 as FastCGI. cgi.fix_pathinfo = 1 in php.ini

Accessing a script in a userdir without path info works fine:

http://servername/~hans/info.php

SCRIPT_FILENAME = '/home/hans/public_html/info.php'
SCRIPT_NAME = '/~hans/info.php'
PHP_SELF = '/~hans/info.php'

Accessing the same script with some added path info:

http://servername/~hans/info.php/foo/bar

PATH_INFO = '/foo/bar'
SCRIPT_FILENAME = '/home/hans/public_html/info.php'
SCRIPT_NAME = 'ic_html/info.php'
PHP_SELF = 'ic_html/info.php'

I have posted a working patch which adds a userdir check in cgi_main.c in the Lighttpd ticket mentioned.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-08-04 14:13 UTC] jani@php.net
And you are really using 5.2.4RC1? 
 [2007-08-04 14:14 UTC] jani@php.net
Also, what is the result if cgi.fix_pathinfo = 0 ?
 [2007-08-06 08:30 UTC] hans at parse dot nl
Yes, problem found initially in 5.2.3 but i tested and confirmed with 5.2.4RC1 before submitting this bug report.

Turning off cgi.fix_pathinfo results in a "No input file specified." message (url being http://servername/~hans/info.php/foo/bar).
 [2007-08-06 15:45 UTC] jani@php.net
What was the configure line used to configure PHP?
 [2007-08-06 16:11 UTC] hans at parse dot nl
./configure --enable-cgi --enable-fastcgi --enable-force-cgi-redirect --prefix=/usr --sysconfdir=/etc --with-config-file-path=/etc/php --with-openssl --with-bz2 --with-gd --with-mysql --with-mysqli --with-gettext --with-zlib --enable-mbstring --enable-sockets --enable-sysvsem --enable-sysvshm --enable-debug=no

Direct link to my patch against php-5.2.3 on lighttpd Trac: http://trac.lighttpd.net/trac/attachment/ticket/405/cgi_main.diff
 [2007-08-07 09:23 UTC] hans at parse dot nl
A little more explanation fyi: The problem is that DOCUMENT_ROOT is always set to the configured document root of the default host or the vhost, even when calling scripts from a userdir. This is not just in Lighttpd/FastCGI, also f.e. in Apache setups. In my testcase DOCUMENT_ROOT is '/var/www/htdocs'.

So if i call http://servername/~hans/info.php/foo/bar , We enter this bit of code in init_request_info() in sapi/cgi/cgi_main.c:

---
/* figure out docroot
   SCRIPT_FILENAME minus SCRIPT_NAME
*/

if (env_document_root)
{
        int l = strlen(env_document_root);
        int path_translated_len = 0;
        char *path_translated = NULL;

        if (l && env_document_root[l - 1] == '/') {
                --l;
        }

        /* we have docroot, so we should have:
         * DOCUMENT_ROOT=/docroot
         * SCRIPT_FILENAME=/docroot/info.php
         *
         * SCRIPT_NAME is the portion of the path beyond docroot
         */
         env_script_name = pt + l;
---

Since env_document_root is pretty much always set, we enter the if. pt is '/home/hans/public_html/info.php' at this point (which is correct). l becomes 15, the strlen of our DOCUMENT_ROOT '/var/www/htdocs'. The "trailing slash check if loop" is skipped since our docroot doesn't have a trailing slash. After this, SCRIPT_NAME is set to pt + l. pt being '/home/hans/public_html/info.php' and l being 15, this results in a invalid SCRIPT_NAME (and thus a PHP_SELF) of 'ic_html/info.php'.

My patch adds a userdir check to the 'if (env_document_root)', to prevent from entering this if() with a DOCUMENT_ROOT that doesn't match the actual docroot of the userdir. The code that follows after this if() handles the userdir requests perfectly and results in correct SCRIPT_NAME and PHP_SELF vars.
 [2007-08-07 11:41 UTC] jani@php.net
You patch does not fix the issue for anything but the userdir module and in a very hackish way. For the aliasing part of your (saw your example on the lighttpd bug report) it does not fix it at all.

When I debugged this I noticed this:

["PATH_TRANSLATED"]=>
  string(17) "/opt/www/foo/bar/"
["SCRIPT_FILENAME"]=>
  string(16) "/home/jani/t.php"
["DOCUMENT_ROOT"]=>
  string(9) "/opt/www/"
["REQUEST_URI"]=>
  string(17) "/r/t.php/foo/bar/"

Shouldn't DOCUMENT_ROOT be /home/jani/ in this case when it's the alias? And PATH_TRANSLATED is also wrong..

 [2007-08-07 11:51 UTC] jani@php.net
Then again same happens with Apache too..
 [2007-08-07 12:35 UTC] hans at parse dot nl
Heh i was pondering and typing a apache2handler example and then i saw your Apache comment. Here it is anyway:
--

Yes i agree, my patch is kinda hacky but solved my personal userdir problem ;) The alias problem was someone else's which i overlooked.

Your alias example suffers from the same problem as userdirs, being that the DOCUMENT_ROOT always points to the docroot of the host, but as i already pointed out, this is also the case in apache/mod_php5 or apache2handler, not just cgi-fcgi.

apache2handler actually is an even bigger mess :) for example:

request: http://www.site.com/~hans/info.php/foo/bar

result:

_SERVER["DOCUMENT_ROOT"]    /var/www/site.com/www/htdocs
_SERVER["REQUEST_URI"]      /~hans/info.php/foo/bar
_SERVER["SCRIPT_NAME"]      /~hans/info.php
_SERVER["PATH_INFO"]        /foo/bar
_SERVER["PATH_TRANSLATED"]  /var/www/site.com/www/htdocs/foo/bar
_SERVER["PHP_SELF"]         /~hans/info.php/foo/bar


Not really consistent, and also an invalid PATH_TRANSLATED, and PATH_INFO added to PHP_SELF ?!

Anyway, back to Lighttpd. I'll try to whip up a less hacky fix that also handles the aliases.
 [2007-08-07 13:08 UTC] jani@php.net
See bug #31892 (It's about Apache)
I fixed the issues there with this patch (against latest CVS checkout of PHP_5_2): 
http://pecl.php.net/~jani/patches/bug_31892.patch

I then tried the same on lighttpd but no luck: Lighttpd sets PATH_TRANSLATED incorrectly, debugged it and saw it was set to this:

PATH_TRANSLATED: /opt/www//foo/bar/
PATH_INFO: /foo/bar/
SCRIPT_FILENAME: /home/jani/t.php
SCRIPT_NAME: /r/t.php
PHP_SELF: /r/t.php
REQUEST_URI: /r/t.php/foo/bar/?bar=foo

Obviously when there's this alias/userdir lighttpd still uses document  root to set the PATH_TRANSLATED with (I checked the actual value lighttpd sets it to, it's not the one PHP modifies..). 
Lighttpd seems to ignore the script name totally too. Under apache it now works (when my patch is applied) as expected:

PATH_TRANSLATED: /home/jani/t.php/foo/bar/
PATH_INFO: /foo/bar/
SCRIPT_FILENAME: /home/jani/t.php
SCRIPT_NAME: /r/t.php/foo/bar/
PHP_SELF: /r/t.php/foo/bar/
REQUEST_URI: /r/t.php/foo/bar/?bar=foo

 [2007-08-07 13:10 UTC] jani@php.net
And FYI, about PHP_SELF:
http://www.php.net/reserved.variables

(yes, it's supposed to contain PATH_INFO..)
 [2007-08-07 14:56 UTC] hans at parse dot nl
Ah, i didn't know about the Apache ticket but it looks like exactly the same issue. Nice work on that, hope it makes it into php-5.2.4 :)

I applied your patch to php-5.2.4RC1 and adapted Lighttpd mod_fastcgi.c so it exactly matches your Apache results.

My patch for lighttpd-1.4.16 can be found here: http://home.parse.nl/~hans/temp/mod_fastcgi.diff

Can you please check if you get proper results with it aswell? Would be great if we can tackle this :)
 [2007-08-07 15:43 UTC] jani@php.net
Yes, that's one way to do it..though I still think the issue is more in how mod_alias/mod_userdir handle the doc_root and might be the proper place to fix it..but I'm not so familiar with lighttpd internals so I could be wrong. Including my patch in 5.2.4 is up to Ilia to decide. :)
 [2007-08-08 13:03 UTC] dmitry@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 23 09:02:23 2014 UTC