php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #46814 Relative includes from symlinked directories fail
Submitted: 2008-12-09 18:17 UTC Modified: 2008-12-29 01:00 UTC
Votes:21
Avg. Score:4.3 ± 0.8
Reproduced:20 of 21 (95.2%)
Same Version:3 (15.0%)
Same OS:6 (30.0%)
From: dennis dot birkholz at nexxes dot net Assigned:
Status: No Feedback Package: Scripting Engine problem
PHP Version: 5.2.8 OS: Gentoo/Linux
Private report: No CVE-ID: None
 [2008-12-09 18:17 UTC] dennis dot birkholz at nexxes dot net
Description:
------------
include statement seems to resolve the current working directory other than the rest of php so if I am in a symlinked directory an try to include a file using a relative path (containing ../), the include fails because the original path of the script is used to resolve the relative include and not the path the script is invoked from.

Reproduce code:
---------------
Asume the following files/directory structure:
Directory /test1
Directory /htdocs
Directory /htdocs/docs
Symlink /htdocs/test2 -> /test1
File /test1/index.php
File /htdocs/docs/docs.inc.php

DocumentRoot is /htdocs

File-Contents of /test1/index.php
<?php
  include("../docs/docs.inc.php");
//  ... other code
?>

Expected result:
----------------
No error, output generated by code after the include

Actual result:
--------------
An error: failed to open stream: No such file or directory
(/test1/index.php:2)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-12-17 22:35 UTC] dennis dot birkholz at nexxes dot net
This IS a bug: in Linux (and Unix like systems) beeing in a symlinked directory should behave exactly like beeing in a directory with the same content.

To use my example: If I use a shell and change to the folder /htdocs/test2 (which is a symlink to /test1), ls ../docs/docs.inc.php will show me the file "/htdocs/docs/docs.inc.php" and NOT "/docs/docs.inc.php".
 [2008-12-18 09:05 UTC] php at degoulet dot net
I don't realy understand your problem ?!
[root@pix sdv]# ls -alR
.:
total 16
drwxr-xr-x  4 root     root    4096 Dec 17 17:44 .
drwxrwxrwx  3 via      ftponly 4096 Dec 17 17:44 ..
drwxr-xr-x  2 root     root    4096 Dec 17 17:45 docs
drwxr-xr-x  2 root     root    4096 Dec 17 17:46 test1
lrwxrwxrwx  1 root     root       5 Dec 17 17:44 test2 -> test1

./docs:
total 12
drwxr-xr-x  2 root root 4096 Dec 17 17:45 .
drwxr-xr-x  4 root root 4096 Dec 17 17:44 ..
-rw-r--r--  1 root root   24 Dec 17 17:45 docs.inc.php

./test1:
total 12
drwxr-xr-x  2 root root 4096 Dec 17 17:46 .
drwxr-xr-x  4 root root 4096 Dec 17 17:44 ..
-rw-r--r--  1 root root   50 Dec 17 17:46 index.php

[root@pix sdv]# cat test1/index.php 
<?php
include("../docs/docs.inc.php");
echo "ok\n";
?>
[root@pix sdv]# cat docs/docs.inc.php 
<?php
echo "docs\n";
?>

No problem when i try this with apache :
http://www.xxxx.com/sdv/test1/index.php
http://www.xxxx.com/sdv/test2/index.php
==> same output : docs ok 

if you try this in command line.
3 cases :
- pwd= test1 : php index.php => output docs ok
- pwd= test2 : php index.php => output docs ok
- pwd= anywhere else : php ./test1/index.php : include(): Unable to access ../docs/docs.inc.php which is quite normal
the include path is relative to the current directory where php is executed not relative to the php script which is executed ...

isn't it ?
 [2008-12-18 21:28 UTC] dennis dot birkholz at nexxes dot net
No, you did not read my initial post correctly:
a file/directory starting with a / (like /test1) means it is in the root-directory. All example pathnames where absolute pathnames, not relative.

Here comes my listing for you:

/htdocs/:
total 12
drwxr-xr-x  3 root root 4096 Dec 18 22:23 ./
drwxr-xr-x 22 root root 4096 Dec 18 22:23 ../
drwxr-xr-x  2 root root 4096 Dec 18 22:23 docs/
lrwxrwxrwx  1 root root    6 Dec 18 22:23 test2 -> /test1/

/htdocs/docs/:
insgesamt 8
drwxr-xr-x 2 root root 4096 18. Dez 22:23 ./
drwxr-xr-x 3 root root 4096 18. Dez 22:23 ../
-rw-r--r-- 1 root root    0 18. Dez 22:23 docs.inc.php

/test1/:
total 8
drwxr-xr-x  2 root root 4096 18. Dez 22:24 ./
drwxr-xr-x 22 root root 4096 18. Dez 22:23 ../
-rw-r--r--  1 root root    0 18. Dez 22:24 index.php

Please note that test1 and test2 are not on the same directory level!
 [2008-12-21 13:12 UTC] jani@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.


 [2008-12-29 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2009-09-03 14:24 UTC] michele dot manzato at gmail dot com
I confirm this bug. Here is the simplest reproduce code that I was able to make up:

~$ cd /tmp
/tmp$ mkdir a
/tmp$ mkdir b
/tmp$ echo '<?php echo getcwd(); require "../inc.php";?>' > a/test.php
/tmp$ echo '<?php echo "ok\n";?>' > b/inc.php
/tmp$ ln -s /tmp/a b/c
/tmp$ cd b/c/
/tmp/b/c$ php -f test.php
/tmp/a
Warning: require(../inc.php): failed to open stream: No such file or directory in /tmp/a/test.php on line 1

As one can see, the script's CWD is /tmp/a although the script was run from /tmp/b/c. As a result the following require() instruction fails because it can't find /inc.php (which should have been /tmp/b/inc.php instead).

The problem here is not the require(). It is that the CWD is converted to the real path when, instead, it should remain the symlinked path.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC